diff options
author | Raja Kedia(miyagix) <rajakedia2222@gmail.com> | 2017-12-14 21:47:35 +0300 |
---|---|---|
committer | Raja Kedia(miyagix) <rajakedia2222@gmail.com> | 2017-12-14 21:47:35 +0300 |
commit | 450eb4ef6c54108e16164aa0820ee00fea9b8b48 (patch) | |
tree | 643a8c2b026205961d2539ac7a5bf363e5f5f500 | |
parent | 31d5262cece4c5644a36cf0511bc42007a2c1e6d (diff) | |
parent | ba256b32ee5d3ab7991fe5abbb47071ccfe8577c (diff) |
Merge remote-tracking branch 'origin' into soc-2017-sculpting_brushsoc-2017-sculpting_brush
479 files changed, 5903 insertions, 4518 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 66ee215864d..04237812d87 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,7 +32,7 @@ if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) if(NOT DEFINED WITH_IN_SOURCE_BUILD) message(FATAL_ERROR "CMake generation for blender is not allowed within the source directory!" - "\n Remove the CMakeCache.txt file and try again from another folder, e.g.:" + "\n Remove \"${CMAKE_SOURCE_DIR}/CMakeCache.txt\" and try again from another folder, e.g.:" "\n " "\n rm CMakeCache.txt" "\n cd .." @@ -58,7 +58,9 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/build_files/cmake/Modules") list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/build_files/cmake/platform") # avoid having empty buildtype -set(CMAKE_BUILD_TYPE_INIT "Release") +if(NOT DEFINED CMAKE_BUILD_TYPE_INIT) + set(CMAKE_BUILD_TYPE_INIT "Release") +endif() # quiet output for Makefiles, 'make -s' helps too # set_property(GLOBAL PROPERTY RULE_MESSAGES OFF) diff --git a/GNUmakefile b/GNUmakefile index 86964e68873..ba7f89c3097 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -104,7 +104,7 @@ endif CMAKE_CONFIG = cmake $(BUILD_CMAKE_ARGS) \ -H"$(BLENDER_DIR)" \ -B"$(BUILD_DIR)" \ - -DCMAKE_BUILD_TYPE:STRING=$(BUILD_TYPE) + -DCMAKE_BUILD_TYPE_INIT:STRING=$(BUILD_TYPE) # ----------------------------------------------------------------------------- diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index b996c234c67..3852b4fe705 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -26,7 +26,7 @@ ARGS=$( \ getopt \ -o s:i:t:h \ --long source:,install:,tmp:,info:,threads:,help,show-deps,no-sudo,no-build,no-confirm,use-cxx11,\ -with-all,with-opencollada,\ +with-all,with-opencollada,with-jack,\ ver-ocio:,ver-oiio:,ver-llvm:,ver-osl:,ver-osd:,ver-openvdb:,\ force-all,force-python,force-numpy,force-boost,\ force-ocio,force-openexr,force-oiio,force-llvm,force-osl,force-osd,force-openvdb,\ @@ -118,6 +118,9 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS: --with-opencollada Build and install the OpenCOLLADA libraries. + --with-jack + Install the jack libraries. + --ver-ocio=<ver> Force version of OCIO library. @@ -322,8 +325,8 @@ OPENEXR_FORCE_REBUILD=false OPENEXR_SKIP=false _with_built_openexr=false -OIIO_VERSION="1.7.13" -OIIO_VERSION_MIN="1.7.13" +OIIO_VERSION="1.7.15" +OIIO_VERSION_MIN="1.7.15" OIIO_VERSION_MAX="1.9.0" # UNKNOWN currently # Not supported by current OSL... OIIO_FORCE_BUILD=false OIIO_FORCE_REBUILD=false @@ -366,7 +369,7 @@ ALEMBIC_FORCE_BUILD=false ALEMBIC_FORCE_REBUILD=false ALEMBIC_SKIP=false -OPENCOLLADA_VERSION="1.6.47" +OPENCOLLADA_VERSION="1.6.51" OPENCOLLADA_FORCE_BUILD=false OPENCOLLADA_FORCE_REBUILD=false OPENCOLLADA_SKIP=false @@ -507,6 +510,9 @@ while true; do --with-opencollada) WITH_OPENCOLLADA=true; shift; continue ;; + --with-jack) + WITH_JACK=true; shift; continue; + ;; --ver-ocio) OCIO_VERSION="$2" OCIO_VERSION_MIN=$OCIO_VERSION @@ -710,6 +716,9 @@ done if [ "$WITH_ALL" = true -a "$OPENCOLLADA_SKIP" = false ]; then WITH_OPENCOLLADA=true fi +if [ "$WITH_ALL" = true ]; then + WITH_JACK=true +fi WARNING "****WARNING****" @@ -788,7 +797,7 @@ ALEMBIC_SOURCE=( "https://github.com/alembic/alembic/archive/${ALEMBIC_VERSION}. # ALEMBIC_SOURCE_REPO_BRANCH="master" OPENCOLLADA_SOURCE=( "https://github.com/KhronosGroup/OpenCOLLADA.git" ) -OPENCOLLADA_REPO_UID="22b1f4ff026881b4d2804d397730286ab7e3d090" +OPENCOLLADA_REPO_UID="0c2cdc17c22cf42050e4d42154bed2176363549c" OPENCOLLADA_REPO_BRANCH="master" FFMPEG_SOURCE=( "http://ffmpeg.org/releases/ffmpeg-$FFMPEG_VERSION.tar.bz2" ) @@ -2652,7 +2661,7 @@ install_DEB() { PRINT "" fi - if [ "$WITH_ALL" = true ]; then + if [ "$WITH_JACK" = true ]; then _packages="$_packages libspnav-dev" # Only install jack if jack2 is not already installed! JACK="libjack-dev" @@ -3189,7 +3198,7 @@ install_RPM() { if [ "$RPM" = "FEDORA" -o "$RPM" = "RHEL" ]; then _packages="$_packages freetype-devel tbb-devel" - if [ "$WITH_ALL" = true ]; then + if [ "$WITH_JACK" = true ]; then _packages="$_packages jack-audio-connection-kit-devel" fi @@ -3663,7 +3672,11 @@ install_ARCH() { THEORA_USE=true if [ "$WITH_ALL" = true ]; then - _packages="$_packages jack libspnav" + _packages="$_packages libspnav" + fi + + if [ "$WITH_JACK" = true ]; then + _packages="$_packages jack" fi PRINT "" @@ -4325,6 +4338,14 @@ print_info() { _buildargs="$_buildargs $_1" fi + if [ "$WITH_JACK" = true ]; then + _1="-D WITH_JACK=ON" + _2="-D WITH_JACK_DYNLOAD=ON" + PRINT " $_1" + PRINT " $_2" + _buildargs="$_buildargs $_1 $_2" + fi + if [ "$ALEMBIC_SKIP" = false ]; then _1="-D WITH_ALEMBIC=ON" PRINT " $_1" diff --git a/build_files/buildbot/config/blender_linux_player.cmake b/build_files/buildbot/config/blender_linux_player.cmake index 2fb31192002..69ab984e386 100644 --- a/build_files/buildbot/config/blender_linux_player.cmake +++ b/build_files/buildbot/config/blender_linux_player.cmake @@ -1,4 +1,4 @@ -# This is applied as an ovveride on top of blender_linux.config +# This is applied as an override on top of blender_linux.config # Disables all the areas which are not needed for the player. set(WITH_COMPOSITOR OFF CACHE BOOL "" FORCE) set(WITH_CYCLES OFF CACHE BOOL "" FORCE) diff --git a/build_files/cmake/Modules/FindOpenCOLLADA.cmake b/build_files/cmake/Modules/FindOpenCOLLADA.cmake index 1c10d5a71de..63bc520ea15 100644 --- a/build_files/cmake/Modules/FindOpenCOLLADA.cmake +++ b/build_files/cmake/Modules/FindOpenCOLLADA.cmake @@ -83,6 +83,7 @@ FOREACH(COMPONENT ${_opencollada_FIND_INCLUDES}) # but this is less trouble, just looks strange. include/opencollada/${COMPONENT} include/${COMPONENT}/include + include/${COMPONENT} HINTS ${_opencollada_SEARCH_DIRS} ) diff --git a/build_files/cmake/platform/platform_win32_msvc.cmake b/build_files/cmake/platform/platform_win32_msvc.cmake index 2055b164f6d..3b417f79cbe 100644 --- a/build_files/cmake/platform/platform_win32_msvc.cmake +++ b/build_files/cmake/platform/platform_win32_msvc.cmake @@ -452,20 +452,21 @@ if(WITH_MOD_CLOTH_ELTOPO) endif() if(WITH_OPENSUBDIV OR WITH_CYCLES_OPENSUBDIV) - set(OPENSUBDIV_INCLUDE_DIR ${LIBDIR}/opensubdiv/include) - set(OPENSUBDIV_LIBPATH ${LIBDIR}/opensubdiv/lib) - set(OPENSUBDIV_LIBRARIES optimized ${OPENSUBDIV_LIBPATH}/osdCPU.lib - optimized ${OPENSUBDIV_LIBPATH}/osdGPU.lib - debug ${OPENSUBDIV_LIBPATH}/osdCPU_d.lib - debug ${OPENSUBDIV_LIBPATH}/osdGPU_d.lib - ) - set(OPENSUBDIV_HAS_OPENMP TRUE) + set(OPENSUBDIV_INCLUDE_DIR ${LIBDIR}/opensubdiv/include) + set(OPENSUBDIV_LIBPATH ${LIBDIR}/opensubdiv/lib) + set(OPENSUBDIV_LIBRARIES + optimized ${OPENSUBDIV_LIBPATH}/osdCPU.lib + optimized ${OPENSUBDIV_LIBPATH}/osdGPU.lib + debug ${OPENSUBDIV_LIBPATH}/osdCPU_d.lib + debug ${OPENSUBDIV_LIBPATH}/osdGPU_d.lib + ) + set(OPENSUBDIV_HAS_OPENMP TRUE) set(OPENSUBDIV_HAS_TBB FALSE) set(OPENSUBDIV_HAS_OPENCL TRUE) set(OPENSUBDIV_HAS_CUDA FALSE) set(OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK TRUE) set(OPENSUBDIV_HAS_GLSL_COMPUTE TRUE) - windows_find_package(OpenSubdiv) + windows_find_package(OpenSubdiv) endif() if(WITH_SDL) @@ -488,14 +489,14 @@ endif() # used in many places so include globally, like OpenGL blender_include_dirs_sys("${PTHREADS_INCLUDE_DIRS}") -#find signtool -SET(ProgramFilesX86_NAME "ProgramFiles(x86)") #env dislikes the ( ) +#find signtool +set(ProgramFilesX86_NAME "ProgramFiles(x86)") #env dislikes the ( ) find_program(SIGNTOOL_EXE signtool -HINTS - "$ENV{${ProgramFilesX86_NAME}}/Windows Kits/10/bin/x86/" - "$ENV{ProgramFiles}/Windows Kits/10/bin/x86/" - "$ENV{${ProgramFilesX86_NAME}}/Windows Kits/8.1/bin/x86/" - "$ENV{ProgramFiles}/Windows Kits/8.1/bin/x86/" - "$ENV{${ProgramFilesX86_NAME}}/Windows Kits/8.0/bin/x86/" - "$ENV{ProgramFiles}/Windows Kits/8.0/bin/x86/" + HINTS + "$ENV{${ProgramFilesX86_NAME}}/Windows Kits/10/bin/x86/" + "$ENV{ProgramFiles}/Windows Kits/10/bin/x86/" + "$ENV{${ProgramFilesX86_NAME}}/Windows Kits/8.1/bin/x86/" + "$ENV{ProgramFiles}/Windows Kits/8.1/bin/x86/" + "$ENV{${ProgramFilesX86_NAME}}/Windows Kits/8.0/bin/x86/" + "$ENV{ProgramFiles}/Windows Kits/8.0/bin/x86/" ) diff --git a/doc/python_api/examples/bpy.app.translations.py b/doc/python_api/examples/bpy.app.translations.py index e41623d2885..4256147ef31 100644 --- a/doc/python_api/examples/bpy.app.translations.py +++ b/doc/python_api/examples/bpy.app.translations.py @@ -32,3 +32,62 @@ Module References ----------------- """ + +import bpy + +# This block can be automatically generated by UI translations addon, which also handles conversion with PO format. +# See also https://wiki.blender.org/index.php/Dev:Doc/Process/Translate_Blender#Translating_non-official_addons +# It can (should) also be put in a different, specific py file. + +# ##### BEGIN AUTOGENERATED I18N SECTION ##### +# 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 = ( + (("*", ""), + ((), ()), + ("fr_FR", "Project-Id-Version: Copy Settings 0.1.5 (r0)\nReport-Msgid-Bugs-To: \nPOT-Creation-Date: 2013-04-18 15:27:45.563524\nPO-Revision-Date: 2013-04-18 15:38+0100\nLast-Translator: Bastien Montagne <montagne29@wanadoo.fr>\nLanguage-Team: LANGUAGE <LL@li.org>\nLanguage: __POT__\nMIME-Version: 1.0\nContent-Type: text/plain; charset=UTF-8\nContent-Transfer-Encoding: 8bit\n", + (False, + ("Blender's translation file (po format).", + "Copyright (C) 2013 The Blender Foundation.", + "This file is distributed under the same license as the Blender package.", + "FIRST AUTHOR <EMAIL@ADDRESS>, YEAR."))), + ), + (("Operator", "Render: Copy Settings"), + (("bpy.types.SCENE_OT_render_copy_settings",), + ()), + ("fr_FR", "Rendu : copier réglages", + (False, ())), + ), + (("*", "Copy render settings from current scene to others"), + (("bpy.types.SCENE_OT_render_copy_settings",), + ()), + ("fr_FR", "Copier les réglages de rendu depuis la scène courante vers d’autres", + (False, ())), + ), + # ... etc, all messages from your addon. +) + +translations_dict = {} +for msg in translations_tuple: + key = msg[0] + for lang, trans, (is_fuzzy, comments) in msg[2:]: + if trans and not is_fuzzy: + translations_dict.setdefault(lang, {})[key] = trans + +# ##### END AUTOGENERATED I18N SECTION ##### + +# Define remaining addon (operators, UI...) here. + +def register(): + # Usual operator/UI/etc. registration... + + bpy.app.translations.register(__name__, translations_dict) + + +def unregister(): + bpy.app.translations.unregister(__name__) + + # Usual operator/UI/etc. unregistration... diff --git a/doc/python_api/examples/bpy.types.Operator.5.py b/doc/python_api/examples/bpy.types.Operator.5.py index 310eeceadf3..c1a49a756a0 100644 --- a/doc/python_api/examples/bpy.types.Operator.5.py +++ b/doc/python_api/examples/bpy.types.Operator.5.py @@ -2,13 +2,14 @@ Modal Execution +++++++++++++++ -This operator defines a :class:`Operator.modal` function which running, -handling events until it returns ``{'FINISHED'}`` or ``{'CANCELLED'}``. - -Grab, Rotate, Scale and Fly-Mode are examples of modal operators. -They are especially useful for interactive tools, -your operator can have its own state where keys toggle options as the operator -runs. +This operator defines a :class:`Operator.modal` function that will keep being +run to handle events until it returns ``{'FINISHED'}`` or ``{'CANCELLED'}``. + +Modal operators run every time a new event is detected, such as a mouse click +or key press. Conversely, when no new events are detected, the modal operator +will not run. Modal operators are especially useful for interactive tools, an +operator can have its own state where keys toggle options as the operator runs. +Grab, Rotate, Scale, and Fly-Mode are examples of modal operators. :class:`Operator.invoke` is used to initialize the operator as being by returning ``{'RUNNING_MODAL'}``, initializing the modal loop. diff --git a/doc/python_api/rst/bge.app.rst b/doc/python_api/rst/bge.app.rst index 34b9263db0c..e8b91ffbcaf 100644 --- a/doc/python_api/rst/bge.app.rst +++ b/doc/python_api/rst/bge.app.rst @@ -47,4 +47,3 @@ Module to access application values that remain unchanged during runtime. True if the BGE has been built with physics support. :type: bool - diff --git a/doc/python_api/rst/gpu.rst b/doc/python_api/rst/gpu.rst index 6c38122a573..cf639357a31 100644 --- a/doc/python_api/rst/gpu.rst +++ b/doc/python_api/rst/gpu.rst @@ -6,6 +6,13 @@ GPU functions (gpu) This module provides access to materials GLSL shaders. +Submodules: + +.. toctree:: + :maxdepth: 1 + + gpu.offscreen.rst + Intro ===== @@ -24,7 +31,6 @@ and in the game engine. Constants ========= - GLSL Data Type -------------- diff --git a/doc/python_api/rst/include__bmesh.rst b/doc/python_api/rst/include__bmesh.rst index 83e3e73cea4..bed374bf7b6 100644 --- a/doc/python_api/rst/include__bmesh.rst +++ b/doc/python_api/rst/include__bmesh.rst @@ -7,14 +7,17 @@ Submodules: -* :mod:`bmesh.ops` -* :mod:`bmesh.types` -* :mod:`bmesh.utils` -* :mod:`bmesh.geometry` +.. toctree:: + :maxdepth: 1 + bmesh.ops.rst + bmesh.types.rst + bmesh.utils.rst + bmesh.geometry.rst -Intro ------ + +Introduction +------------ This API gives access the blenders internal mesh editing api, featuring geometry connectivity data and access to editing operations such as split, separate, collapse and dissolve. diff --git a/doc/python_api/rst/info_overview.rst b/doc/python_api/rst/info_overview.rst index ba2e6949b81..721374cd472 100644 --- a/doc/python_api/rst/info_overview.rst +++ b/doc/python_api/rst/info_overview.rst @@ -5,23 +5,25 @@ Python API Overview ******************* -This document is to give an understanding of how Python and Blender fit together, -covering some of the functionality that isn't obvious from reading the API reference and example scripts. +The purpose of this document is to explain how Python and Blender fit together, +covering some of the functionality that may not be obvious from reading the API +references and example scripts. Python in Blender ================= -Blender embeds a Python interpreter which is started with Blender and stays active. -This interpreter runs scripts to draw the user interface and is used for some of Blender's internal tools too. +Blender has an embedded Python interpreter which is loaded when Blender is started and stays +active while Blender is running. This interpreter runs scripts to draw the user interface +and is used for some of Blender’s internal tools as well. -This is a typical Python environment so tutorials on how to write Python scripts -will work running the scripts in Blender too. -Blender provides the :mod:`bpy` module to the Python interpreter. -This module can be imported in a script and gives access to Blender data, classes, and functions. -Scripts that deal with Blender data will need to import this module. +Blender's embedded interpreter provides a typical Python environment, so code from tutorials +on how to write Python scripts can also be run with Blender’s interpreter. Blender provides its +Python modules, such as :mod:`bpy` and :mod:`mathutils`, to the embedded interpreter so they can +be imported into a script and give access to Blender's data, classes, and functions. Scripts that +deal with Blender data will need to import the modules to work. -Here is a simple example of moving a vertex of the object named **Cube**: +Here is a simple example which moves a vertex attached to an object named **Cube**: .. code-block:: python @@ -49,15 +51,17 @@ See the :ref:`directory layout docs <blender_manual:getting-started_installing-c Script Loading ============== -This may seem obvious but it's important to note the difference -between executing a script directly or importing it as a module. +This may seem obvious, but it is important to note the difference between +executing a script directly and importing a script as a module. -Scripts that extend Blender - define classes that exist beyond the scripts execution, -this makes future access to these classes (to unregister for example) -more difficult than importing as a module where class instance is kept -in the module and can be accessed by importing that module later on. +Extending Blender by executing a script directly means the classes that the script +defines remain available inside Blender after the script finishes execution. +Using scripts this way makes future access to their classes +(to unregister them for example) more difficult compared to importing the scripts as modules. +When a script is imported as a module, its class instances will remain +inside the module and can be accessed later on by importing that module again. -For this reason it's preferable to only use directly execute scripts that don't extend Blender by registering classes. +For this reason it is preferable to avoid directly executing scripts that extend Blender by registering classes. Here are some ways to run scripts directly in Blender. @@ -396,8 +400,8 @@ This works just as well for PropertyGroup subclasses you define yourself. Dynamic Defined-Classes (Advanced) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -In some cases the specifier for data may not be in Blender, -renderman shader definitions for example and it may be useful to define types and remove them on the fly. +In some cases the specifier for data may not be in Blender, renderman shader definitions +for example, and it may be useful to define them as types and remove them on the fly. .. code-block:: python @@ -420,7 +424,7 @@ renderman shader definitions for example and it may be useful to define types an This is an alternative syntax for class creation in Python, better suited to constructing classes dynamically. -Calling these operators: +To call the operators from the previous example: >>> bpy.ops.object.operator_1() Hello World OBJECT_OT_operator_1 diff --git a/doc/python_api/rst/info_tutorial_addon.rst b/doc/python_api/rst/info_tutorial_addon.rst deleted file mode 100644 index 92fbf9b8787..00000000000 --- a/doc/python_api/rst/info_tutorial_addon.rst +++ /dev/null @@ -1,635 +0,0 @@ - -Add-on Tutorial -############### - -************ -Introduction -************ - - -Intended Audience -================= - -This tutorial is designed to help technical artists or developers learn to extend Blender. -An understanding of the basics of Python is expected for those working through this tutorial. - - -Prerequisites -------------- - -Before going through the tutorial you should... - -- Familiarity with the basics of working in Blender. -- Know how to run a script in Blender's text editor (as documented in the quick-start) -- Have an understanding of Python primitive types (int, boolean, string, list, tuple, dictionary, and set). -- Be familiar with the concept of Python modules. -- Basic understanding of classes (object orientation) in Python. - - -Suggested reading before starting this tutorial. - -- `Dive Into Python <http://getpython3.com/diveintopython3/index.html>`_ sections (1, 2, 3, 4, and 7). -- :ref:`Blender API Quickstart <info_quickstart>` - to help become familiar with Blender/Python basics. - - -To best troubleshoot any error message Python prints while writing scripts you run blender with from a terminal, -see :ref:`Use The Terminal <use_the_terminal>`. - - -Documentation Links -=================== - -While going through the tutorial you may want to look into our reference documentation. - -- :ref:`Blender API Overview <info_overview>`. - - *This document is rather detailed but helpful if you want to know more on a topic.* -- :mod:`bpy.context` api reference. - - *Handy to have a list of available items your script may operate on.* -- :class:`bpy.types.Operator`. - - *The following add-ons define operators, these docs give details and more examples of operators.* - - -******* -Add-ons -******* - -What is an Add-on? -================== - -An add-on is simply a Python module with some additional requirements so Blender can display it in a list with useful -information. - -To give an example, here is the simplest possible add-on. - -.. code-block:: python - - bl_info = {"name": "My Test Add-on", "category": "Object"} - def register(): - print("Hello World") - def unregister(): - print("Goodbye World") - - -- ``bl_info`` is a dictionary containing add-on metadata such as the title, - version and author to be displayed in the user preferences add-on list. -- ``register`` is a function which only runs when enabling the add-on, - this means the module can be loaded without activating the add-on. -- ``unregister`` is a function to unload anything setup by ``register``, this is called when the add-on is disabled. - - -Notice this add-on does not do anything related to Blender, (the :mod:`bpy` module is not imported for example). - -This is a contrived example of an add-on that serves to illustrate the point -that the base requirements of an add-on are simple. - -An add-on will typically register operators, panels, menu items etc, but its worth noting that _any_ script can do this, -when executed from the text editor or even the interactive console - there is nothing inherently different about an -add-on that allows it to integrate with Blender, such functionality is just provided by the :mod:`bpy` module for any -script to access. - -So an add-on is just a way to encapsulate a Python module in a way a user can easily utilize. - -.. note:: - - Running this script within the text editor won't print anything, - to see the output it must be installed through the user preferences. - Messages will be printed when enabling and disabling. - - -Your First Add-on -================= - -The simplest possible add-on above is useful as an example but not much else. -This next add-on is simple but shows how to integrate a script into Blender using an ``Operator`` -which is the typical way to define a tool accessed from menus, buttons and keyboard shortcuts. - -For the first example we will make a script that simply moves all objects in a scene. - - -Write The Script ----------------- - -Add the following script to the text editor in Blender. - -.. code-block:: python - - import bpy - - scene = bpy.context.scene - for obj in scene.objects: - obj.location.x += 1.0 - - -Click the :ref:`Run Script button <blender_manual:editors-text-run-script>`, -all objects in the active scene are moved by 1.0 Blender unit. - - -Write the Add-on (Simple) -------------------------- - -This add-on takes the body of the script above, and adds them to an operator's ``execute()`` function. - - -.. code-block:: python - - bl_info = { - "name": "Move X Axis", - "category": "Object", - } - - import bpy - - - class ObjectMoveX(bpy.types.Operator): - """My Object Moving Script""" # blender will use this as a tooltip for menu items and buttons. - bl_idname = "object.move_x" # unique identifier for buttons and menu items to reference. - bl_label = "Move X by One" # display name in the interface. - bl_options = {'REGISTER', 'UNDO'} # enable undo for the operator. - - def execute(self, context): # execute() is called by blender when running the operator. - - # The original script - scene = context.scene - for obj in scene.objects: - obj.location.x += 1.0 - - return {'FINISHED'} # this lets blender know the operator finished successfully. - - def register(): - bpy.utils.register_class(ObjectMoveX) - - - def unregister(): - bpy.utils.unregister_class(ObjectMoveX) - - - # This allows you to run the script directly from blenders text editor - # to test the add-on without having to install it. - if __name__ == "__main__": - register() - - -.. note:: - - ``bl_info`` is split across multiple lines, this is just a style convention used to more easily add items. - -.. note:: - - Rather than using ``bpy.context.scene``, we use the ``context.scene`` argument passed to ``execute()``. - In most cases these will be the same however in some cases operators will be passed a custom context - so script authors should prefer the ``context`` argument passed to operators. - -To test the script you can copy and paste this into Blender text editor and run it, this will execute the script -directly and call register immediately. - -However running the script wont move any objects, for this you need to execute the newly registered operator. - -.. image:: spacebar.png - :width: 924px - :align: center - :height: 574px - :alt: Spacebar - -Do this by pressing :kbd:`Spacebar` to bring up the operator search dialog and type in -"Move X by One" (the ``bl_label``), then :kbd:`Enter`. - - - -The objects should move as before. - -*Keep this add-on open in Blender for the next step - Installing.* - - -Install The Add-on ------------------- - -Once you have your add-on within in Blender's text editor, -you will want to be able to install it so it can be enabled in the user preferences to load on startup. - -Even though the add-on above is a test, lets go through the steps anyway so you know how to do it for later. - -To install the Blender text as an add-on you will first have to save it to disk, take care to obey the naming -restrictions that apply to Python modules and end with a ``.py`` extension. - -Once the file is on disk, you can install it as you would for an add-on downloaded online. - -Open the user :menuselection:`File --> User Preferences`, -Select the *Add-on* section, press *Install Add-on...* and select the file. - -Now the add-on will be listed and you can enable it by pressing the check-box, -if you want it to be enabled on restart, press *Save as Default*. - -.. note:: - - The destination of the add-on depends on your Blender configuration. - When installing an add-on the source and destination path are printed in the console. - You can also find add-on path locations by running this in the Python console. - - .. code-block:: python - - import addon_utils - print(addon_utils.paths()) - - More is written on this topic here: - :ref:`Directory Layout <blender_manual:getting-started_installing-config-directories>`. - - -Your Second Add-on -================== - -For our second add-on, we will focus on object instancing - this is - to make linked copies of an object in a -similar way to what you may have seen with the array modifier. - - -Write The Script ----------------- - -As before, first we will start with a script, develop it, then convert into an add-on. - -.. code-block:: python - - import bpy - from bpy import context - - # Get the current scene - scene = context.scene - - # Get the 3D cursor - cursor = scene.cursor_location - - # Get the active object (assume we have one) - obj = scene.objects.active - - # Now make a copy of the object - obj_new = obj.copy() - - # The object won't automatically get into a new scene - scene.objects.link(obj_new) - - # Now we can place the object - obj_new.location = cursor - - -Now try copy this script into Blender and run it on the default cube. -Make sure you click to move the 3D cursor before running as the duplicate will appear at the cursor's location. - - -... go off and test ... - - -After running, notice that when you go into edit-mode to change the cube - all of the copies change, -in Blender this is known as *Linked-Duplicates*. - - -Next, we're going to do this in a loop, to make an array of objects between the active object and the cursor. - - -.. code-block:: python - - import bpy - from bpy import context - - scene = context.scene - cursor = scene.cursor_location - obj = scene.objects.active - - # Use a fixed value for now, eventually make this user adjustable - total = 10 - - # Add 'total' objects into the scene - for i in range(total): - obj_new = obj.copy() - scene.objects.link(obj_new) - - # Now place the object in between the cursor - # and the active object based on 'i' - factor = i / total - obj_new.location = (obj.location * factor) + (cursor * (1.0 - factor)) - - -Try run this script with with the active object and the cursor spaced apart to see the result. - -With this script you'll notice we're doing some math with the object location and cursor, this works because both are -3D :class:`mathutils.Vector` instances, a convenient class provided by the :mod:`mathutils` module and -allows vectors to be multiplied by numbers and matrices. - -If you are interested in this area, read into :class:`mathutils.Vector` - there are many handy utility functions -such as getting the angle between vectors, cross product, dot products -as well as more advanced functions in :mod:`mathutils.geometry` such as Bézier Spline interpolation and -ray-triangle intersection. - -For now we will focus on making this script an add-on, but its good to know that this 3D math module is available and -can help you with more advanced functionality later on. - - -Write the Add-on ----------------- - -The first step is to convert the script as-is into an add-on. - - -.. code-block:: python - - bl_info = { - "name": "Cursor Array", - "category": "Object", - } - - import bpy - - - class ObjectCursorArray(bpy.types.Operator): - """Object Cursor Array""" - bl_idname = "object.cursor_array" - bl_label = "Cursor Array" - bl_options = {'REGISTER', 'UNDO'} - - def execute(self, context): - scene = context.scene - cursor = scene.cursor_location - obj = scene.objects.active - - total = 10 - - for i in range(total): - obj_new = obj.copy() - scene.objects.link(obj_new) - - factor = i / total - obj_new.location = (obj.location * factor) + (cursor * (1.0 - factor)) - - return {'FINISHED'} - - def register(): - bpy.utils.register_class(ObjectCursorArray) - - - def unregister(): - bpy.utils.unregister_class(ObjectCursorArray) - - - if __name__ == "__main__": - register() - - -Everything here has been covered in the previous steps, you may want to try run the add-on still -and consider what could be done to make it more useful. - - -... go off and test ... - - -The two of the most obvious missing things are - having the total fixed at 10, and having to access the operator from -space-bar is not very convenient. - -Both these additions are explained next, with the final script afterwards. - - -Operator Property -^^^^^^^^^^^^^^^^^ - -There are a variety of property types that are used for tool settings, common property types include: -int, float, vector, color, boolean and string. - -These properties are handled differently to typical Python class attributes -because Blender needs to be display them in the interface, -store their settings in key-maps and keep settings for re-use. - -While this is handled in a fairly Pythonic way, be mindful that you are in fact defining tool settings that -are loaded into Blender and accessed by other parts of Blender, outside of Python. - - -To get rid of the literal 10 for `total`, we'll us an operator property. -Operator properties are defined via bpy.props module, this is added to the class body. - -.. code-block:: python - - # moved assignment from execute() to the body of the class... - total = bpy.props.IntProperty(name="Steps", default=2, min=1, max=100) - - # and this is accessed on the class - # instance within the execute() function as... - self.total - - -These properties from :mod:`bpy.props` are handled specially by Blender when the class is registered -so they display as buttons in the user interface. -There are many arguments you can pass to properties to set limits, change the default and display a tooltip. - -.. seealso:: :mod:`bpy.props.IntProperty` - -This document doesn't go into details about using other property types, -however the link above includes examples of more advanced property usage. - - -Menu Item -^^^^^^^^^ - -Add-ons can add to the user interface of existing panels, headers and menus defined in Python. - -For this example we'll add to an existing menu. - -.. image:: menu_id.png - :width: 334px - :align: center - :height: 128px - :alt: Menu Identifier - -To find the identifier of a menu you can hover your mouse over the menu item and the identifier is displayed. - -The method used for adding a menu item is to append a draw function into an existing class. - - -.. code-block:: python - - def menu_func(self, context): - self.layout.operator(ObjectCursorArray.bl_idname) - - def register(): - bpy.types.VIEW3D_MT_object.append(menu_func) - - -For docs on extending menus see: :doc:`bpy.types.Menu`. - - -Keymap -^^^^^^ - -In Blender, add-ons have their own keymaps so as not to interfere with Blenders built in key-maps. - -In the example below, a new object-mode :class:`bpy.types.KeyMap` is added, -then a :class:`bpy.types.KeyMapItem` is added to the key-map which references our newly added operator, -using :kbd:`Ctrl-Shift-Space` as the key shortcut to activate it. - - -.. code-block:: python - - # store keymaps here to access after registration - addon_keymaps = [] - - def register(): - - # handle the keymap - wm = bpy.context.window_manager - km = wm.keyconfigs.addon.keymaps.new(name='Object Mode', space_type='EMPTY') - - kmi = km.keymap_items.new(ObjectCursorArray.bl_idname, 'SPACE', 'PRESS', ctrl=True, shift=True) - kmi.properties.total = 4 - - addon_keymaps.append((km, kmi)) - - - def unregister(): - - # handle the keymap - for km, kmi in addon_keymaps: - km.keymap_items.remove(kmi) - addon_keymaps.clear() - - -Notice how the key-map item can have a different ``total`` setting then the default set by the operator, -this allows you to have multiple keys accessing the same operator with different settings. - - -.. note:: - - While :kbd:`Ctrl-Shift-Space` isn't a default Blender key shortcut, its hard to make sure add-ons won't - overwrite each others keymaps, At least take care when assigning keys that they don't - conflict with important functionality within Blender. - -For API documentation on the functions listed above, see: -:class:`bpy.types.KeyMaps.new`, -:class:`bpy.types.KeyMap`, -:class:`bpy.types.KeyMapItems.new`, -:class:`bpy.types.KeyMapItem`. - - -Bringing it all together -^^^^^^^^^^^^^^^^^^^^^^^^ - -.. code-block:: python - - bl_info = { - "name": "Cursor Array", - "category": "Object", - } - - import bpy - - - class ObjectCursorArray(bpy.types.Operator): - """Object Cursor Array""" - bl_idname = "object.cursor_array" - bl_label = "Cursor Array" - bl_options = {'REGISTER', 'UNDO'} - - total = bpy.props.IntProperty(name="Steps", default=2, min=1, max=100) - - def execute(self, context): - scene = context.scene - cursor = scene.cursor_location - obj = scene.objects.active - - for i in range(self.total): - obj_new = obj.copy() - scene.objects.link(obj_new) - - factor = i / self.total - obj_new.location = (obj.location * factor) + (cursor * (1.0 - factor)) - - return {'FINISHED'} - - - def menu_func(self, context): - self.layout.operator(ObjectCursorArray.bl_idname) - - # store keymaps here to access after registration - addon_keymaps = [] - - - def register(): - bpy.utils.register_class(ObjectCursorArray) - bpy.types.VIEW3D_MT_object.append(menu_func) - - # handle the keymap - wm = bpy.context.window_manager - # Note that in background mode (no GUI available), keyconfigs are not available either, so we have to check this - # to avoid nasty errors in background case. - kc = wm.keyconfigs.addon - if kc: - km = wm.keyconfigs.addon.keymaps.new(name='Object Mode', space_type='EMPTY') - kmi = km.keymap_items.new(ObjectCursorArray.bl_idname, 'SPACE', 'PRESS', ctrl=True, shift=True) - kmi.properties.total = 4 - addon_keymaps.append((km, kmi)) - - def unregister(): - # Note: when unregistering, it's usually good practice to do it in reverse order you registered. - # Can avoid strange issues like keymap still referring to operators already unregistered... - # handle the keymap - for km, kmi in addon_keymaps: - km.keymap_items.remove(kmi) - addon_keymaps.clear() - - bpy.utils.unregister_class(ObjectCursorArray) - bpy.types.VIEW3D_MT_object.remove(menu_func) - - - if __name__ == "__main__": - register() - -.. image:: in_menu.png - :width: 591px - :align: center - :height: 649px - :alt: In the menu - -Run the script (or save it and add it through the Preferences like before) and it will appear in the menu. - -.. image:: op_prop.png - :width: 669px - :align: center - :height: 644px - :alt: Operator Property - -After selecting it from the menu, you can choose how many instance of the cube you want created. - - -.. note:: - - Directly executing the script multiple times will add the menu each time too. - While not useful behavior, theres nothing to worry about since add-ons won't register them selves multiple - times when enabled through the user preferences. - - -Conclusions -=========== - -Add-ons can encapsulate certain functionality neatly for writing tools to improve your work-flow or for writing utilities -for others to use. - -While there are limits to what Python can do within Blender, there is certainly a lot that can be achieved without -having to dive into Blender's C/C++ code. - -The example given in the tutorial is limited, but shows the Blender API used for common tasks that you can expand on -to write your own tools. - - -Further Reading ---------------- - -Blender comes commented templates which are accessible from the text editor header, if you have specific areas -you want to see example code for, this is a good place to start. - - -Here are some sites you might like to check on after completing this tutorial. - -- :ref:`Blender/Python API Overview <info_overview>` - - *For more background details on Blender/Python integration.* -- `How to Think Like a Computer Scientist <http://interactivepython.org/courselib/static/thinkcspy/index.html>`_ - - *Great info for those who are still learning Python.* -- `Blender Development (Wiki) <https://wiki.blender.org/index.php/Dev:Contents>`_ - - *Blender Development, general information and helpful links.* -- `Blender Artists (Coding Section) <https://blenderartists.org/forum/forumdisplay.php?47-Coding>`_ - - *forum where people ask Python development questions* - diff --git a/doc/python_api/rst_from_bmesh_opdefines.py b/doc/python_api/rst_from_bmesh_opdefines.py index cdbed88cc88..d3e4b2a0cfd 100644 --- a/doc/python_api/rst_from_bmesh_opdefines.py +++ b/doc/python_api/rst_from_bmesh_opdefines.py @@ -22,7 +22,7 @@ # 'bmesh_opdefines.c' in order to avoid having to add a lot of introspection # data access into the api. # -# The script is stupid becase it makes assumptions about formatting... +# The script is stupid because it makes assumptions about formatting... # that each arg has its own line, that comments above or directly after will be __doc__ etc... # # We may want to replace this script with something else one day but for now its good enough. diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py index 47bb323e574..3b0e8f52c83 100644 --- a/doc/python_api/sphinx_doc_gen.py +++ b/doc/python_api/sphinx_doc_gen.py @@ -341,6 +341,8 @@ EXTRA_SOURCE_FILES = ( "../examples/bge.texture.py", "../examples/bmesh.ops.1.py", "../examples/bpy.app.translations.py", + "../static/favicon.ico", + "../static/blender_logo.svg", ) @@ -362,8 +364,6 @@ INFO_DOCS = ( "Blender/Python Quickstart: new to Blender/scripting and want to get your feet wet?"), ("info_overview.rst", "Blender/Python API Overview: a more complete explanation of Python integration"), - ("info_tutorial_addon.rst", - "Blender/Python Add-on Tutorial: a step by step guide on how to write an add-on from scratch"), ("info_api_reference.rst", "Blender/Python API Reference Usage: examples of how to use the API reference docs"), ("info_best_practice.rst", @@ -1613,10 +1613,8 @@ def pyrna2sphinx(basepath): else: url_base = API_BASEURL - fw(" :file: `%s <%s/%s>`_:%d\n\n" % (location[0], - url_base, - location[0], - location[1])) + fw(" :file: `%s\\:%d <%s/%s$%d>`_\n\n" % + (location[0], location[1], url_base, location[0], location[1])) file.close() @@ -1646,14 +1644,14 @@ def write_sphinx_conf_py(basepath): if ARGS.sphinx_theme == "blender-org": fw("html_theme_path = ['../']\n") - # copied with the theme, exclude else we get an error [T28873] - fw("html_favicon = 'favicon.ico'\n") # in <theme>/static/ # not helpful since the source is generated, adds to upload size. fw("html_copy_source = False\n") fw("html_show_sphinx = False\n") fw("html_split_index = True\n") - fw("\n") + fw("html_extra_path = ['__/static/favicon.ico', '__/static/blender_logo.svg']\n") + fw("html_favicon = '__/static/favicon.ico'\n") + fw("html_logo = '__/static/blender_logo.svg'\n\n") # needed for latex, pdf gen fw("latex_elements = {\n") @@ -1699,6 +1697,9 @@ def write_rst_contents(basepath): for info, info_desc in INFO_DOCS: fw(" %s <%s>\n\n" % (info_desc, info)) fw("\n") + fw("- :ref:`Blender/Python Add-on Tutorial: a step by step guide on") + fw(" how to write an add-on from scratch <blender_manual:advanced_scripting_addon_tutorial>`\n") + fw("\n") fw(title_string("Application Modules", "=", double=True)) fw(".. toctree::\n") @@ -1715,8 +1716,6 @@ def write_rst_contents(basepath): "bpy.utils.previews", "bpy.path", "bpy.app", - "bpy.app.handlers", - "bpy.app.translations", # C modules "bpy.props", @@ -1731,19 +1730,9 @@ def write_rst_contents(basepath): fw(" :maxdepth: 1\n\n") standalone_modules = ( - # mathutils - "mathutils", - "mathutils.geometry", - "mathutils.bvhtree", "mathutils.kdtree", - "mathutils.interpolate", - "mathutils.noise", - # misc - "freestyle", "bgl", "blf", - "gpu", "gpu.offscreen", - "aud", "bpy_extras", - "idprop.types", - # bmesh, submodules are in own page - "bmesh", + # submodules are added in parent page + "mathutils", "freestyle", "bgl", "blf", "gpu", + "aud", "bpy_extras", "idprop.types", "bmesh", ) for mod in standalone_modules: diff --git a/doc/python_api/static/blender_logo.svg b/doc/python_api/static/blender_logo.svg new file mode 100644 index 00000000000..bbf446c9bec --- /dev/null +++ b/doc/python_api/static/blender_logo.svg @@ -0,0 +1,116 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<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" + id="svg8" + version="1.1" + viewBox="0 0 55.032989 15.935012" + height="60.226818" + width="207.9987"> + <defs + id="defs2"> + <clipPath + clipPathUnits="userSpaceOnUse" + id="clipPath3020"> + <path + style="stroke-width:1.06666672" + d="M 0,0 H 211.2 V 61.866667 H 0 Z" + id="path3022" /> + </clipPath> + <clipPath + clipPathUnits="userSpaceOnUse" + id="clipPath3020-8"> + <path + style="stroke-width:1.06666672" + d="M 0,0 H 211.2 V 61.866667 H 0 Z" + id="path3022-1" /> + </clipPath> + </defs> + <metadata + id="metadata5"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:creator> + <cc:Agent> + <dc:title>Blender Logo</dc:title> + </cc:Agent> + </dc:creator> + <dc:source>https://www.blender.org/about/logo/</dc:source> + <cc:license + rdf:resource="(c) Blender Foundation" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + transform="translate(42.023693,-77.734934)" + id="layer1"> + <g + transform="matrix(0.26259939,0,0,-0.26259939,-42.237694,93.888967)" + id="g3012" + style="stroke-width:7.2904439"> + <g + id="g3014" + style="stroke-width:7.2904439" /> + <g + id="g3016" + style="stroke-width:7.2904439"> + <g + clip-path="url(#clipPath3020-8)" + id="g3018" + style="stroke-width:7.2904439"> + <path + id="path3024" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7.77647352" + d="m 192.54827,44.510933 c 0,0 -125.158403,0 -128.688003,0 -0.07893,0.06187 -0.1504,0.1344 -0.2272,0.193067 -0.01813,0.0192 -18.9312,14.548267 -19.5008,14.986667 -0.032,0.0256 -0.06507,0.04907 -0.06507,0.04907 -3.029333,2.321067 -7.531733,2.369067 -10.721067,0.133334 -1.9968,-1.396267 -3.194666,-3.508267 -3.285333,-5.792 -0.0021,-0.09173 -0.0064,-0.1824 -0.0064,-0.2752 0,-1.185067 0.314667,-2.3296 0.8832,-3.357867 -5.857067,-0.0053 -11.746133,-0.0128 -11.746133,-0.0128 -4.3936,-0.0021 -8.3648,-2.965333 -9.2725337,-6.8928 C 9.7898667,42.9792 9.7248,42.411733 9.7248,41.8496 c 0,-1.643733 0.546133,-3.236267 1.5808,-4.542933 1.162667,-1.463467 2.842667,-2.448 4.7584,-2.832 C 10.530133,30.2272 5.0016,25.984 4.9973333,25.979733 4.9578667,25.949867 4.9248,25.924267 4.8970667,25.905067 c -2.2176,-1.703467 -3.68,-4.1728 -4.0106667,-6.770134 -0.0490667,-0.381866 -0.0714667,-0.7584 -0.0714667,-1.133866 0,-1.870934 0.5962667,-3.650134 1.7301334,-5.102934 1.3781333,-1.764266 3.4144,-2.884266 5.7322666,-3.147733 2.6549337,-0.3072 5.4495997,0.542933 7.6607997,2.330667 0.01493,0.01173 2.753067,2.256 5.639467,4.6176 1.060267,-2.555734 2.545067,-4.926934 4.465067,-7.0453337 2.4704,-2.7306666 5.473066,-4.8864 8.919466,-6.4128 C 38.5856,1.6352 42.466133,0.82453333 46.501333,0.83413333 50.5376,0.8416 54.417067,1.6629333 58.0352,3.2768 c 3.453867,1.5466667 6.449067,3.7109333 8.910933,6.4352 0.360534,0.4032 0.693334,0.8288 1.0272,1.2544 4.885334,0 124.574937,0 124.574937,0 9.84,0 17.8368,7.5232 17.8368,16.7712 0,9.248 -7.9968,16.773333 -17.8368,16.773333" /> + <path + id="path3026" + style="fill:#0d528a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7.77647352" + d="m 38.538667,28.497067 c 0.113066,2.016 1.101866,3.793066 2.590933,5.0528 1.4624,1.237333 3.428267,1.9936 5.575467,1.9936 2.144,0 4.110933,-0.756267 5.572266,-1.9936 1.490134,-1.259734 2.4768,-3.0368 2.590934,-5.050667 0.113066,-2.0736 -0.718934,-3.997867 -2.181334,-5.425067 C 51.1968,21.6224 49.0784,20.7104 46.705067,20.7104 c -2.3744,0 -4.497067,0.912 -5.9872,2.363733 -1.461334,1.4272 -2.292267,3.351467 -2.1792,5.422934" /> + <path + id="path3028" + style="fill:#f5792a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7.77647352" + d="m 25.536,24.421333 c 0.01387,-0.7904 0.2656,-2.3232 0.6432,-3.521066 C 26.9728,18.3648 28.318933,16.0192 30.193067,13.950933 32.1152,11.8272 34.482133,10.119467 37.216,8.9088 c 2.872533,-1.2736 5.986133,-1.9210667 9.220267,-1.9157333 3.229866,0.00427 6.3424,0.6656 9.216,1.9477333 2.733866,1.2224 5.098666,2.9376 7.018666,5.063467 1.870934,2.074666 3.216,4.424533 4.010667,6.96 0.401067,1.282133 0.6528,2.581333 0.754133,3.886933 0.100267,1.285333 0.0576,2.571733 -0.1248,3.858133 -0.356266,2.507734 -1.223466,4.858667 -2.557866,7.002667 -1.2224,1.970133 -2.7968,3.696 -4.6688,5.147733 l 0.0053,0.0021 -18.8928,14.506666 c -0.016,0.0128 -0.02987,0.02667 -0.048,0.03733 -1.240533,0.952533 -3.3248,0.948266 -4.686933,-0.0053 -1.3792,-0.9632 -1.536,-2.557866 -0.3104,-3.5648 l -0.0043,-0.0043 7.8784,-6.407467 -24.016,-0.02667 c -0.01173,0 -0.0224,0 -0.032,0 -1.985067,-0.0011 -3.893333,-1.303466 -4.269867,-2.9504 -0.389333,-1.6768 0.958934,-3.067733 3.022934,-3.074133 l -0.0021,-0.0075 L 30.900267,39.3888 9.1786667,22.715733 c -0.026667,-0.02133 -0.0576,-0.0416 -0.0832,-0.06293 -2.0490667,-1.568 -2.7104,-4.178133 -1.4197334,-5.828267 1.3088,-1.68 4.0949337,-1.6832 6.1653337,-0.0096 L 25.696,26.516267 c 0,0 -0.173867,-1.3088 -0.16,-2.094934 z M 56,20.034133 c -2.443733,-2.488533 -5.8624,-3.899733 -9.563733,-3.9072 -3.7056,-0.0064 -7.124267,1.393067 -9.568,3.877334 -1.1936,1.210666 -2.0704,2.602666 -2.6112,4.087466 -0.529067,1.457067 -0.736,3.0048 -0.599467,4.5664 0.130133,1.527467 0.583467,2.9824 1.309867,4.3008 0.712533,1.293867 1.6928,2.465067 2.9056,3.454934 2.373333,1.934933 5.396266,2.981333 8.558933,2.9856 3.1648,0.0053 6.1856,-1.0336 8.561067,-2.961067 1.2096,-0.9856 2.190933,-2.151467 2.903466,-3.445333 0.728534,-1.316267 1.179734,-2.765867 1.314134,-4.2976 C 59.344,27.136 59.138133,25.5904 58.609067,24.1312 58.0672,22.6432 57.1936,21.2512 56,20.034133" /> + <path + id="path3030" + style="fill:#0d528a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7.77647352" + d="m 167.96587,28.529067 c 0.1824,2.0352 1.75466,3.325866 4.15786,3.325866 2.4064,0 3.97974,-1.290666 4.16214,-3.325866 z M 176.0384,23.504 c -0.61547,-1.508267 -2.06507,-2.401067 -4.03627,-2.401067 -2.46613,0 -4.12693,1.540267 -4.1952,3.9744 h 14.18347 c 0,0.251734 0,0.462934 0,0.715734 0,6.094933 -3.57653,9.518933 -9.98827,9.518933 -6.22506,0 -9.98826,-3.457067 -9.98826,-8.878933 0,-5.454934 3.82293,-8.9056 9.98826,-8.9056 3.70134,0 6.5696,1.2672 8.33814,3.4976 L 176.0384,23.504" /> + <path + id="path3032" + style="fill:#0d528a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7.77647352" + d="m 105.0336,28.519467 c 0.18667,2.036266 1.76,3.326933 4.16533,3.326933 2.40214,0 3.97547,-1.290667 4.15894,-3.326933 z m 8.07787,-5.025067 c -0.61547,-1.512533 -2.06614,-2.404267 -4.03947,-2.404267 -2.464,0 -4.12907,1.544534 -4.19413,3.9776 h 14.18026 c 0,0.2496 0,0.4608 0,0.712534 0,6.098133 -3.57546,9.524266 -9.98613,9.524266 -6.22933,0 -9.986133,-3.458133 -9.986133,-8.88 0,-5.456 3.821863,-8.906666 9.986133,-8.906666 3.6992,0 6.5696,1.262933 8.34133,3.495466 l -4.30186,2.481067" /> + <path + id="path3034" + style="fill:#0d528a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7.77647352" + d="m 92.701867,38.997333 h 5.114666 v -20.9248 h -5.114666 z" /> + <path + id="path3036" + style="fill:#0d528a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7.77647352" + d="m 120.33067,33.438933 h 5.14453 v -1.245866 c 1.8208,1.9424 4.00747,2.9248 6.47253,2.9248 2.84054,0 4.992,-0.9824 6.1024,-2.653867 0.92587,-1.381333 0.98774,-3.0496 0.98774,-5.239467 v -9.152 h -5.15094 v 8.040534 c 0,3.336533 -0.67093,4.877866 -3.6,4.877866 -2.96106,0 -4.81173,-1.764266 -4.81173,-4.724266 v -8.194134 h -5.14453 v 15.3664" /> + <path + id="path3038" + style="fill:#0d528a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7.77647352" + d="m 155.60107,26.173867 c 0,-2.864 -1.9136,-4.741334 -4.8736,-4.741334 -2.96427,0 -4.87787,1.813334 -4.87787,4.709334 0,2.9376 1.88907,4.750933 4.87787,4.750933 2.96,0 4.8736,-1.8464 4.8736,-4.718933 z m 0,6.568533 c -1.30027,1.393067 -3.1808,2.157867 -5.79734,2.157867 -5.64266,0 -9.49546,-3.479467 -9.49546,-8.6944 0,-5.112534 3.82613,-8.688 9.40266,-8.688 2.5568,0 4.4352,0.645333 5.89014,2.096 v -1.541334 h 5.14666 v 22.2528 l -5.14666,-1.328 V 32.7424" /> + <path + id="path3040" + style="fill:#0d528a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7.77647352" + d="m 81.010133,30.8928 c 2.990934,0 4.871467,-1.813333 4.871467,-4.750933 0,-2.896 -1.9104,-4.709334 -4.871467,-4.709334 -2.958933,0 -4.869333,1.877334 -4.869333,4.741334 0,2.872533 1.9104,4.718933 4.869333,4.718933 z m -4.869333,8.104533 -5.1488,1.328 v -22.2528 h 5.1488 v 1.541334 c 1.448533,-1.450667 3.329067,-2.096 5.886933,-2.096 5.579734,0 9.4016,3.575466 9.4016,8.688 0,5.214933 -3.853866,8.6944 -9.493333,8.6944 -2.621867,0 -4.5024,-0.7648 -5.7952,-2.157867 v 6.254933" /> + <path + id="path3042" + style="fill:#0d528a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7.77647352" + d="m 183.2608,18.072533 v 15.3664 h 5.14667 v -0.9504 c 1.54026,1.857067 3.1712,2.7808 5.0272,2.7808 0.368,0 0.82986,-0.05973 1.44533,-0.1216 V 30.768 c -0.496,0.064 -1.04747,0.064 -1.6352,0.064 -2.992,0 -4.83733,-1.972267 -4.83733,-5.329067 v -7.4304 h -5.14667" /> + <path + id="path3044" + style="fill:#0d528a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7.77647352" + d="m 201.55307,35.252267 h -0.39467 l 0.0139,1.409066 0.0203,0.466134 -0.1056,-0.384 -0.46826,-1.4912 h -0.36054 l -0.45866,1.4912 -0.1152,0.376533 0.0277,-0.458667 0.0139,-1.409066 h -0.38614 v 2.282666 h 0.54187 l 0.57067,-1.8016 0.5568,1.8016 h 0.544 z m -3.12747,0 h -0.39787 V 37.1968 h -0.7328 v 0.338133 h 1.85067 V 37.1968 h -0.72 v -1.944533" /> + </g> + </g> + </g> + </g> +</svg> diff --git a/doc/python_api/blender-org/static/favicon.ico b/doc/python_api/static/favicon.ico Binary files differindex f125d24dcb6..f125d24dcb6 100644 --- a/doc/python_api/blender-org/static/favicon.ico +++ b/doc/python_api/static/favicon.ico diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index b5149b5082e..3018fd5b316 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -239,7 +239,8 @@ def register_passes(engine, scene, srl): if crl.pass_debug_bvh_intersections: engine.register_pass(scene, srl, "Debug BVH Intersections", 1, "X", 'VALUE') if crl.pass_debug_ray_bounces: engine.register_pass(scene, srl, "Debug Ray Bounces", 1, "X", 'VALUE') - if crl.use_denoising and crl.denoising_store_passes: + cscene = scene.cycles + if crl.use_denoising and crl.denoising_store_passes and not cscene.use_progressive_refine: engine.register_pass(scene, srl, "Denoising Normal", 3, "XYZ", 'VECTOR') engine.register_pass(scene, srl, "Denoising Normal Variance", 3, "XYZ", 'VECTOR') engine.register_pass(scene, srl, "Denoising Albedo", 3, "RGB", 'COLOR') diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 8bb25aba13c..68474529ed3 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -695,10 +695,17 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): update=devices_update_callback ) - cls.debug_opencl_kernel_single_program = BoolProperty(name="Single Program", default=True, update=devices_update_callback); + cls.debug_opencl_kernel_single_program = BoolProperty( + name="Single Program", + default=True, + update=devices_update_callback, + ) cls.debug_use_opencl_debug = BoolProperty(name="Debug OpenCL", default=False) + cls.debug_opencl_mem_limit = IntProperty(name="Memory limit", default=0, + description="Artificial limit on OpenCL memory usage in MB (0 to disable limit)") + @classmethod def unregister(cls): del bpy.types.Scene.cycles @@ -1209,6 +1216,7 @@ class CyclesRenderLayerSettings(bpy.types.PropertyGroup): name="Use Denoising", description="Denoise the rendered image", default=False, + update=update_render_passes, ) cls.denoising_diffuse_direct = BoolProperty( name="Diffuse Direct", diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 4ed3ccd9a2c..49beebe5ab4 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -531,17 +531,17 @@ class CyclesRender_PT_layer_passes(CyclesButtonsPanel, Panel): col.prop(rl, "use_pass_environment") if context.scene.cycles.feature_set == 'EXPERIMENTAL': - col.separator() - sub = col.column() - sub.active = crl.use_denoising - sub.prop(crl, "denoising_store_passes", text="Denoising") + col.separator() + sub = col.column() + sub.active = crl.use_denoising + sub.prop(crl, "denoising_store_passes", text="Denoising") if _cycles.with_cycles_debug: - col = layout.column() - col.prop(crl, "pass_debug_bvh_traversed_nodes") - col.prop(crl, "pass_debug_bvh_traversed_instances") - col.prop(crl, "pass_debug_bvh_intersections") - col.prop(crl, "pass_debug_ray_bounces") + col = layout.column() + col.prop(crl, "pass_debug_bvh_traversed_nodes") + col.prop(crl, "pass_debug_bvh_traversed_instances") + col.prop(crl, "pass_debug_bvh_intersections") + col.prop(crl, "pass_debug_ray_bounces") class CyclesRender_PT_views(CyclesButtonsPanel, Panel): @@ -1608,6 +1608,7 @@ class CyclesRender_PT_debug(CyclesButtonsPanel, Panel): col.prop(cscene, "debug_opencl_device_type", text="Device") col.prop(cscene, "debug_opencl_kernel_single_program", text="Single Program") col.prop(cscene, "debug_use_opencl_debug", text="Debug") + col.prop(cscene, "debug_opencl_mem_limit") class CyclesParticle_PT_CurveSettings(CyclesButtonsPanel, Panel): @@ -1710,7 +1711,7 @@ def draw_device(self, context): layout.prop(cscene, "feature_set") - split = layout.split(percentage=1/3) + split = layout.split(percentage=1 / 3) split.label("Device:") row = split.row() row.active = show_device_active(context) diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp index 01570b1e3f9..54973fd1b7f 100644 --- a/intern/cycles/blender/blender_python.cpp +++ b/intern/cycles/blender/blender_python.cpp @@ -106,6 +106,7 @@ bool debug_flags_sync_from_scene(BL::Scene b_scene) } /* Synchronize other OpenCL flags. */ flags.opencl.debug = get_boolean(cscene, "debug_use_opencl_debug"); + flags.opencl.mem_limit = ((size_t)get_int(cscene, "debug_opencl_mem_limit"))*1024*1024; flags.opencl.single_program = get_boolean(cscene, "debug_opencl_kernel_single_program"); return flags.opencl.device_type != opencl_device_type || flags.opencl.kernel_type != opencl_kernel_type; diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index c6a59577507..2b5dd5eadea 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -399,14 +399,7 @@ void BlenderSession::render() BL::RenderLayer b_rlay = *b_single_rlay; /* add passes */ - array<Pass> passes; - if(session_params.device.advanced_shading) { - passes = sync->sync_render_passes(b_rlay, *b_layer_iter); - } - else { - Pass::add(PASS_COMBINED, passes); - } - + array<Pass> passes = sync->sync_render_passes(b_rlay, *b_layer_iter, session_params); buffer_params.passes = passes; PointerRNA crl = RNA_pointer_get(&b_layer_iter->ptr, "cycles"); diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 41723599874..3a00384458a 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -553,11 +553,16 @@ int BlenderSync::get_denoising_pass(BL::RenderPass& b_pass) } array<Pass> BlenderSync::sync_render_passes(BL::RenderLayer& b_rlay, - BL::SceneRenderLayer& b_srlay) + BL::SceneRenderLayer& b_srlay, + const SessionParams &session_params) { array<Pass> passes; Pass::add(PASS_COMBINED, passes); + if(!session_params.device.advanced_shading) { + return passes; + } + /* loop over passes */ BL::RenderLayer::passes_iterator b_pass_iter; @@ -572,7 +577,9 @@ array<Pass> BlenderSync::sync_render_passes(BL::RenderLayer& b_rlay, } PointerRNA crp = RNA_pointer_get(&b_srlay.ptr, "cycles"); - if(get_boolean(crp, "denoising_store_passes")) { + if(get_boolean(crp, "denoising_store_passes") && + get_boolean(crp, "use_denoising") && + !session_params.progressive_refine) { b_engine.add_pass("Denoising Normal", 3, "XYZ", b_srlay.name().c_str()); b_engine.add_pass("Denoising Normal Variance", 3, "XYZ", b_srlay.name().c_str()); b_engine.add_pass("Denoising Albedo", 3, "RGB", b_srlay.name().c_str()); diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 0950285d976..4ec46424b5a 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -68,7 +68,8 @@ public: const char *layer = 0); void sync_render_layers(BL::SpaceView3D& b_v3d, const char *layer); array<Pass> sync_render_passes(BL::RenderLayer& b_rlay, - BL::SceneRenderLayer& b_srlay); + BL::SceneRenderLayer& b_srlay, + const SessionParams &session_params); void sync_integrator(); void sync_camera(BL::RenderSettings& b_render, BL::Object& b_override, diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp index 0603ecb3afb..a54bb77f9f3 100644 --- a/intern/cycles/device/device.cpp +++ b/intern/cycles/device/device.cpp @@ -68,6 +68,8 @@ std::ostream& operator <<(std::ostream &os, << string_from_bool(requested_features.use_transparent) << std::endl; os << "Use Principled BSDF: " << string_from_bool(requested_features.use_principled) << std::endl; + os << "Use Denoising: " + << string_from_bool(requested_features.use_denoising) << std::endl; return os; } diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h index 527940e8f50..b3b693c630c 100644 --- a/intern/cycles/device/device.h +++ b/intern/cycles/device/device.h @@ -127,6 +127,9 @@ public: /* Per-uber shader usage flags. */ bool use_principled; + /* Denoising features. */ + bool use_denoising; + DeviceRequestedFeatures() { /* TODO(sergey): Find more meaningful defaults. */ @@ -145,6 +148,7 @@ public: use_transparent = false; use_shadow_tricks = false; use_principled = false; + use_denoising = false; } bool modified(const DeviceRequestedFeatures& requested_features) @@ -163,7 +167,8 @@ public: use_patch_evaluation == requested_features.use_patch_evaluation && use_transparent == requested_features.use_transparent && use_shadow_tricks == requested_features.use_shadow_tricks && - use_principled == requested_features.use_principled); + use_principled == requested_features.use_principled && + use_denoising == requested_features.use_denoising); } /* Convert the requested features structure to a build options, @@ -213,6 +218,9 @@ public: if(!use_principled) { build_options += " -D__NO_PRINCIPLED__"; } + if(!use_denoising) { + build_options += " -D__NO_DENOISING__"; + } return build_options; } }; diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp index c2f74aa8903..18112437b45 100644 --- a/intern/cycles/device/device_cpu.cpp +++ b/intern/cycles/device/device_cpu.cpp @@ -149,7 +149,8 @@ public: device_memory& use_queues_flag, device_memory& work_pool_wgs); - virtual SplitKernelFunction* get_split_kernel_function(string kernel_name, const DeviceRequestedFeatures&); + virtual SplitKernelFunction* get_split_kernel_function(const string& kernel_name, + const DeviceRequestedFeatures&); virtual int2 split_kernel_local_size(); virtual int2 split_kernel_global_size(device_memory& kg, device_memory& data, DeviceTask *task); virtual uint64_t state_buffer_size(device_memory& kg, device_memory& data, size_t num_threads); @@ -185,9 +186,9 @@ public: KernelFunctions<void(*)(int, int, float*, float*, float*, float*, int*, int, int)> filter_nlm_update_output_kernel; KernelFunctions<void(*)(float*, float*, int*, int)> filter_nlm_normalize_kernel; - KernelFunctions<void(*)(float*, int, int, int, float*, int*, int*, int, int, float)> filter_construct_transform_kernel; - KernelFunctions<void(*)(int, int, float*, float*, float*, float*, float*, int*, float*, float3*, int*, int*, int, int, int, int)> filter_nlm_construct_gramian_kernel; - KernelFunctions<void(*)(int, int, int, int, int, float*, int*, float*, float3*, int*, int)> filter_finalize_kernel; + KernelFunctions<void(*)(float*, int, int, int, float*, int*, int*, int, int, float)> filter_construct_transform_kernel; + KernelFunctions<void(*)(int, int, float*, float*, float*, int*, float*, float3*, int*, int*, int, int, int, int)> filter_nlm_construct_gramian_kernel; + KernelFunctions<void(*)(int, int, int, int, int, float*, int*, float*, float3*, int*, int)> filter_finalize_kernel; KernelFunctions<void(*)(KernelGlobals *, ccl_constant KernelData*, ccl_global void*, int, ccl_global char*, ccl_global uint*, int, int, int, int, int, int, int, int, ccl_global int*, int, @@ -248,6 +249,7 @@ public: REGISTER_SPLIT_KERNEL(direct_lighting); REGISTER_SPLIT_KERNEL(shadow_blocked_ao); REGISTER_SPLIT_KERNEL(shadow_blocked_dl); + REGISTER_SPLIT_KERNEL(enqueue_inactive); REGISTER_SPLIT_KERNEL(next_iteration_setup); REGISTER_SPLIT_KERNEL(indirect_subsurface); REGISTER_SPLIT_KERNEL(buffer_update); @@ -465,8 +467,6 @@ public: bool denoising_reconstruct(device_ptr color_ptr, device_ptr color_variance_ptr, - device_ptr guide_ptr, - device_ptr guide_variance_ptr, device_ptr output_ptr, DenoisingTask *task) { @@ -485,8 +485,8 @@ public: task->reconstruction_state.source_w - max(0, dx), task->reconstruction_state.source_h - max(0, dy)}; filter_nlm_calc_difference_kernel()(dx, dy, - (float*) guide_ptr, - (float*) guide_variance_ptr, + (float*) color_ptr, + (float*) color_variance_ptr, difference, local_rect, task->buffer.w, @@ -499,8 +499,6 @@ public: filter_nlm_construct_gramian_kernel()(dx, dy, blurDifference, (float*) task->buffer.mem.device_pointer, - (float*) color_ptr, - (float*) color_variance_ptr, (float*) task->storage.transform.device_pointer, (int*) task->storage.rank.device_pointer, (float*) task->storage.XtWX.device_pointer, @@ -648,7 +646,7 @@ public: DenoisingTask denoising(this); denoising.functions.construct_transform = function_bind(&CPUDevice::denoising_construct_transform, this, &denoising); - denoising.functions.reconstruct = function_bind(&CPUDevice::denoising_reconstruct, this, _1, _2, _3, _4, _5, &denoising); + denoising.functions.reconstruct = function_bind(&CPUDevice::denoising_reconstruct, this, _1, _2, _3, &denoising); denoising.functions.divide_shadow = function_bind(&CPUDevice::denoising_divide_shadow, this, _1, _2, _3, _4, _5, &denoising); denoising.functions.non_local_means = function_bind(&CPUDevice::denoising_non_local_means, this, _1, _2, _3, _4, &denoising); denoising.functions.combine_halves = function_bind(&CPUDevice::denoising_combine_halves, this, _1, _2, _3, _4, _5, _6, &denoising); @@ -935,7 +933,8 @@ bool CPUSplitKernel::enqueue_split_kernel_data_init(const KernelDimensions& dim, return true; } -SplitKernelFunction* CPUSplitKernel::get_split_kernel_function(string kernel_name, const DeviceRequestedFeatures&) +SplitKernelFunction* CPUSplitKernel::get_split_kernel_function(const string& kernel_name, + const DeviceRequestedFeatures&) { CPUSplitKernelFunction *kernel = new CPUSplitKernelFunction(device); diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp index 99537e9a983..3a29538aa13 100644 --- a/intern/cycles/device/device_cuda.cpp +++ b/intern/cycles/device/device_cuda.cpp @@ -105,7 +105,8 @@ public: device_memory& use_queues_flag, device_memory& work_pool_wgs); - virtual SplitKernelFunction* get_split_kernel_function(string kernel_name, const DeviceRequestedFeatures&); + virtual SplitKernelFunction* get_split_kernel_function(const string& kernel_name, + const DeviceRequestedFeatures&); virtual int2 split_kernel_local_size(); virtual int2 split_kernel_global_size(device_memory& kg, device_memory& data, DeviceTask *task); }; @@ -1051,8 +1052,6 @@ public: bool denoising_reconstruct(device_ptr color_ptr, device_ptr color_variance_ptr, - device_ptr guide_ptr, - device_ptr guide_variance_ptr, device_ptr output_ptr, DenoisingTask *task) { @@ -1096,8 +1095,8 @@ public: task->reconstruction_state.source_h - max(0, dy)}; void *calc_difference_args[] = {&dx, &dy, - &guide_ptr, - &guide_variance_ptr, + &color_ptr, + &color_variance_ptr, &difference, &local_rect, &task->buffer.w, @@ -1126,8 +1125,6 @@ public: void *construct_gramian_args[] = {&dx, &dy, &blurDifference, &task->buffer.mem.device_pointer, - &color_ptr, - &color_variance_ptr, &task->storage.transform.device_pointer, &task->storage.rank.device_pointer, &task->storage.XtWX.device_pointer, @@ -1294,7 +1291,7 @@ public: DenoisingTask denoising(this); denoising.functions.construct_transform = function_bind(&CUDADevice::denoising_construct_transform, this, &denoising); - denoising.functions.reconstruct = function_bind(&CUDADevice::denoising_reconstruct, this, _1, _2, _3, _4, _5, &denoising); + denoising.functions.reconstruct = function_bind(&CUDADevice::denoising_reconstruct, this, _1, _2, _3, &denoising); denoising.functions.divide_shadow = function_bind(&CUDADevice::denoising_divide_shadow, this, _1, _2, _3, _4, _5, &denoising); denoising.functions.non_local_means = function_bind(&CUDADevice::denoising_non_local_means, this, _1, _2, _3, _4, &denoising); denoising.functions.combine_halves = function_bind(&CUDADevice::denoising_combine_halves, this, _1, _2, _3, _4, _5, _6, &denoising); @@ -2041,7 +2038,8 @@ bool CUDASplitKernel::enqueue_split_kernel_data_init(const KernelDimensions& dim return !device->have_error(); } -SplitKernelFunction* CUDASplitKernel::get_split_kernel_function(string kernel_name, const DeviceRequestedFeatures&) +SplitKernelFunction* CUDASplitKernel::get_split_kernel_function(const string& kernel_name, + const DeviceRequestedFeatures&) { CUfunction func; diff --git a/intern/cycles/device/device_denoising.cpp b/intern/cycles/device/device_denoising.cpp index 613bd9112cf..619cc1d171e 100644 --- a/intern/cycles/device/device_denoising.cpp +++ b/intern/cycles/device/device_denoising.cpp @@ -215,7 +215,7 @@ bool DenoisingTask::run_denoising() { device_sub_ptr color_ptr (device, buffer.mem, 8*buffer.pass_stride, 3*buffer.pass_stride, MEM_READ_WRITE); device_sub_ptr color_var_ptr(device, buffer.mem, 11*buffer.pass_stride, 3*buffer.pass_stride, MEM_READ_WRITE); - functions.reconstruct(*color_ptr, *color_var_ptr, *color_ptr, *color_var_ptr, render_buffer.ptr); + functions.reconstruct(*color_ptr, *color_var_ptr, render_buffer.ptr); } device->mem_free(storage.XtWX); diff --git a/intern/cycles/device/device_denoising.h b/intern/cycles/device/device_denoising.h index 25b93c2ad74..def7b72f67d 100644 --- a/intern/cycles/device/device_denoising.h +++ b/intern/cycles/device/device_denoising.h @@ -58,8 +58,6 @@ public: )> non_local_means; function<bool(device_ptr color_ptr, device_ptr color_variance_ptr, - device_ptr guide_ptr, - device_ptr guide_variance_ptr, device_ptr output_ptr )> reconstruct; function<bool()> construct_transform; diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp index edd2047debc..681b8214b03 100644 --- a/intern/cycles/device/device_opencl.cpp +++ b/intern/cycles/device/device_opencl.cpp @@ -130,10 +130,22 @@ string device_opencl_capabilities(void) opencl_assert(func(id, what, sizeof(data), &data, NULL)); \ result += string_printf("%s: %s\n", name, data); \ } while(false) +#define APPEND_STRING_EXTENSION_INFO(func, id, name, what) \ + do { \ + char data[1024] = "\0"; \ + size_t length = 0; \ + if(func(id, what, sizeof(data), &data, &length) == CL_SUCCESS) { \ + if(length != 0 && data[0] != '\0') { \ + result += string_printf("%s: %s\n", name, data); \ + } \ + } \ + } while(false) #define APPEND_PLATFORM_STRING_INFO(id, name, what) \ APPEND_STRING_INFO(clGetPlatformInfo, id, "\tPlatform " name, what) #define APPEND_DEVICE_STRING_INFO(id, name, what) \ APPEND_STRING_INFO(clGetDeviceInfo, id, "\t\t\tDevice " name, what) +#define APPEND_DEVICE_STRING_EXTENSION_INFO(id, name, what) \ + APPEND_STRING_EXTENSION_INFO(clGetDeviceInfo, id, "\t\t\tDevice " name, what) vector<cl_device_id> device_ids; for(cl_uint platform = 0; platform < num_platforms; ++platform) { @@ -167,6 +179,7 @@ string device_opencl_capabilities(void) result += string_printf("\t\tDevice: #%u\n", device); APPEND_DEVICE_STRING_INFO(device_id, "Name", CL_DEVICE_NAME); + APPEND_DEVICE_STRING_EXTENSION_INFO(device_id, "Board Name", CL_DEVICE_BOARD_NAME_AMD); APPEND_DEVICE_STRING_INFO(device_id, "Vendor", CL_DEVICE_VENDOR); APPEND_DEVICE_STRING_INFO(device_id, "OpenCL C Version", CL_DEVICE_OPENCL_C_VERSION); APPEND_DEVICE_STRING_INFO(device_id, "Profile", CL_DEVICE_PROFILE); diff --git a/intern/cycles/device/device_split_kernel.cpp b/intern/cycles/device/device_split_kernel.cpp index dddd19f179f..d2b3a89fa98 100644 --- a/intern/cycles/device/device_split_kernel.cpp +++ b/intern/cycles/device/device_split_kernel.cpp @@ -47,6 +47,7 @@ DeviceSplitKernel::DeviceSplitKernel(Device *device) : device(device) kernel_direct_lighting = NULL; kernel_shadow_blocked_ao = NULL; kernel_shadow_blocked_dl = NULL; + kernel_enqueue_inactive = NULL; kernel_next_iteration_setup = NULL; kernel_indirect_subsurface = NULL; kernel_buffer_update = NULL; @@ -74,6 +75,7 @@ DeviceSplitKernel::~DeviceSplitKernel() delete kernel_direct_lighting; delete kernel_shadow_blocked_ao; delete kernel_shadow_blocked_dl; + delete kernel_enqueue_inactive; delete kernel_next_iteration_setup; delete kernel_indirect_subsurface; delete kernel_buffer_update; @@ -101,6 +103,7 @@ bool DeviceSplitKernel::load_kernels(const DeviceRequestedFeatures& requested_fe LOAD_KERNEL(direct_lighting); LOAD_KERNEL(shadow_blocked_ao); LOAD_KERNEL(shadow_blocked_dl); + LOAD_KERNEL(enqueue_inactive); LOAD_KERNEL(next_iteration_setup); LOAD_KERNEL(indirect_subsurface); LOAD_KERNEL(buffer_update); @@ -256,6 +259,7 @@ bool DeviceSplitKernel::path_trace(DeviceTask *task, ENQUEUE_SPLIT_KERNEL(direct_lighting, global_size, local_size); ENQUEUE_SPLIT_KERNEL(shadow_blocked_ao, global_size, local_size); ENQUEUE_SPLIT_KERNEL(shadow_blocked_dl, global_size, local_size); + ENQUEUE_SPLIT_KERNEL(enqueue_inactive, global_size, local_size); ENQUEUE_SPLIT_KERNEL(next_iteration_setup, global_size, local_size); ENQUEUE_SPLIT_KERNEL(indirect_subsurface, global_size, local_size); ENQUEUE_SPLIT_KERNEL(queue_enqueue, global_size, local_size); diff --git a/intern/cycles/device/device_split_kernel.h b/intern/cycles/device/device_split_kernel.h index 68c2ba974a5..9c42cb58520 100644 --- a/intern/cycles/device/device_split_kernel.h +++ b/intern/cycles/device/device_split_kernel.h @@ -69,6 +69,7 @@ private: SplitKernelFunction *kernel_direct_lighting; SplitKernelFunction *kernel_shadow_blocked_ao; SplitKernelFunction *kernel_shadow_blocked_dl; + SplitKernelFunction *kernel_enqueue_inactive; SplitKernelFunction *kernel_next_iteration_setup; SplitKernelFunction *kernel_indirect_subsurface; SplitKernelFunction *kernel_buffer_update; @@ -124,7 +125,8 @@ public: device_memory& use_queues_flag, device_memory& work_pool_wgs) = 0; - virtual SplitKernelFunction* get_split_kernel_function(string kernel_name, const DeviceRequestedFeatures&) = 0; + virtual SplitKernelFunction* get_split_kernel_function(const string& kernel_name, + const DeviceRequestedFeatures&) = 0; virtual int2 split_kernel_local_size() = 0; virtual int2 split_kernel_global_size(device_memory& kg, device_memory& data, DeviceTask *task) = 0; }; diff --git a/intern/cycles/device/opencl/opencl.h b/intern/cycles/device/opencl/opencl.h index 27e196d1e68..7da690904aa 100644 --- a/intern/cycles/device/opencl/opencl.h +++ b/intern/cycles/device/opencl/opencl.h @@ -84,7 +84,7 @@ public: string *error = NULL); static bool device_version_check(cl_device_id device, string *error = NULL); - static string get_hardware_id(string platform_name, + static string get_hardware_id(const string& platform_name, cl_device_id device_id); static void get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices, bool force_all = false); @@ -130,6 +130,11 @@ public: cl_int* error = NULL); static cl_device_type get_device_type(cl_device_id device_id); + static bool get_driver_version(cl_device_id device_id, + int *major, + int *minor, + cl_int* error = NULL); + static int mem_address_alignment(cl_device_id device_id); /* Get somewhat more readable device name. @@ -242,17 +247,17 @@ public: public: OpenCLProgram() : loaded(false), device(NULL) {} OpenCLProgram(OpenCLDeviceBase *device, - string program_name, - string kernel_name, - string kernel_build_options, + const string& program_name, + const string& kernel_name, + const string& kernel_build_options, bool use_stdout = true); ~OpenCLProgram(); void add_kernel(ustring name); void load(); - bool is_loaded() { return loaded; } - string get_log() { return log; } + bool is_loaded() const { return loaded; } + const string& get_log() const { return log; } void report_error(); cl_kernel operator()(); @@ -266,8 +271,8 @@ public: bool load_binary(const string& clbin, const string *debug_src = NULL); bool save_binary(const string& clbin); - void add_log(string msg, bool is_debug); - void add_error(string msg); + void add_log(const string& msg, bool is_debug); + void add_error(const string& msg); bool loaded; cl_program program; @@ -390,8 +395,6 @@ protected: bool denoising_construct_transform(DenoisingTask *task); bool denoising_reconstruct(device_ptr color_ptr, device_ptr color_variance_ptr, - device_ptr guide_ptr, - device_ptr guide_variance_ptr, device_ptr output_ptr, DenoisingTask *task); bool denoising_combine_halves(device_ptr a_ptr, diff --git a/intern/cycles/device/opencl/opencl_base.cpp b/intern/cycles/device/opencl/opencl_base.cpp index 24b70e3446c..509da7a0a84 100644 --- a/intern/cycles/device/opencl/opencl_base.cpp +++ b/intern/cycles/device/opencl/opencl_base.cpp @@ -20,6 +20,7 @@ #include "kernel/kernel_types.h" +#include "util/util_algorithm.h" #include "util/util_foreach.h" #include "util/util_logging.h" #include "util/util_md5.h" @@ -276,6 +277,25 @@ void OpenCLDeviceBase::mem_alloc(const char *name, device_memory& mem, MemoryTyp size_t size = mem.memory_size(); + /* check there is enough memory available for the allocation */ + cl_ulong max_alloc_size = 0; + clGetDeviceInfo(cdDevice, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(cl_ulong), &max_alloc_size, NULL); + + if(DebugFlags().opencl.mem_limit) { + max_alloc_size = min(max_alloc_size, + cl_ulong(DebugFlags().opencl.mem_limit - stats.mem_used)); + } + + if(size > max_alloc_size) { + string error = "Scene too complex to fit in available memory."; + if(name != NULL) { + error += string_printf(" (allocating buffer %s failed.)", name); + } + set_error(error); + + return; + } + cl_mem_flags mem_flag; void *mem_ptr = NULL; @@ -693,8 +713,6 @@ bool OpenCLDeviceBase::denoising_construct_transform(DenoisingTask *task) bool OpenCLDeviceBase::denoising_reconstruct(device_ptr color_ptr, device_ptr color_variance_ptr, - device_ptr guide_ptr, - device_ptr guide_variance_ptr, device_ptr output_ptr, DenoisingTask *task) { @@ -703,8 +721,6 @@ bool OpenCLDeviceBase::denoising_reconstruct(device_ptr color_ptr, cl_mem color_mem = CL_MEM_PTR(color_ptr); cl_mem color_variance_mem = CL_MEM_PTR(color_variance_ptr); - cl_mem guide_mem = CL_MEM_PTR(guide_ptr); - cl_mem guide_variance_mem = CL_MEM_PTR(guide_variance_ptr); cl_mem output_mem = CL_MEM_PTR(output_ptr); cl_mem buffer_mem = CL_MEM_PTR(task->buffer.mem.device_pointer); @@ -735,8 +751,8 @@ bool OpenCLDeviceBase::denoising_reconstruct(device_ptr color_ptr, kernel_set_args(ckNLMCalcDifference, 0, dx, dy, - guide_mem, - guide_variance_mem, + color_mem, + color_variance_mem, difference, local_rect, task->buffer.w, @@ -775,8 +791,6 @@ bool OpenCLDeviceBase::denoising_reconstruct(device_ptr color_ptr, dx, dy, blurDifference, buffer_mem, - color_mem, - color_variance_mem, transform_mem, rank_mem, XtWX_mem, @@ -961,7 +975,7 @@ void OpenCLDeviceBase::denoise(RenderTile &rtile, const DeviceTask &task) denoising.functions.set_tiles = function_bind(&OpenCLDeviceBase::denoising_set_tiles, this, _1, &denoising); denoising.functions.construct_transform = function_bind(&OpenCLDeviceBase::denoising_construct_transform, this, &denoising); - denoising.functions.reconstruct = function_bind(&OpenCLDeviceBase::denoising_reconstruct, this, _1, _2, _3, _4, _5, &denoising); + denoising.functions.reconstruct = function_bind(&OpenCLDeviceBase::denoising_reconstruct, this, _1, _2, _3, &denoising); denoising.functions.divide_shadow = function_bind(&OpenCLDeviceBase::denoising_divide_shadow, this, _1, _2, _3, _4, _5, &denoising); denoising.functions.non_local_means = function_bind(&OpenCLDeviceBase::denoising_non_local_means, this, _1, _2, _3, _4, &denoising); denoising.functions.combine_halves = function_bind(&OpenCLDeviceBase::denoising_combine_halves, this, _1, _2, _3, _4, _5, _6, &denoising); @@ -1232,7 +1246,7 @@ void OpenCLDeviceBase::store_cached_kernel( } string OpenCLDeviceBase::build_options_for_base_program( - const DeviceRequestedFeatures& /*requested_features*/) + const DeviceRequestedFeatures& requested_features) { /* TODO(sergey): By default we compile all features, meaning * mega kernel is not getting feature-based optimizations. @@ -1240,6 +1254,14 @@ string OpenCLDeviceBase::build_options_for_base_program( * Ideally we need always compile kernel with as less features * enabled as possible to keep performance at it's max. */ + + /* For now disable baking when not in use as this has major + * impact on kernel build times. + */ + if(!requested_features.use_baking) { + return "-D__NO_BAKING__"; + } + return ""; } diff --git a/intern/cycles/device/opencl/opencl_split.cpp b/intern/cycles/device/opencl/opencl_split.cpp index 76dcbd6fc9a..76d9983e9a2 100644 --- a/intern/cycles/device/opencl/opencl_split.cpp +++ b/intern/cycles/device/opencl/opencl_split.cpp @@ -25,6 +25,7 @@ #include "device/device_split_kernel.h" +#include "util/util_algorithm.h" #include "util/util_logging.h" #include "util/util_md5.h" #include "util/util_path.h" @@ -176,17 +177,62 @@ protected: friend class OpenCLSplitKernelFunction; }; +struct CachedSplitMemory { + int id; + device_memory *split_data; + device_memory *ray_state; + device_ptr *rng_state; + device_memory *queue_index; + device_memory *use_queues_flag; + device_memory *work_pools; + device_ptr *buffer; +}; + class OpenCLSplitKernelFunction : public SplitKernelFunction { public: OpenCLDeviceSplitKernel* device; OpenCLDeviceBase::OpenCLProgram program; + CachedSplitMemory& cached_memory; + int cached_id; + + OpenCLSplitKernelFunction(OpenCLDeviceSplitKernel* device, CachedSplitMemory& cached_memory) : + device(device), cached_memory(cached_memory), cached_id(cached_memory.id-1) + { + } - OpenCLSplitKernelFunction(OpenCLDeviceSplitKernel* device) : device(device) {} - ~OpenCLSplitKernelFunction() { program.release(); } + ~OpenCLSplitKernelFunction() + { + program.release(); + } virtual bool enqueue(const KernelDimensions& dim, device_memory& kg, device_memory& data) { - device->kernel_set_args(program(), 0, kg, data); + if(cached_id != cached_memory.id) { + cl_uint start_arg_index = + device->kernel_set_args(program(), + 0, + kg, + data, + *cached_memory.split_data, + *cached_memory.ray_state, + *cached_memory.rng_state); + +/* TODO(sergey): Avoid map lookup here. */ +#define KERNEL_TEX(type, ttype, name) \ + device->set_kernel_arg_mem(program(), &start_arg_index, #name); +#include "kernel/kernel_textures.h" +#undef KERNEL_TEX + + start_arg_index += + device->kernel_set_args(program(), + start_arg_index, + *cached_memory.queue_index, + *cached_memory.use_queues_flag, + *cached_memory.work_pools, + *cached_memory.buffer); + + cached_id = cached_memory.id; + } device->ciErr = clEnqueueNDRangeKernel(device->cqCommandQueue, program(), @@ -213,14 +259,15 @@ public: class OpenCLSplitKernel : public DeviceSplitKernel { OpenCLDeviceSplitKernel *device; + CachedSplitMemory cached_memory; public: explicit OpenCLSplitKernel(OpenCLDeviceSplitKernel *device) : DeviceSplitKernel(device), device(device) { } - virtual SplitKernelFunction* get_split_kernel_function(string kernel_name, + virtual SplitKernelFunction* get_split_kernel_function(const string& kernel_name, const DeviceRequestedFeatures& requested_features) { - OpenCLSplitKernelFunction* kernel = new OpenCLSplitKernelFunction(device); + OpenCLSplitKernelFunction* kernel = new OpenCLSplitKernelFunction(device, cached_memory); bool single_program = OpenCLInfo::use_single_program(); kernel->program = @@ -349,6 +396,15 @@ public: return false; } + cached_memory.split_data = &split_data; + cached_memory.ray_state = &ray_state; + cached_memory.rng_state = &rtile.rng_state; + cached_memory.queue_index = &queue_index; + cached_memory.use_queues_flag = &use_queues_flag; + cached_memory.work_pools = &work_pool_wgs; + cached_memory.buffer = &rtile.buffer; + cached_memory.id++; + return true; } @@ -368,12 +424,18 @@ public: cl_ulong max_buffer_size; clGetDeviceInfo(device->cdDevice, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(cl_ulong), &max_buffer_size, NULL); + + if(DebugFlags().opencl.mem_limit) { + max_buffer_size = min(max_buffer_size, + cl_ulong(DebugFlags().opencl.mem_limit - device->stats.mem_used)); + } + VLOG(1) << "Maximum device allocation size: " << string_human_readable_number(max_buffer_size) << " bytes. (" << string_human_readable_size(max_buffer_size) << ")."; size_t num_elements = max_elements_for_max_buffer_size(kg, data, max_buffer_size / 2); - int2 global_size = make_int2(round_down((int)sqrt(num_elements), 64), (int)sqrt(num_elements)); + int2 global_size = make_int2(max(round_down((int)sqrt(num_elements), 64), 64), (int)sqrt(num_elements)); VLOG(1) << "Global size: " << global_size << "."; return global_size; } diff --git a/intern/cycles/device/opencl/opencl_util.cpp b/intern/cycles/device/opencl/opencl_util.cpp index 642c1bfa11c..0d34af3e040 100644 --- a/intern/cycles/device/opencl/opencl_util.cpp +++ b/intern/cycles/device/opencl/opencl_util.cpp @@ -241,9 +241,9 @@ string OpenCLCache::get_kernel_md5() } OpenCLDeviceBase::OpenCLProgram::OpenCLProgram(OpenCLDeviceBase *device, - string program_name, - string kernel_file, - string kernel_build_options, + const string& program_name, + const string& kernel_file, + const string& kernel_build_options, bool use_stdout) : device(device), program_name(program_name), @@ -274,7 +274,7 @@ void OpenCLDeviceBase::OpenCLProgram::release() } } -void OpenCLDeviceBase::OpenCLProgram::add_log(string msg, bool debug) +void OpenCLDeviceBase::OpenCLProgram::add_log(const string& msg, bool debug) { if(!use_stdout) { log += msg + "\n"; @@ -288,7 +288,7 @@ void OpenCLDeviceBase::OpenCLProgram::add_log(string msg, bool debug) } } -void OpenCLDeviceBase::OpenCLProgram::add_error(string msg) +void OpenCLDeviceBase::OpenCLProgram::add_error(const string& msg) { if(use_stdout) { fprintf(stderr, "%s\n", msg.c_str()); @@ -608,6 +608,14 @@ bool OpenCLInfo::device_supported(const string& platform_name, if(!get_device_name(device_id, &device_name)) { return false; } + + int driver_major = 0; + int driver_minor = 0; + if(!get_driver_version(device_id, &driver_major, &driver_minor)) { + return false; + } + VLOG(3) << "OpenCL driver version " << driver_major << "." << driver_minor; + /* It is possible tyo have Iris GPU on AMD/Apple OpenCL framework * (aka, it will not be on Intel framework). This isn't supported * and needs an explicit blacklist. @@ -618,6 +626,21 @@ bool OpenCLInfo::device_supported(const string& platform_name, if(platform_name == "AMD Accelerated Parallel Processing" && device_type == CL_DEVICE_TYPE_GPU) { + if(driver_major < 2236) { + VLOG(1) << "AMD driver version " << driver_major << "." << driver_minor << " not supported."; + return false; + } + const char *blacklist[] = { + /* GCN 1 */ + "Tahiti", "Pitcairn", "Capeverde", "Oland", + NULL + }; + for (int i = 0; blacklist[i] != NULL; i++) { + if(device_name == blacklist[i]) { + VLOG(1) << "AMD device " << device_name << " not supported"; + return false; + } + } return true; } if(platform_name == "Apple" && device_type == CL_DEVICE_TYPE_GPU) { @@ -684,7 +707,7 @@ bool OpenCLInfo::device_version_check(cl_device_id device, return true; } -string OpenCLInfo::get_hardware_id(string platform_name, cl_device_id device_id) +string OpenCLInfo::get_hardware_id(const string& platform_name, cl_device_id device_id) { if(platform_name == "AMD Accelerated Parallel Processing" || platform_name == "Apple") { /* Use cl_amd_device_topology extension. */ @@ -1063,7 +1086,7 @@ string OpenCLInfo::get_readable_device_name(cl_device_id device_id) CL_DEVICE_BOARD_NAME_AMD, sizeof(board_name), &board_name, - &length) == CL_SUCCESS) + &length) == CL_SUCCESS) { if(length != 0 && board_name[0] != '\0') { return board_name; @@ -1073,6 +1096,34 @@ string OpenCLInfo::get_readable_device_name(cl_device_id device_id) return get_device_name(device_id); } +bool OpenCLInfo::get_driver_version(cl_device_id device_id, + int *major, + int *minor, + cl_int* error) +{ + char buffer[1024]; + cl_int err; + if((err = clGetDeviceInfo(device_id, + CL_DRIVER_VERSION, + sizeof(buffer), + &buffer, + NULL)) != CL_SUCCESS) + { + if(error != NULL) { + *error = err; + } + return false; + } + if(error != NULL) { + *error = CL_SUCCESS; + } + if(sscanf(buffer, "%d.%d", major, minor) < 2) { + VLOG(1) << string_printf("OpenCL: failed to parse driver version string (%s).", buffer); + return false; + } + return true; +} + int OpenCLInfo::mem_address_alignment(cl_device_id device_id) { int base_align_bits; diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index bef869f34b4..23e9bd311c4 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -45,6 +45,7 @@ set(SRC kernels/opencl/kernel_direct_lighting.cl kernels/opencl/kernel_shadow_blocked_ao.cl kernels/opencl/kernel_shadow_blocked_dl.cl + kernels/opencl/kernel_enqueue_inactive.cl kernels/opencl/kernel_next_iteration_setup.cl kernels/opencl/kernel_indirect_subsurface.cl kernels/opencl/kernel_buffer_update.cl @@ -121,6 +122,10 @@ set(SRC_KERNELS_CUDA_HEADERS kernels/cuda/kernel_config.h ) +set(SRC_KERNELS_OPENCL_HEADERS + kernels/opencl/kernel_split_function.h +) + set(SRC_CLOSURE_HEADERS closure/alloc.h closure/bsdf.h @@ -278,6 +283,7 @@ set(SRC_SPLIT_HEADERS split/kernel_data_init.h split/kernel_direct_lighting.h split/kernel_do_volume.h + split/kernel_enqueue_inactive.h split/kernel_holdout_emission_blurring_pathtermination_ao.h split/kernel_indirect_background.h split/kernel_indirect_subsurface.h @@ -450,6 +456,7 @@ add_library(cycles_kernel ${SRC_HEADERS} ${SRC_KERNELS_CPU_HEADERS} ${SRC_KERNELS_CUDA_HEADERS} + ${SRC_KERNELS_OPENCL_HEADERS} ${SRC_BVH_HEADERS} ${SRC_CLOSURE_HEADERS} ${SRC_FILTER_HEADERS} @@ -490,9 +497,11 @@ delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "kernels/opencl/kernel_subsurface_sc delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "kernels/opencl/kernel_direct_lighting.cl" ${CYCLES_INSTALL_PATH}/source/kernel/kernels/opencl) delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "kernels/opencl/kernel_shadow_blocked_ao.cl" ${CYCLES_INSTALL_PATH}/source/kernel/kernels/opencl) delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "kernels/opencl/kernel_shadow_blocked_dl.cl" ${CYCLES_INSTALL_PATH}/source/kernel/kernels/opencl) +delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "kernels/opencl/kernel_enqueue_inactive.cl" ${CYCLES_INSTALL_PATH}/source/kernel/kernels/opencl) delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "kernels/opencl/kernel_next_iteration_setup.cl" ${CYCLES_INSTALL_PATH}/source/kernel/kernels/opencl) delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "kernels/opencl/kernel_indirect_subsurface.cl" ${CYCLES_INSTALL_PATH}/source/kernel/kernels/opencl) delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "kernels/opencl/kernel_buffer_update.cl" ${CYCLES_INSTALL_PATH}/source/kernel/kernels/opencl) +delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "kernels/opencl/kernel_split_function.h" ${CYCLES_INSTALL_PATH}/source/kernel/kernels/opencl) delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "kernels/opencl/filter.cl" ${CYCLES_INSTALL_PATH}/source/kernel/kernels/opencl) delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "kernels/cuda/kernel.cu" ${CYCLES_INSTALL_PATH}/source/kernel/kernels/cuda) delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "kernels/cuda/kernel_split.cu" ${CYCLES_INSTALL_PATH}/source/kernel/kernels/cuda) diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h index a04c157dc40..86a00d2124d 100644 --- a/intern/cycles/kernel/closure/bsdf.h +++ b/intern/cycles/kernel/closure/bsdf.h @@ -423,6 +423,11 @@ ccl_device bool bsdf_merge(ShaderClosure *a, ShaderClosure *b) case CLOSURE_BSDF_HAIR_REFLECTION_ID: case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: return bsdf_hair_merge(a, b); +#ifdef __PRINCIPLED__ + case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID: + case CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID: + return bsdf_principled_diffuse_merge(a, b); +#endif #ifdef __VOLUME__ case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID: return volume_henyey_greenstein_merge(a, b); diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index 30cc8b90330..b12e248f0a3 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -288,12 +288,16 @@ ccl_device int bsdf_microfacet_ggx_setup(MicrofacetBsdf *bsdf) return SD_BSDF|SD_BSDF_HAS_EVAL; } -ccl_device int bsdf_microfacet_ggx_fresnel_setup(MicrofacetBsdf *bsdf) +ccl_device int bsdf_microfacet_ggx_fresnel_setup(MicrofacetBsdf *bsdf, const ShaderData *sd) { bsdf->extra->cspec0.x = saturate(bsdf->extra->cspec0.x); bsdf->extra->cspec0.y = saturate(bsdf->extra->cspec0.y); bsdf->extra->cspec0.z = saturate(bsdf->extra->cspec0.z); + float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior); + float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0)); + bsdf->sample_weight *= F; + bsdf->alpha_x = saturate(bsdf->alpha_x); bsdf->alpha_y = bsdf->alpha_x; @@ -302,12 +306,16 @@ ccl_device int bsdf_microfacet_ggx_fresnel_setup(MicrofacetBsdf *bsdf) return SD_BSDF|SD_BSDF_HAS_EVAL; } -ccl_device int bsdf_microfacet_ggx_clearcoat_setup(MicrofacetBsdf *bsdf) +ccl_device int bsdf_microfacet_ggx_clearcoat_setup(MicrofacetBsdf *bsdf, const ShaderData *sd) { bsdf->extra->cspec0.x = saturate(bsdf->extra->cspec0.x); bsdf->extra->cspec0.y = saturate(bsdf->extra->cspec0.y); bsdf->extra->cspec0.z = saturate(bsdf->extra->cspec0.z); + float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior); + float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0)); + bsdf->sample_weight *= 0.25f * bsdf->extra->clearcoat * F; + bsdf->alpha_x = saturate(bsdf->alpha_x); bsdf->alpha_y = bsdf->alpha_x; @@ -343,12 +351,16 @@ ccl_device int bsdf_microfacet_ggx_aniso_setup(MicrofacetBsdf *bsdf) return SD_BSDF|SD_BSDF_HAS_EVAL; } -ccl_device int bsdf_microfacet_ggx_aniso_fresnel_setup(MicrofacetBsdf *bsdf) +ccl_device int bsdf_microfacet_ggx_aniso_fresnel_setup(MicrofacetBsdf *bsdf, const ShaderData *sd) { bsdf->extra->cspec0.x = saturate(bsdf->extra->cspec0.x); bsdf->extra->cspec0.y = saturate(bsdf->extra->cspec0.y); bsdf->extra->cspec0.z = saturate(bsdf->extra->cspec0.z); + float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior); + float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0)); + bsdf->sample_weight *= F; + bsdf->alpha_x = saturate(bsdf->alpha_x); bsdf->alpha_y = saturate(bsdf->alpha_y); diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h index b07b515c405..22d0092093a 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h @@ -245,35 +245,69 @@ ccl_device_forceinline float mf_ggx_albedo(float r) return saturate(albedo); } +ccl_device_inline float mf_ggx_transmission_albedo(float a, float ior) +{ + if(ior < 1.0f) { + ior = 1.0f/ior; + } + a = saturate(a); + ior = clamp(ior, 1.0f, 3.0f); + float I_1 = 0.0476898f*expf(-0.978352f*(ior-0.65657f)*(ior-0.65657f)) - 0.033756f*ior + 0.993261f; + float R_1 = (((0.116991f*a - 0.270369f)*a + 0.0501366f)*a - 0.00411511f)*a + 1.00008f; + float I_2 = (((-2.08704f*ior + 26.3298f)*ior - 127.906f)*ior + 292.958f)*ior - 287.946f + 199.803f/(ior*ior) - 101.668f/(ior*ior*ior); + float R_2 = ((((5.3725f*a -24.9307f)*a + 22.7437f)*a - 3.40751f)*a + 0.0986325f)*a + 0.00493504f; + + return saturate(1.0f + I_2*R_2*0.0019127f - (1.0f - I_1)*(1.0f - R_1)*9.3205f); +} + ccl_device_forceinline float mf_ggx_pdf(const float3 wi, const float3 wo, const float alpha) { float D = D_ggx(normalize(wi+wo), alpha); float lambda = mf_lambda(wi, make_float2(alpha, alpha)); + float singlescatter = 0.25f * D / max((1.0f + lambda) * wi.z, 1e-7f); + + float multiscatter = wo.z * M_1_PI_F; + float albedo = mf_ggx_albedo(alpha); - return 0.25f * D / max((1.0f + lambda) * wi.z, 1e-7f) + (1.0f - albedo) * wo.z; + return albedo*singlescatter + (1.0f - albedo)*multiscatter; } ccl_device_forceinline float mf_ggx_aniso_pdf(const float3 wi, const float3 wo, const float2 alpha) { - return 0.25f * D_ggx_aniso(normalize(wi+wo), alpha) / ((1.0f + mf_lambda(wi, alpha)) * wi.z) + (1.0f - mf_ggx_albedo(sqrtf(alpha.x*alpha.y))) * wo.z; + float D = D_ggx_aniso(normalize(wi+wo), alpha); + float lambda = mf_lambda(wi, alpha); + float singlescatter = 0.25f * D / max((1.0f + lambda) * wi.z, 1e-7f); + + float multiscatter = wo.z * M_1_PI_F; + + float albedo = mf_ggx_albedo(sqrtf(alpha.x*alpha.y)); + return albedo*singlescatter + (1.0f - albedo)*multiscatter; } ccl_device_forceinline float mf_glass_pdf(const float3 wi, const float3 wo, const float alpha, const float eta) { - float3 wh; - float fresnel; - if(wi.z*wo.z > 0.0f) { - wh = normalize(wi + wo); - fresnel = fresnel_dielectric_cos(dot(wi, wh), eta); - } - else { - wh = normalize(wi + wo*eta); - fresnel = 1.0f - fresnel_dielectric_cos(dot(wi, wh), eta); - } + bool reflective = (wi.z*wo.z > 0.0f); + + float wh_len; + float3 wh = normalize_len(wi + (reflective? wo : (wo*eta)), &wh_len); if(wh.z < 0.0f) wh = -wh; float3 r_wi = (wi.z < 0.0f)? -wi: wi; - return fresnel * max(0.0f, dot(r_wi, wh)) * D_ggx(wh, alpha) / ((1.0f + mf_lambda(r_wi, make_float2(alpha, alpha))) * r_wi.z) + fabsf(wo.z); + float lambda = mf_lambda(r_wi, make_float2(alpha, alpha)); + float D = D_ggx(wh, alpha); + float fresnel = fresnel_dielectric_cos(dot(r_wi, wh), eta); + + float multiscatter = fabsf(wo.z * M_1_PI_F); + if(reflective) { + float singlescatter = 0.25f * D / max((1.0f + lambda) * r_wi.z, 1e-7f); + float albedo = mf_ggx_albedo(alpha); + return fresnel * (albedo*singlescatter + (1.0f - albedo)*multiscatter); + } + else { + float singlescatter = fabsf(dot(r_wi, wh)*dot(wo, wh) * D * eta*eta / max((1.0f + lambda) * r_wi.z * wh_len*wh_len, 1e-7f)); + float albedo = mf_ggx_transmission_albedo(alpha, eta); + return (1.0f - fresnel) * (albedo*singlescatter + (1.0f - albedo)*multiscatter); + } } /* === Actual random walk implementations, one version of mf_eval and mf_sample per phase function. === */ @@ -326,13 +360,17 @@ ccl_device int bsdf_microfacet_multi_ggx_aniso_setup(MicrofacetBsdf *bsdf) return bsdf_microfacet_multi_ggx_common_setup(bsdf); } -ccl_device int bsdf_microfacet_multi_ggx_aniso_fresnel_setup(MicrofacetBsdf *bsdf) +ccl_device int bsdf_microfacet_multi_ggx_aniso_fresnel_setup(MicrofacetBsdf *bsdf, const ShaderData *sd) { if(is_zero(bsdf->T)) bsdf->T = make_float3(1.0f, 0.0f, 0.0f); bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID; + float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior); + float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0)); + bsdf->sample_weight *= F; + return bsdf_microfacet_multi_ggx_common_setup(bsdf); } @@ -345,12 +383,16 @@ ccl_device int bsdf_microfacet_multi_ggx_setup(MicrofacetBsdf *bsdf) return bsdf_microfacet_multi_ggx_common_setup(bsdf); } -ccl_device int bsdf_microfacet_multi_ggx_fresnel_setup(MicrofacetBsdf *bsdf) +ccl_device int bsdf_microfacet_multi_ggx_fresnel_setup(MicrofacetBsdf *bsdf, const ShaderData *sd) { bsdf->alpha_y = bsdf->alpha_x; bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID; + float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior); + float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0)); + bsdf->sample_weight *= F; + return bsdf_microfacet_multi_ggx_common_setup(bsdf); } @@ -455,7 +497,7 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_setup(MicrofacetBsdf *bsdf) return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_NEEDS_LCG; } -ccl_device int bsdf_microfacet_multi_ggx_glass_fresnel_setup(MicrofacetBsdf *bsdf) +ccl_device int bsdf_microfacet_multi_ggx_glass_fresnel_setup(MicrofacetBsdf *bsdf, const ShaderData *sd) { bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f); bsdf->alpha_y = bsdf->alpha_x; @@ -469,6 +511,10 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_fresnel_setup(MicrofacetBsdf *bsd bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID; + float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior); + float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0)); + bsdf->sample_weight *= F; + return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_NEEDS_LCG; } diff --git a/intern/cycles/kernel/closure/bsdf_principled_diffuse.h b/intern/cycles/kernel/closure/bsdf_principled_diffuse.h index 215c32e1ffb..f8ca64293b0 100644 --- a/intern/cycles/kernel/closure/bsdf_principled_diffuse.h +++ b/intern/cycles/kernel/closure/bsdf_principled_diffuse.h @@ -58,6 +58,14 @@ ccl_device int bsdf_principled_diffuse_setup(PrincipledDiffuseBsdf *bsdf) return SD_BSDF|SD_BSDF_HAS_EVAL; } +ccl_device bool bsdf_principled_diffuse_merge(const ShaderClosure *a, const ShaderClosure *b) +{ + const PrincipledDiffuseBsdf *bsdf_a = (const PrincipledDiffuseBsdf*)a; + const PrincipledDiffuseBsdf *bsdf_b = (const PrincipledDiffuseBsdf*)b; + + return (isequal_float3(bsdf_a->N, bsdf_b->N) && bsdf_a->roughness == bsdf_b->roughness); +} + ccl_device float3 bsdf_principled_diffuse_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { diff --git a/intern/cycles/kernel/filter/filter_features.h b/intern/cycles/kernel/filter/filter_features.h index 53d703de143..6226ed2c2ef 100644 --- a/intern/cycles/kernel/filter/filter_features.h +++ b/intern/cycles/kernel/filter/filter_features.h @@ -78,16 +78,10 @@ ccl_device_inline void filter_calculate_scale(float *scale) scale[3] = scale[4] = scale[5] = 1.0f/max(sqrtf(scale[3]), 0.01f); } -ccl_device_inline float3 filter_get_pixel_color(const ccl_global float *ccl_restrict buffer, - int pass_stride) +ccl_device_inline float3 filter_get_color(const ccl_global float *ccl_restrict buffer, + int pass_stride) { - return make_float3(ccl_get_feature(buffer, 0), ccl_get_feature(buffer, 1), ccl_get_feature(buffer, 2)); -} - -ccl_device_inline float filter_get_pixel_variance(const ccl_global float *ccl_restrict buffer, - int pass_stride) -{ - return average(make_float3(ccl_get_feature(buffer, 0), ccl_get_feature(buffer, 1), ccl_get_feature(buffer, 2))); + return make_float3(ccl_get_feature(buffer, 8), ccl_get_feature(buffer, 9), ccl_get_feature(buffer, 10)); } ccl_device_inline void design_row_add(float *design_row, diff --git a/intern/cycles/kernel/filter/filter_nlm_cpu.h b/intern/cycles/kernel/filter/filter_nlm_cpu.h index 5cb4038bc33..3e752bce68f 100644 --- a/intern/cycles/kernel/filter/filter_nlm_cpu.h +++ b/intern/cycles/kernel/filter/filter_nlm_cpu.h @@ -101,7 +101,7 @@ ccl_device_inline void kernel_filter_nlm_calc_weight(const float *ccl_restrict d for(int x = rect.x; x < rect.z; x++) { const int low = max(rect.x, x-f); const int high = min(rect.z, x+f+1); - out_image[y*w+x] = expf(-max(out_image[y*w+x] * (1.0f/(high - low)), 0.0f)); + out_image[y*w+x] = fast_expf(-max(out_image[y*w+x] * (1.0f/(high - low)), 0.0f)); } } } @@ -133,8 +133,6 @@ ccl_device_inline void kernel_filter_nlm_update_output(int dx, int dy, ccl_device_inline void kernel_filter_nlm_construct_gramian(int dx, int dy, const float *ccl_restrict difference_image, const float *ccl_restrict buffer, - float *color_pass, - float *variance_pass, float *transform, int *rank, float *XtWX, @@ -167,7 +165,6 @@ ccl_device_inline void kernel_filter_nlm_construct_gramian(int dx, int dy, dx, dy, w, h, pass_stride, buffer, - color_pass, variance_pass, l_transform, l_rank, weight, l_XtWX, l_XtWY, 0); } diff --git a/intern/cycles/kernel/filter/filter_nlm_gpu.h b/intern/cycles/kernel/filter/filter_nlm_gpu.h index 078c5f56763..2c5ac807051 100644 --- a/intern/cycles/kernel/filter/filter_nlm_gpu.h +++ b/intern/cycles/kernel/filter/filter_nlm_gpu.h @@ -66,7 +66,7 @@ ccl_device_inline void kernel_filter_nlm_calc_weight(int x, int y, sum += difference_image[y*w+x1]; } sum *= 1.0f/(high-low); - out_image[y*w+x] = expf(-max(sum, 0.0f)); + out_image[y*w+x] = fast_expf(-max(sum, 0.0f)); } ccl_device_inline void kernel_filter_nlm_update_output(int x, int y, @@ -97,8 +97,6 @@ ccl_device_inline void kernel_filter_nlm_construct_gramian(int fx, int fy, int dx, int dy, const ccl_global float *ccl_restrict difference_image, const ccl_global float *ccl_restrict buffer, - ccl_global float *color_pass, - ccl_global float *variance_pass, const ccl_global float *ccl_restrict transform, ccl_global int *rank, ccl_global float *XtWX, @@ -130,7 +128,6 @@ ccl_device_inline void kernel_filter_nlm_construct_gramian(int fx, int fy, dx, dy, w, h, pass_stride, buffer, - color_pass, variance_pass, transform, rank, weight, XtWX, XtWY, localIdx); diff --git a/intern/cycles/kernel/filter/filter_prefilter.h b/intern/cycles/kernel/filter/filter_prefilter.h index 82cc36625ec..d5ae1b73927 100644 --- a/intern/cycles/kernel/filter/filter_prefilter.h +++ b/intern/cycles/kernel/filter/filter_prefilter.h @@ -142,13 +142,22 @@ ccl_device void kernel_filter_detect_outliers(int x, int y, float ref = 2.0f*values[(int)(n*0.75f)]; float fac = 1.0f; if(L > ref) { - /* If the pixel is an outlier, negate the depth value to mark it as one. - * Also, scale its brightness down to the outlier threshold to avoid trouble with the NLM weights. */ - depth[idx] = -depth[idx]; - fac = ref/L; - variance[idx ] *= fac*fac; - variance[idx + pass_stride] *= fac*fac; - variance[idx+2*pass_stride] *= fac*fac; + /* The pixel appears to be an outlier. + * However, it may just be a legitimate highlight. Therefore, it is checked how likely it is that the pixel + * should actually be at the reference value: + * If the reference is within the 3-sigma interval, the pixel is assumed to be a statistical outlier. + * Otherwise, it is very unlikely that the pixel should be darker, which indicates a legitimate highlight. + */ + float stddev = sqrtf(average(make_float3(variance[idx], variance[idx+pass_stride], variance[idx+2*pass_stride]))); + if(L - 3*stddev < ref) { + /* The pixel is an outlier, so negate the depth value to mark it as one. + * Also, scale its brightness down to the outlier threshold to avoid trouble with the NLM weights. */ + depth[idx] = -depth[idx]; + fac = ref/L; + variance[idx ] *= fac*fac; + variance[idx + pass_stride] *= fac*fac; + variance[idx+2*pass_stride] *= fac*fac; + } } out[idx ] = fac*image[idx]; out[idx + pass_stride] = fac*image[idx + pass_stride]; diff --git a/intern/cycles/kernel/filter/filter_reconstruction.h b/intern/cycles/kernel/filter/filter_reconstruction.h index 4a4c81b7ba3..25a3025056c 100644 --- a/intern/cycles/kernel/filter/filter_reconstruction.h +++ b/intern/cycles/kernel/filter/filter_reconstruction.h @@ -22,8 +22,6 @@ ccl_device_inline void kernel_filter_construct_gramian(int x, int y, int w, int h, int pass_stride, const ccl_global float *ccl_restrict buffer, - ccl_global float *color_pass, - ccl_global float *variance_pass, const ccl_global float *ccl_restrict transform, ccl_global int *rank, float weight, @@ -31,38 +29,31 @@ ccl_device_inline void kernel_filter_construct_gramian(int x, int y, ccl_global float3 *XtWY, int localIdx) { + if(weight < 1e-3f) { + return; + } + int p_offset = y *w + x; int q_offset = (y+dy)*w + (x+dx); -#ifdef __KERNEL_CPU__ - const int stride = 1; - (void)storage_stride; - (void)localIdx; - float design_row[DENOISE_FEATURES+1]; -#elif defined(__KERNEL_CUDA__) +#ifdef __KERNEL_GPU__ const int stride = storage_stride; +#else + const int stride = 1; + (void) storage_stride; +#endif + +#ifdef __KERNEL_CUDA__ ccl_local float shared_design_row[(DENOISE_FEATURES+1)*CCL_MAX_LOCAL_SIZE]; ccl_local_param float *design_row = shared_design_row + localIdx*(DENOISE_FEATURES+1); #else - const int stride = storage_stride; float design_row[DENOISE_FEATURES+1]; #endif - float3 p_color = filter_get_pixel_color(color_pass + p_offset, pass_stride); - float3 q_color = filter_get_pixel_color(color_pass + q_offset, pass_stride); + float3 q_color = filter_get_color(buffer + q_offset, pass_stride); - float p_std_dev = sqrtf(filter_get_pixel_variance(variance_pass + p_offset, pass_stride)); - float q_std_dev = sqrtf(filter_get_pixel_variance(variance_pass + q_offset, pass_stride)); - - /* If the pixel was flagged as an outlier during prefiltering, skip it. - * Otherwise, perform the regular confidence interval test unless - * the center pixel is an outlier (in that case, using the confidence - * interval test could result in no pixels being used at all). */ - bool p_outlier = (ccl_get_feature(buffer + p_offset, 0) < 0.0f); - bool q_outlier = (ccl_get_feature(buffer + q_offset, 0) < 0.0f); - bool outside_of_interval = (average(fabs(p_color - q_color)) > 2.0f*(p_std_dev + q_std_dev + 1e-3f)); - - if(q_outlier || (!p_outlier && outside_of_interval)) { + /* If the pixel was flagged as an outlier during prefiltering, skip it. */ + if(ccl_get_feature(buffer + q_offset, 0) < 0.0f) { return; } @@ -83,13 +74,19 @@ ccl_device_inline void kernel_filter_finalize(int x, int y, int w, int h, int4 buffer_params, int sample) { -#ifdef __KERNEL_CPU__ - const int stride = 1; - (void)storage_stride; -#else +#ifdef __KERNEL_GPU__ const int stride = storage_stride; +#else + const int stride = 1; + (void) storage_stride; #endif + if(XtWX[0] < 1e-3f) { + /* There is not enough information to determine a denoised result. + * As a fallback, keep the original value of the pixel. */ + return; + } + /* The weighted average of pixel colors (essentially, the NLM-filtered image). * In case the solution of the linear model fails due to numerical issues, * fall back to this value. */ @@ -102,6 +99,9 @@ ccl_device_inline void kernel_filter_finalize(int x, int y, int w, int h, final_color = mean_color; } + /* Clamp pixel value to positive values. */ + final_color = max(final_color, make_float3(0.0f, 0.0f, 0.0f)); + ccl_global float *combined_buffer = buffer + (y*buffer_params.y + x + buffer_params.x)*buffer_params.z; final_color *= sample; if(buffer_params.w) { @@ -114,6 +114,4 @@ ccl_device_inline void kernel_filter_finalize(int x, int y, int w, int h, combined_buffer[2] = final_color.z; } -#undef STORAGE_TYPE - CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/kernel_accumulate.h b/intern/cycles/kernel/kernel_accumulate.h index 06728415c15..175bd6b9737 100644 --- a/intern/cycles/kernel/kernel_accumulate.h +++ b/intern/cycles/kernel/kernel_accumulate.h @@ -621,25 +621,43 @@ ccl_device_inline void path_radiance_accum_sample(PathRadiance *L, PathRadiance { float fac = 1.0f/num_samples; +#ifdef __SPLIT_KERNEL__ +# define safe_float3_add(f, v) \ + do { \ + ccl_global float *p = (ccl_global float*)(&(f)); \ + atomic_add_and_fetch_float(p+0, (v).x); \ + atomic_add_and_fetch_float(p+1, (v).y); \ + atomic_add_and_fetch_float(p+2, (v).z); \ + } while(0) +#else +# define safe_float3_add(f, v) (f) += (v) +#endif /* __SPLIT_KERNEL__ */ + #ifdef __PASSES__ - L->direct_diffuse += L_sample->direct_diffuse*fac; - L->direct_glossy += L_sample->direct_glossy*fac; - L->direct_transmission += L_sample->direct_transmission*fac; - L->direct_subsurface += L_sample->direct_subsurface*fac; - L->direct_scatter += L_sample->direct_scatter*fac; - - L->indirect_diffuse += L_sample->indirect_diffuse*fac; - L->indirect_glossy += L_sample->indirect_glossy*fac; - L->indirect_transmission += L_sample->indirect_transmission*fac; - L->indirect_subsurface += L_sample->indirect_subsurface*fac; - L->indirect_scatter += L_sample->indirect_scatter*fac; - - L->background += L_sample->background*fac; - L->ao += L_sample->ao*fac; - L->shadow += L_sample->shadow*fac; + safe_float3_add(L->direct_diffuse, L_sample->direct_diffuse*fac); + safe_float3_add(L->direct_glossy, L_sample->direct_glossy*fac); + safe_float3_add(L->direct_transmission, L_sample->direct_transmission*fac); + safe_float3_add(L->direct_subsurface, L_sample->direct_subsurface*fac); + safe_float3_add(L->direct_scatter, L_sample->direct_scatter*fac); + + safe_float3_add(L->indirect_diffuse, L_sample->indirect_diffuse*fac); + safe_float3_add(L->indirect_glossy, L_sample->indirect_glossy*fac); + safe_float3_add(L->indirect_transmission, L_sample->indirect_transmission*fac); + safe_float3_add(L->indirect_subsurface, L_sample->indirect_subsurface*fac); + safe_float3_add(L->indirect_scatter, L_sample->indirect_scatter*fac); + + safe_float3_add(L->background, L_sample->background*fac); + safe_float3_add(L->ao, L_sample->ao*fac); + safe_float3_add(L->shadow, L_sample->shadow*fac); +# ifdef __SPLIT_KERNEL__ + atomic_add_and_fetch_float(&L->mist, L_sample->mist*fac); +# else L->mist += L_sample->mist*fac; -#endif - L->emission += L_sample->emission * fac; +# endif /* __SPLIT_KERNEL__ */ +#endif /* __PASSES__ */ + safe_float3_add(L->emission, L_sample->emission*fac); + +#undef safe_float3_add } #ifdef __SHADOW_TRICKS__ diff --git a/intern/cycles/kernel/kernel_passes.h b/intern/cycles/kernel/kernel_passes.h index 9d52834ffcc..9cd7ffb181d 100644 --- a/intern/cycles/kernel/kernel_passes.h +++ b/intern/cycles/kernel/kernel_passes.h @@ -142,7 +142,7 @@ ccl_device_inline void kernel_write_denoising_shadow(KernelGlobals *kg, ccl_glob ccl_device_inline void kernel_update_denoising_features(KernelGlobals *kg, ShaderData *sd, - ccl_global PathState *state, + ccl_addr_space PathState *state, PathRadiance *L) { #ifdef __DENOISING_FEATURES__ diff --git a/intern/cycles/kernel/kernel_path_state.h b/intern/cycles/kernel/kernel_path_state.h index 0fa77d9e8bd..5d92fd12201 100644 --- a/intern/cycles/kernel/kernel_path_state.h +++ b/intern/cycles/kernel/kernel_path_state.h @@ -139,9 +139,11 @@ ccl_device_inline void path_state_next(KernelGlobals *kg, ccl_addr_space PathSta /* random number generator next bounce */ state->rng_offset += PRNG_BOUNCE_NUM; +#ifdef __DENOISING_FEATURES__ if((state->denoising_feature_weight == 0.0f) && !(state->flag & PATH_RAY_SHADOW_CATCHER)) { state->flag &= ~PATH_RAY_STORE_SHADOW_INFO; } +#endif } ccl_device_inline uint path_state_ray_visibility(KernelGlobals *kg, PathState *state) diff --git a/intern/cycles/kernel/kernel_queues.h b/intern/cycles/kernel/kernel_queues.h index 96bc636d5ac..e32d4bbbc1b 100644 --- a/intern/cycles/kernel/kernel_queues.h +++ b/intern/cycles/kernel/kernel_queues.h @@ -128,6 +128,21 @@ ccl_device unsigned int get_global_queue_index( return my_gqidx; } +ccl_device int dequeue_ray_index( + int queue_number, + ccl_global int *queues, + int queue_size, + ccl_global int *queue_index) +{ + int index = atomic_fetch_and_dec_uint32((ccl_global uint*)&queue_index[queue_number])-1; + + if(index < 0) { + return QUEUE_EMPTY_SLOT; + } + + return queues[index + queue_number * queue_size]; +} + CCL_NAMESPACE_END #endif // __KERNEL_QUEUE_H__ diff --git a/intern/cycles/kernel/kernel_subsurface.h b/intern/cycles/kernel/kernel_subsurface.h index 1026cde7b29..6475d4b66fd 100644 --- a/intern/cycles/kernel/kernel_subsurface.h +++ b/intern/cycles/kernel/kernel_subsurface.h @@ -418,7 +418,7 @@ ccl_device_noinline void subsurface_scatter_multi_setup( } /* subsurface scattering step, from a point on the surface to another nearby point on the same object */ -ccl_device void subsurface_scatter_step(KernelGlobals *kg, ShaderData *sd, ccl_global PathState *state, +ccl_device void subsurface_scatter_step(KernelGlobals *kg, ShaderData *sd, ccl_addr_space PathState *state, int state_flag, ShaderClosure *sc, uint *lcg_state, float disk_u, float disk_v, bool all) { float3 eval = make_float3(0.0f, 0.0f, 0.0f); diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index dbeaffdfb24..34affab1b9d 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -135,7 +135,7 @@ CCL_NAMESPACE_BEGIN * this is because megakernel in device_opencl does not support * custom cflags depending on the scene features. */ -# endif /* __KERNEL_OPENCL_NVIDIA__ */ +# endif /* __KERNEL_OPENCL_APPLE__ */ # ifdef __KERNEL_OPENCL_AMD__ # define __CL_USE_NATIVE__ @@ -236,6 +236,9 @@ CCL_NAMESPACE_BEGIN #ifdef __NO_PRINCIPLED__ # undef __PRINCIPLED__ #endif +#ifdef __NO_DENOISING__ +# undef __DENOISING_FEATURES__ +#endif /* Random Numbers */ @@ -1387,6 +1390,8 @@ enum QueueNumber { #ifdef __BRANCHED_PATH__ /* All rays moving to next iteration of the indirect loop for light */ QUEUE_LIGHT_INDIRECT_ITER, + /* Queue of all inactive rays. These are candidates for sharing work of indirect loops */ + QUEUE_INACTIVE_RAYS, # ifdef __VOLUME__ /* All rays moving to next iteration of the indirect loop for volumes */ QUEUE_VOLUME_INDIRECT_ITER, @@ -1429,6 +1434,9 @@ enum RayState { RAY_BRANCHED_VOLUME_INDIRECT = (1 << 5), RAY_BRANCHED_SUBSURFACE_INDIRECT = (1 << 6), RAY_BRANCHED_INDIRECT = (RAY_BRANCHED_LIGHT_INDIRECT | RAY_BRANCHED_VOLUME_INDIRECT | RAY_BRANCHED_SUBSURFACE_INDIRECT), + + /* Ray is evaluating an iteration of an indirect loop for another thread */ + RAY_BRANCHED_INDIRECT_SHARED = (1 << 7), }; #define ASSIGN_RAY_STATE(ray_state, ray_index, state) (ray_state[ray_index] = ((ray_state[ray_index] & RAY_FLAG_MASK) | state)) diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h index 9c0878249d4..1e472aaf51a 100644 --- a/intern/cycles/kernel/kernel_volume.h +++ b/intern/cycles/kernel/kernel_volume.h @@ -660,6 +660,7 @@ typedef struct VolumeSegment { * but the entire segment is needed to do always scattering, rather than probabilistically * hitting or missing the volume. if we don't know the transmittance at the end of the * volume we can't generate stratified distance samples up to that transmittance */ +#ifdef __VOLUME_DECOUPLED__ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg, PathState *state, Ray *ray, ShaderData *sd, VolumeSegment *segment, bool heterogeneous) { @@ -829,6 +830,7 @@ ccl_device void kernel_volume_decoupled_free(KernelGlobals *kg, VolumeSegment *s #endif } } +#endif /* __VOLUME_DECOUPLED__ */ /* scattering for homogeneous and heterogeneous volumes, using decoupled ray * marching. diff --git a/intern/cycles/kernel/kernels/cpu/filter_cpu.h b/intern/cycles/kernel/kernels/cpu/filter_cpu.h index ffd34c293fc..2ed713299fd 100644 --- a/intern/cycles/kernel/kernels/cpu/filter_cpu.h +++ b/intern/cycles/kernel/kernels/cpu/filter_cpu.h @@ -107,8 +107,6 @@ void KERNEL_FUNCTION_FULL_NAME(filter_nlm_construct_gramian)(int dx, int dy, float *difference_image, float *buffer, - float *color_pass, - float *variance_pass, float *transform, int *rank, float *XtWX, diff --git a/intern/cycles/kernel/kernels/cpu/filter_cpu_impl.h b/intern/cycles/kernel/kernels/cpu/filter_cpu_impl.h index 261176846b1..8dc1a8d583c 100644 --- a/intern/cycles/kernel/kernels/cpu/filter_cpu_impl.h +++ b/intern/cycles/kernel/kernels/cpu/filter_cpu_impl.h @@ -213,8 +213,6 @@ void KERNEL_FUNCTION_FULL_NAME(filter_nlm_construct_gramian)(int dx, int dy, float *difference_image, float *buffer, - float *color_pass, - float *variance_pass, float *transform, int *rank, float *XtWX, @@ -229,7 +227,7 @@ void KERNEL_FUNCTION_FULL_NAME(filter_nlm_construct_gramian)(int dx, #ifdef KERNEL_STUB STUB_ASSERT(KERNEL_ARCH, filter_nlm_construct_gramian); #else - kernel_filter_nlm_construct_gramian(dx, dy, difference_image, buffer, color_pass, variance_pass, transform, rank, XtWX, XtWY, load_int4(rect), load_int4(filter_rect), w, h, f, pass_stride); + kernel_filter_nlm_construct_gramian(dx, dy, difference_image, buffer, transform, rank, XtWX, XtWY, load_int4(rect), load_int4(filter_rect), w, h, f, pass_stride); #endif } diff --git a/intern/cycles/kernel/kernels/cpu/kernel_cpu.h b/intern/cycles/kernel/kernels/cpu/kernel_cpu.h index 9895080d328..c8938534fe8 100644 --- a/intern/cycles/kernel/kernels/cpu/kernel_cpu.h +++ b/intern/cycles/kernel/kernels/cpu/kernel_cpu.h @@ -85,6 +85,7 @@ DECLARE_SPLIT_KERNEL_FUNCTION(subsurface_scatter) DECLARE_SPLIT_KERNEL_FUNCTION(direct_lighting) DECLARE_SPLIT_KERNEL_FUNCTION(shadow_blocked_ao) DECLARE_SPLIT_KERNEL_FUNCTION(shadow_blocked_dl) +DECLARE_SPLIT_KERNEL_FUNCTION(enqueue_inactive) DECLARE_SPLIT_KERNEL_FUNCTION(next_iteration_setup) DECLARE_SPLIT_KERNEL_FUNCTION(indirect_subsurface) DECLARE_SPLIT_KERNEL_FUNCTION(buffer_update) diff --git a/intern/cycles/kernel/kernels/cpu/kernel_cpu_impl.h b/intern/cycles/kernel/kernels/cpu/kernel_cpu_impl.h index 9b85a864153..d4315ee5ec4 100644 --- a/intern/cycles/kernel/kernels/cpu/kernel_cpu_impl.h +++ b/intern/cycles/kernel/kernels/cpu/kernel_cpu_impl.h @@ -53,6 +53,7 @@ # include "kernel/split/kernel_direct_lighting.h" # include "kernel/split/kernel_shadow_blocked_ao.h" # include "kernel/split/kernel_shadow_blocked_dl.h" +# include "kernel/split/kernel_enqueue_inactive.h" # include "kernel/split/kernel_next_iteration_setup.h" # include "kernel/split/kernel_indirect_subsurface.h" # include "kernel/split/kernel_buffer_update.h" @@ -230,6 +231,7 @@ DEFINE_SPLIT_KERNEL_FUNCTION(subsurface_scatter) DEFINE_SPLIT_KERNEL_FUNCTION_LOCALS(direct_lighting, uint) DEFINE_SPLIT_KERNEL_FUNCTION(shadow_blocked_ao) DEFINE_SPLIT_KERNEL_FUNCTION(shadow_blocked_dl) +DEFINE_SPLIT_KERNEL_FUNCTION_LOCALS(enqueue_inactive, uint) DEFINE_SPLIT_KERNEL_FUNCTION_LOCALS(next_iteration_setup, uint) DEFINE_SPLIT_KERNEL_FUNCTION(indirect_subsurface) DEFINE_SPLIT_KERNEL_FUNCTION_LOCALS(buffer_update, uint) diff --git a/intern/cycles/kernel/kernels/cuda/filter.cu b/intern/cycles/kernel/kernels/cuda/filter.cu index 2edbff08087..009c3fde9d5 100644 --- a/intern/cycles/kernel/kernels/cuda/filter.cu +++ b/intern/cycles/kernel/kernels/cuda/filter.cu @@ -207,8 +207,6 @@ CUDA_LAUNCH_BOUNDS(CUDA_THREADS_BLOCK_WIDTH, CUDA_KERNEL_MAX_REGISTERS) kernel_cuda_filter_nlm_construct_gramian(int dx, int dy, const float *ccl_restrict difference_image, const float *ccl_restrict buffer, - float *color_pass, - float *variance_pass, float const* __restrict__ transform, int *rank, float *XtWX, @@ -225,7 +223,6 @@ kernel_cuda_filter_nlm_construct_gramian(int dx, int dy, dx, dy, difference_image, buffer, - color_pass, variance_pass, transform, rank, XtWX, XtWY, rect, filter_rect, diff --git a/intern/cycles/kernel/kernels/cuda/kernel_split.cu b/intern/cycles/kernel/kernels/cuda/kernel_split.cu index 8b7f1a8d405..628891b1458 100644 --- a/intern/cycles/kernel/kernels/cuda/kernel_split.cu +++ b/intern/cycles/kernel/kernels/cuda/kernel_split.cu @@ -39,6 +39,7 @@ #include "kernel/split/kernel_direct_lighting.h" #include "kernel/split/kernel_shadow_blocked_ao.h" #include "kernel/split/kernel_shadow_blocked_dl.h" +#include "kernel/split/kernel_enqueue_inactive.h" #include "kernel/split/kernel_next_iteration_setup.h" #include "kernel/split/kernel_indirect_subsurface.h" #include "kernel/split/kernel_buffer_update.h" @@ -118,6 +119,7 @@ DEFINE_SPLIT_KERNEL_FUNCTION(subsurface_scatter) DEFINE_SPLIT_KERNEL_FUNCTION_LOCALS(direct_lighting, uint) DEFINE_SPLIT_KERNEL_FUNCTION(shadow_blocked_ao) DEFINE_SPLIT_KERNEL_FUNCTION(shadow_blocked_dl) +DEFINE_SPLIT_KERNEL_FUNCTION_LOCALS(enqueue_inactive, uint) DEFINE_SPLIT_KERNEL_FUNCTION_LOCALS(next_iteration_setup, uint) DEFINE_SPLIT_KERNEL_FUNCTION(indirect_subsurface) DEFINE_SPLIT_KERNEL_FUNCTION_LOCALS(buffer_update, uint) diff --git a/intern/cycles/kernel/kernels/opencl/filter.cl b/intern/cycles/kernel/kernels/opencl/filter.cl index 0462ca6f9bc..ba53ba4b26f 100644 --- a/intern/cycles/kernel/kernels/opencl/filter.cl +++ b/intern/cycles/kernel/kernels/opencl/filter.cl @@ -207,8 +207,6 @@ __kernel void kernel_ocl_filter_nlm_construct_gramian(int dx, int dy, const ccl_global float *ccl_restrict difference_image, const ccl_global float *ccl_restrict buffer, - ccl_global float *color_pass, - ccl_global float *variance_pass, const ccl_global float *ccl_restrict transform, ccl_global int *rank, ccl_global float *XtWX, @@ -227,7 +225,6 @@ __kernel void kernel_ocl_filter_nlm_construct_gramian(int dx, dx, dy, difference_image, buffer, - color_pass, variance_pass, transform, rank, XtWX, XtWY, rect, filter_rect, diff --git a/intern/cycles/kernel/kernels/opencl/kernel_buffer_update.cl b/intern/cycles/kernel/kernels/opencl/kernel_buffer_update.cl index db65c91baf7..dcea2630aef 100644 --- a/intern/cycles/kernel/kernels/opencl/kernel_buffer_update.cl +++ b/intern/cycles/kernel/kernels/opencl/kernel_buffer_update.cl @@ -18,10 +18,9 @@ #include "kernel/split/kernel_split_common.h" #include "kernel/split/kernel_buffer_update.h" -__kernel void kernel_ocl_path_trace_buffer_update( - ccl_global char *kg, - ccl_constant KernelData *data) -{ - ccl_local unsigned int local_queue_atomics; - kernel_buffer_update((KernelGlobals*)kg, &local_queue_atomics); -} +#define KERNEL_NAME buffer_update +#define LOCALS_TYPE unsigned int +#include "kernel/kernels/opencl/kernel_split_function.h" +#undef KERNEL_NAME +#undef LOCALS_TYPE + diff --git a/intern/cycles/kernel/kernels/opencl/kernel_direct_lighting.cl b/intern/cycles/kernel/kernels/opencl/kernel_direct_lighting.cl index eb34f750881..ed64ae01aae 100644 --- a/intern/cycles/kernel/kernels/opencl/kernel_direct_lighting.cl +++ b/intern/cycles/kernel/kernels/opencl/kernel_direct_lighting.cl @@ -18,10 +18,9 @@ #include "kernel/split/kernel_split_common.h" #include "kernel/split/kernel_direct_lighting.h" -__kernel void kernel_ocl_path_trace_direct_lighting( - ccl_global char *kg, - ccl_constant KernelData *data) -{ - ccl_local unsigned int local_queue_atomics; - kernel_direct_lighting((KernelGlobals*)kg, &local_queue_atomics); -} +#define KERNEL_NAME direct_lighting +#define LOCALS_TYPE unsigned int +#include "kernel/kernels/opencl/kernel_split_function.h" +#undef KERNEL_NAME +#undef LOCALS_TYPE + diff --git a/intern/cycles/kernel/kernels/opencl/kernel_do_volume.cl b/intern/cycles/kernel/kernels/opencl/kernel_do_volume.cl index 83ef5f5f3f2..8afaa686e28 100644 --- a/intern/cycles/kernel/kernels/opencl/kernel_do_volume.cl +++ b/intern/cycles/kernel/kernels/opencl/kernel_do_volume.cl @@ -18,9 +18,7 @@ #include "kernel/split/kernel_split_common.h" #include "kernel/split/kernel_do_volume.h" -__kernel void kernel_ocl_path_trace_do_volume( - ccl_global char *kg, - ccl_constant KernelData *data) -{ - kernel_do_volume((KernelGlobals*)kg); -} +#define KERNEL_NAME do_volume +#include "kernel/kernels/opencl/kernel_split_function.h" +#undef KERNEL_NAME + diff --git a/intern/cycles/kernel/kernels/opencl/kernel_enqueue_inactive.cl b/intern/cycles/kernel/kernels/opencl/kernel_enqueue_inactive.cl new file mode 100644 index 00000000000..e68d4104a91 --- /dev/null +++ b/intern/cycles/kernel/kernels/opencl/kernel_enqueue_inactive.cl @@ -0,0 +1,26 @@ +/* + * Copyright 2011-2017 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "kernel/kernel_compat_opencl.h" +#include "kernel/split/kernel_split_common.h" +#include "kernel/split/kernel_enqueue_inactive.h" + +#define KERNEL_NAME enqueue_inactive +#define LOCALS_TYPE unsigned int +#include "kernel/kernels/opencl/kernel_split_function.h" +#undef KERNEL_NAME +#undef LOCALS_TYPE + diff --git a/intern/cycles/kernel/kernels/opencl/kernel_holdout_emission_blurring_pathtermination_ao.cl b/intern/cycles/kernel/kernels/opencl/kernel_holdout_emission_blurring_pathtermination_ao.cl index d071b39aa6f..9e1e57beba6 100644 --- a/intern/cycles/kernel/kernels/opencl/kernel_holdout_emission_blurring_pathtermination_ao.cl +++ b/intern/cycles/kernel/kernels/opencl/kernel_holdout_emission_blurring_pathtermination_ao.cl @@ -18,12 +18,9 @@ #include "kernel/split/kernel_split_common.h" #include "kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h" -__kernel void kernel_ocl_path_trace_holdout_emission_blurring_pathtermination_ao( - ccl_global char *kg, - ccl_constant KernelData *data) -{ - ccl_local BackgroundAOLocals locals; - kernel_holdout_emission_blurring_pathtermination_ao( - (KernelGlobals*)kg, - &locals); -} +#define KERNEL_NAME holdout_emission_blurring_pathtermination_ao +#define LOCALS_TYPE BackgroundAOLocals +#include "kernel/kernels/opencl/kernel_split_function.h" +#undef KERNEL_NAME +#undef LOCALS_TYPE + diff --git a/intern/cycles/kernel/kernels/opencl/kernel_indirect_background.cl b/intern/cycles/kernel/kernels/opencl/kernel_indirect_background.cl index 8c213ff5cb2..192d01444ba 100644 --- a/intern/cycles/kernel/kernels/opencl/kernel_indirect_background.cl +++ b/intern/cycles/kernel/kernels/opencl/kernel_indirect_background.cl @@ -18,9 +18,7 @@ #include "kernel/split/kernel_split_common.h" #include "kernel/split/kernel_indirect_background.h" -__kernel void kernel_ocl_path_trace_indirect_background( - ccl_global char *kg, - ccl_constant KernelData *data) -{ - kernel_indirect_background((KernelGlobals*)kg); -} +#define KERNEL_NAME indirect_background +#include "kernel/kernels/opencl/kernel_split_function.h" +#undef KERNEL_NAME + diff --git a/intern/cycles/kernel/kernels/opencl/kernel_indirect_subsurface.cl b/intern/cycles/kernel/kernels/opencl/kernel_indirect_subsurface.cl index 998ebc4c0c3..84938b889e5 100644 --- a/intern/cycles/kernel/kernels/opencl/kernel_indirect_subsurface.cl +++ b/intern/cycles/kernel/kernels/opencl/kernel_indirect_subsurface.cl @@ -18,9 +18,7 @@ #include "kernel/split/kernel_split_common.h" #include "kernel/split/kernel_indirect_subsurface.h" -__kernel void kernel_ocl_path_trace_indirect_subsurface( - ccl_global char *kg, - ccl_constant KernelData *data) -{ - kernel_indirect_subsurface((KernelGlobals*)kg); -} +#define KERNEL_NAME indirect_subsurface +#include "kernel/kernels/opencl/kernel_split_function.h" +#undef KERNEL_NAME + diff --git a/intern/cycles/kernel/kernels/opencl/kernel_lamp_emission.cl b/intern/cycles/kernel/kernels/opencl/kernel_lamp_emission.cl index 822d2287715..c314dc96c33 100644 --- a/intern/cycles/kernel/kernels/opencl/kernel_lamp_emission.cl +++ b/intern/cycles/kernel/kernels/opencl/kernel_lamp_emission.cl @@ -18,9 +18,7 @@ #include "kernel/split/kernel_split_common.h" #include "kernel/split/kernel_lamp_emission.h" -__kernel void kernel_ocl_path_trace_lamp_emission( - ccl_global char *kg, - ccl_constant KernelData *data) -{ - kernel_lamp_emission((KernelGlobals*)kg); -} +#define KERNEL_NAME lamp_emission +#include "kernel/kernels/opencl/kernel_split_function.h" +#undef KERNEL_NAME + diff --git a/intern/cycles/kernel/kernels/opencl/kernel_next_iteration_setup.cl b/intern/cycles/kernel/kernels/opencl/kernel_next_iteration_setup.cl index 6d207253a40..8b1332bf013 100644 --- a/intern/cycles/kernel/kernels/opencl/kernel_next_iteration_setup.cl +++ b/intern/cycles/kernel/kernels/opencl/kernel_next_iteration_setup.cl @@ -18,10 +18,9 @@ #include "kernel/split/kernel_split_common.h" #include "kernel/split/kernel_next_iteration_setup.h" -__kernel void kernel_ocl_path_trace_next_iteration_setup( - ccl_global char *kg, - ccl_constant KernelData *data) -{ - ccl_local unsigned int local_queue_atomics; - kernel_next_iteration_setup((KernelGlobals*)kg, &local_queue_atomics); -} +#define KERNEL_NAME next_iteration_setup +#define LOCALS_TYPE unsigned int +#include "kernel/kernels/opencl/kernel_split_function.h" +#undef KERNEL_NAME +#undef LOCALS_TYPE + diff --git a/intern/cycles/kernel/kernels/opencl/kernel_path_init.cl b/intern/cycles/kernel/kernels/opencl/kernel_path_init.cl index bd9aa9538c8..fa210e747c0 100644 --- a/intern/cycles/kernel/kernels/opencl/kernel_path_init.cl +++ b/intern/cycles/kernel/kernels/opencl/kernel_path_init.cl @@ -18,9 +18,7 @@ #include "kernel/split/kernel_split_common.h" #include "kernel/split/kernel_path_init.h" -__kernel void kernel_ocl_path_trace_path_init( - ccl_global char *kg, - ccl_constant KernelData *data) -{ - kernel_path_init((KernelGlobals*)kg); -} +#define KERNEL_NAME path_init +#include "kernel/kernels/opencl/kernel_split_function.h" +#undef KERNEL_NAME + diff --git a/intern/cycles/kernel/kernels/opencl/kernel_queue_enqueue.cl b/intern/cycles/kernel/kernels/opencl/kernel_queue_enqueue.cl index 9be154e3d75..68ee6f1d536 100644 --- a/intern/cycles/kernel/kernels/opencl/kernel_queue_enqueue.cl +++ b/intern/cycles/kernel/kernels/opencl/kernel_queue_enqueue.cl @@ -18,10 +18,9 @@ #include "kernel/split/kernel_split_common.h" #include "kernel/split/kernel_queue_enqueue.h" -__kernel void kernel_ocl_path_trace_queue_enqueue( - ccl_global char *kg, - ccl_constant KernelData *data) -{ - ccl_local QueueEnqueueLocals locals; - kernel_queue_enqueue((KernelGlobals*)kg, &locals); -} +#define KERNEL_NAME queue_enqueue +#define LOCALS_TYPE QueueEnqueueLocals +#include "kernel/kernels/opencl/kernel_split_function.h" +#undef KERNEL_NAME +#undef LOCALS_TYPE + diff --git a/intern/cycles/kernel/kernels/opencl/kernel_scene_intersect.cl b/intern/cycles/kernel/kernels/opencl/kernel_scene_intersect.cl index eb4fb4d153a..10d09377ba9 100644 --- a/intern/cycles/kernel/kernels/opencl/kernel_scene_intersect.cl +++ b/intern/cycles/kernel/kernels/opencl/kernel_scene_intersect.cl @@ -18,9 +18,7 @@ #include "kernel/split/kernel_split_common.h" #include "kernel/split/kernel_scene_intersect.h" -__kernel void kernel_ocl_path_trace_scene_intersect( - ccl_global char *kg, - ccl_constant KernelData *data) -{ - kernel_scene_intersect((KernelGlobals*)kg); -} +#define KERNEL_NAME scene_intersect +#include "kernel/kernels/opencl/kernel_split_function.h" +#undef KERNEL_NAME + diff --git a/intern/cycles/kernel/kernels/opencl/kernel_shader_eval.cl b/intern/cycles/kernel/kernels/opencl/kernel_shader_eval.cl index 5bfb31b193a..40eaa561863 100644 --- a/intern/cycles/kernel/kernels/opencl/kernel_shader_eval.cl +++ b/intern/cycles/kernel/kernels/opencl/kernel_shader_eval.cl @@ -18,9 +18,7 @@ #include "kernel/split/kernel_split_common.h" #include "kernel/split/kernel_shader_eval.h" -__kernel void kernel_ocl_path_trace_shader_eval( - ccl_global char *kg, - ccl_constant KernelData *data) -{ - kernel_shader_eval((KernelGlobals*)kg); -} +#define KERNEL_NAME shader_eval +#include "kernel/kernels/opencl/kernel_split_function.h" +#undef KERNEL_NAME + diff --git a/intern/cycles/kernel/kernels/opencl/kernel_shader_setup.cl b/intern/cycles/kernel/kernels/opencl/kernel_shader_setup.cl index 38bfd04ad4c..8c36100f762 100644 --- a/intern/cycles/kernel/kernels/opencl/kernel_shader_setup.cl +++ b/intern/cycles/kernel/kernels/opencl/kernel_shader_setup.cl @@ -18,10 +18,9 @@ #include "kernel/split/kernel_split_common.h" #include "kernel/split/kernel_shader_setup.h" -__kernel void kernel_ocl_path_trace_shader_setup( - ccl_global char *kg, - ccl_constant KernelData *data) -{ - ccl_local unsigned int local_queue_atomics; - kernel_shader_setup((KernelGlobals*)kg, &local_queue_atomics); -} +#define KERNEL_NAME shader_setup +#define LOCALS_TYPE unsigned int +#include "kernel/kernels/opencl/kernel_split_function.h" +#undef KERNEL_NAME +#undef LOCALS_TYPE + diff --git a/intern/cycles/kernel/kernels/opencl/kernel_shader_sort.cl b/intern/cycles/kernel/kernels/opencl/kernel_shader_sort.cl index 6f722915d45..bcacaa4a054 100644 --- a/intern/cycles/kernel/kernels/opencl/kernel_shader_sort.cl +++ b/intern/cycles/kernel/kernels/opencl/kernel_shader_sort.cl @@ -19,10 +19,9 @@ #include "kernel/split/kernel_shader_sort.h" __attribute__((reqd_work_group_size(64, 1, 1))) -__kernel void kernel_ocl_path_trace_shader_sort( - ccl_global char *kg, - ccl_constant KernelData *data) -{ - ccl_local ShaderSortLocals locals; - kernel_shader_sort((KernelGlobals*)kg, &locals); -} +#define KERNEL_NAME shader_sort +#define LOCALS_TYPE ShaderSortLocals +#include "kernel/kernels/opencl/kernel_split_function.h" +#undef KERNEL_NAME +#undef LOCALS_TYPE + diff --git a/intern/cycles/kernel/kernels/opencl/kernel_shadow_blocked_ao.cl b/intern/cycles/kernel/kernels/opencl/kernel_shadow_blocked_ao.cl index 6a8ef81b32a..8de250a375c 100644 --- a/intern/cycles/kernel/kernels/opencl/kernel_shadow_blocked_ao.cl +++ b/intern/cycles/kernel/kernels/opencl/kernel_shadow_blocked_ao.cl @@ -18,9 +18,7 @@ #include "kernel/split/kernel_split_common.h" #include "kernel/split/kernel_shadow_blocked_ao.h" -__kernel void kernel_ocl_path_trace_shadow_blocked_ao( - ccl_global char *kg, - ccl_constant KernelData *data) -{ - kernel_shadow_blocked_ao((KernelGlobals*)kg); -} +#define KERNEL_NAME shadow_blocked_ao +#include "kernel/kernels/opencl/kernel_split_function.h" +#undef KERNEL_NAME + diff --git a/intern/cycles/kernel/kernels/opencl/kernel_shadow_blocked_dl.cl b/intern/cycles/kernel/kernels/opencl/kernel_shadow_blocked_dl.cl index b255cc5ef8b..29da77022ed 100644 --- a/intern/cycles/kernel/kernels/opencl/kernel_shadow_blocked_dl.cl +++ b/intern/cycles/kernel/kernels/opencl/kernel_shadow_blocked_dl.cl @@ -18,9 +18,7 @@ #include "kernel/split/kernel_split_common.h" #include "kernel/split/kernel_shadow_blocked_dl.h" -__kernel void kernel_ocl_path_trace_shadow_blocked_dl( - ccl_global char *kg, - ccl_constant KernelData *data) -{ - kernel_shadow_blocked_dl((KernelGlobals*)kg); -} +#define KERNEL_NAME shadow_blocked_dl +#include "kernel/kernels/opencl/kernel_split_function.h" +#undef KERNEL_NAME + diff --git a/intern/cycles/kernel/kernels/opencl/kernel_split.cl b/intern/cycles/kernel/kernels/opencl/kernel_split.cl index 8de82db7afe..651addb02f4 100644 --- a/intern/cycles/kernel/kernels/opencl/kernel_split.cl +++ b/intern/cycles/kernel/kernels/opencl/kernel_split.cl @@ -31,6 +31,7 @@ #include "kernel/kernels/opencl/kernel_direct_lighting.cl" #include "kernel/kernels/opencl/kernel_shadow_blocked_ao.cl" #include "kernel/kernels/opencl/kernel_shadow_blocked_dl.cl" +#include "kernel/kernels/opencl/kernel_enqueue_inactive.cl" #include "kernel/kernels/opencl/kernel_next_iteration_setup.cl" #include "kernel/kernels/opencl/kernel_indirect_subsurface.cl" #include "kernel/kernels/opencl/kernel_buffer_update.cl" diff --git a/intern/cycles/kernel/kernels/opencl/kernel_split_function.h b/intern/cycles/kernel/kernels/opencl/kernel_split_function.h new file mode 100644 index 00000000000..f1e914a70d4 --- /dev/null +++ b/intern/cycles/kernel/kernels/opencl/kernel_split_function.h @@ -0,0 +1,72 @@ +/* + * Copyright 2011-2017 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define KERNEL_NAME_JOIN(a, b) a ## _ ## b +#define KERNEL_NAME_EVAL(a, b) KERNEL_NAME_JOIN(a, b) + +__kernel void KERNEL_NAME_EVAL(kernel_ocl_path_trace, KERNEL_NAME)( + ccl_global char *kg_global, + ccl_constant KernelData *data, + + ccl_global void *split_data_buffer, + ccl_global char *ray_state, + ccl_global uint *rng_state, + +#define KERNEL_TEX(type, ttype, name) \ + ccl_global type *name, +#include "kernel/kernel_textures.h" + + ccl_global int *queue_index, + ccl_global char *use_queues_flag, + ccl_global unsigned int *work_pools, + ccl_global float *buffer + ) +{ +#ifdef LOCALS_TYPE + ccl_local LOCALS_TYPE locals; +#endif + + KernelGlobals *kg = (KernelGlobals*)kg_global; + + if(ccl_local_id(0) + ccl_local_id(1) == 0) { + kg->data = data; + + kernel_split_params.rng_state = rng_state; + kernel_split_params.queue_index = queue_index; + kernel_split_params.use_queues_flag = use_queues_flag; + kernel_split_params.work_pools = work_pools; + kernel_split_params.buffer = buffer; + + split_data_init(kg, &kernel_split_state, ccl_global_size(0)*ccl_global_size(1), split_data_buffer, ray_state); + +#define KERNEL_TEX(type, ttype, name) \ + kg->name = name; +#include "kernel/kernel_textures.h" + } + + ccl_barrier(CCL_LOCAL_MEM_FENCE); + + KERNEL_NAME_EVAL(kernel, KERNEL_NAME)( + kg +#ifdef LOCALS_TYPE + , &locals +#endif + ); +} + +#undef KERNEL_NAME_JOIN +#undef KERNEL_NAME_EVAL + diff --git a/intern/cycles/kernel/kernels/opencl/kernel_subsurface_scatter.cl b/intern/cycles/kernel/kernels/opencl/kernel_subsurface_scatter.cl index 99b74a1802b..2b3be38df84 100644 --- a/intern/cycles/kernel/kernels/opencl/kernel_subsurface_scatter.cl +++ b/intern/cycles/kernel/kernels/opencl/kernel_subsurface_scatter.cl @@ -18,9 +18,7 @@ #include "kernel/split/kernel_split_common.h" #include "kernel/split/kernel_subsurface_scatter.h" -__kernel void kernel_ocl_path_trace_subsurface_scatter( - ccl_global char *kg, - ccl_constant KernelData *data) -{ - kernel_subsurface_scatter((KernelGlobals*)kg); -} +#define KERNEL_NAME subsurface_scatter +#include "kernel/kernels/opencl/kernel_split_function.h" +#undef KERNEL_NAME + diff --git a/intern/cycles/kernel/osl/osl_bssrdf.cpp b/intern/cycles/kernel/osl/osl_bssrdf.cpp index 188c3960a5f..27a96720c1e 100644 --- a/intern/cycles/kernel/osl/osl_bssrdf.cpp +++ b/intern/cycles/kernel/osl/osl_bssrdf.cpp @@ -191,7 +191,7 @@ class PrincipledBSSRDFClosure : public CBSSRDFClosure { public: void setup(ShaderData *sd, int path_flag, float3 weight) { - alloc(sd, path_flag, weight * albedo, CLOSURE_BSSRDF_PRINCIPLED_ID); + alloc(sd, path_flag, weight, CLOSURE_BSSRDF_PRINCIPLED_ID); } }; diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp index 5b66793a05d..14c5c1c3db5 100644 --- a/intern/cycles/kernel/osl/osl_closures.cpp +++ b/intern/cycles/kernel/osl/osl_closures.cpp @@ -156,7 +156,7 @@ BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannRefraction, microfacet_beckmann_refra BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction) BSDF_CLOSURE_CLASS_BEGIN(HairReflection, hair_reflection, HairBsdf, LABEL_GLOSSY) - CLOSURE_FLOAT3_PARAM(HairReflectionClosure, unused), + CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.N), CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.roughness1), CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.roughness2), CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.T), @@ -164,7 +164,7 @@ BSDF_CLOSURE_CLASS_BEGIN(HairReflection, hair_reflection, HairBsdf, LABEL_GLOSSY BSDF_CLOSURE_CLASS_END(HairReflection, hair_reflection) BSDF_CLOSURE_CLASS_BEGIN(HairTransmission, hair_transmission, HairBsdf, LABEL_GLOSSY) - CLOSURE_FLOAT3_PARAM(HairTransmissionClosure, unused), + CLOSURE_FLOAT3_PARAM(HairTransmissionClosure, params.N), CLOSURE_FLOAT_PARAM(HairTransmissionClosure, params.roughness1), CLOSURE_FLOAT_PARAM(HairTransmissionClosure, params.roughness2), CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.T), @@ -191,7 +191,7 @@ BSDF_CLOSURE_CLASS_END(PrincipledSheen, principled_sheen) class PrincipledClearcoatClosure : public CBSDFClosure { public: MicrofacetBsdf params; - float clearcoat, clearcoat_gloss; + float clearcoat, clearcoat_roughness; MicrofacetBsdf *alloc(ShaderData *sd, int path_flag, float3 weight) { @@ -202,8 +202,8 @@ public: bsdf->ior = 1.5f; - bsdf->alpha_x = 0.1f * (1.0f - clearcoat_gloss) + 0.001f * clearcoat_gloss; - bsdf->alpha_y = 0.1f * (1.0f - clearcoat_gloss) + 0.001f * clearcoat_gloss; + bsdf->alpha_x = clearcoat_roughness; + bsdf->alpha_y = clearcoat_roughness; bsdf->extra->cspec0 = make_float3(0.04f, 0.04f, 0.04f); bsdf->extra->clearcoat = clearcoat; @@ -217,7 +217,7 @@ public: void setup(ShaderData *sd, int path_flag, float3 weight) { MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight); - sd->flag |= (bsdf) ? bsdf_microfacet_ggx_clearcoat_setup(bsdf) : 0; + sd->flag |= (bsdf) ? bsdf_microfacet_ggx_clearcoat_setup(bsdf, sd) : 0; } }; @@ -226,7 +226,7 @@ ClosureParam *closure_bsdf_principled_clearcoat_params() static ClosureParam params[] = { CLOSURE_FLOAT3_PARAM(PrincipledClearcoatClosure, params.N), CLOSURE_FLOAT_PARAM(PrincipledClearcoatClosure, clearcoat), - CLOSURE_FLOAT_PARAM(PrincipledClearcoatClosure, clearcoat_gloss), + CLOSURE_FLOAT_PARAM(PrincipledClearcoatClosure, clearcoat_roughness), CLOSURE_STRING_KEYPARAM(PrincipledClearcoatClosure, label, "label"), CLOSURE_FINISH_PARAM(PrincipledClearcoatClosure) }; @@ -389,7 +389,7 @@ public: void setup(ShaderData *sd, int path_flag, float3 weight) { MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight); - sd->flag |= (bsdf) ? bsdf_microfacet_ggx_fresnel_setup(bsdf) : 0; + sd->flag |= (bsdf) ? bsdf_microfacet_ggx_fresnel_setup(bsdf, sd) : 0; } }; @@ -413,7 +413,7 @@ public: void setup(ShaderData *sd, int path_flag, float3 weight) { MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight); - sd->flag |= (bsdf) ? bsdf_microfacet_ggx_aniso_fresnel_setup(bsdf) : 0; + sd->flag |= (bsdf) ? bsdf_microfacet_ggx_aniso_fresnel_setup(bsdf, sd) : 0; } }; @@ -566,7 +566,7 @@ public: void setup(ShaderData *sd, int path_flag, float3 weight) { MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight); - sd->flag |= (bsdf) ? bsdf_microfacet_multi_ggx_fresnel_setup(bsdf) : 0; + sd->flag |= (bsdf) ? bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd) : 0; } }; @@ -590,7 +590,7 @@ public: void setup(ShaderData *sd, int path_flag, float3 weight) { MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight); - sd->flag |= (bsdf) ? bsdf_microfacet_multi_ggx_aniso_fresnel_setup(bsdf) : 0; + sd->flag |= (bsdf) ? bsdf_microfacet_multi_ggx_aniso_fresnel_setup(bsdf, sd) : 0; } }; @@ -618,7 +618,7 @@ public: void setup(ShaderData *sd, int path_flag, float3 weight) { MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight); - sd->flag |= (bsdf) ? bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf) : 0; + sd->flag |= (bsdf) ? bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf, sd) : 0; } }; diff --git a/intern/cycles/kernel/shaders/node_principled_bsdf.osl b/intern/cycles/kernel/shaders/node_principled_bsdf.osl index 57f40789d49..2bb981c3918 100644 --- a/intern/cycles/kernel/shaders/node_principled_bsdf.osl +++ b/intern/cycles/kernel/shaders/node_principled_bsdf.osl @@ -32,7 +32,7 @@ shader node_principled_bsdf( float Sheen = 0.0, float SheenTint = 0.5, float Clearcoat = 0.0, - float ClearcoatGloss = 1.0, + float ClearcoatRoughness = 0.03, float IOR = 1.45, float Transmission = 0.0, float TransmissionRoughness = 0.0, @@ -57,8 +57,8 @@ shader node_principled_bsdf( if (diffuse_weight > 1e-5) { if (Subsurface > 1e-5) { - color Albedo = SubsurfaceColor * Subsurface + BaseColor * (1.0 - Subsurface); - BSDF = bssrdf_principled(Normal, Subsurface * SubsurfaceRadius, 0.0, Albedo, Roughness); + color mixed_ss_base_color = SubsurfaceColor * Subsurface + BaseColor * (1.0 - Subsurface); + BSDF = mixed_ss_base_color * bssrdf_principled(Normal, Subsurface * SubsurfaceRadius, 0.0, SubsurfaceColor, Roughness); } else { BSDF = BaseColor * principled_diffuse(Normal, Roughness); } @@ -114,7 +114,7 @@ shader node_principled_bsdf( } if (Clearcoat > 1e-5) { - BSDF = BSDF + principled_clearcoat(ClearcoatNormal, Clearcoat, ClearcoatGloss); + BSDF = BSDF + principled_clearcoat(ClearcoatNormal, Clearcoat, ClearcoatRoughness * ClearcoatRoughness); } } diff --git a/intern/cycles/kernel/shaders/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h index 289d1091b0a..c91d2918687 100644 --- a/intern/cycles/kernel/shaders/stdosl.h +++ b/intern/cycles/kernel/shaders/stdosl.h @@ -546,7 +546,7 @@ closure color holdout() BUILTIN; closure color ambient_occlusion() BUILTIN; closure color principled_diffuse(normal N, float roughness) BUILTIN; closure color principled_sheen(normal N) BUILTIN; -closure color principled_clearcoat(normal N, float clearcoat, float clearcoat_gloss) BUILTIN; +closure color principled_clearcoat(normal N, float clearcoat, float clearcoat_roughness) BUILTIN; // BSSRDF closure color bssrdf_cubic(normal N, vector radius, float texture_blur, float sharpness) BUILTIN; diff --git a/intern/cycles/kernel/split/kernel_branched.h b/intern/cycles/kernel/split/kernel_branched.h index dc74a2ada53..e2762a85fc8 100644 --- a/intern/cycles/kernel/split/kernel_branched.h +++ b/intern/cycles/kernel/split/kernel_branched.h @@ -63,12 +63,49 @@ ccl_device_inline void kernel_split_branched_path_indirect_loop_end(KernelGlobal REMOVE_RAY_FLAG(kernel_split_state.ray_state, ray_index, RAY_BRANCHED_INDIRECT); } +ccl_device_inline bool kernel_split_branched_indirect_start_shared(KernelGlobals *kg, int ray_index) +{ + ccl_global char *ray_state = kernel_split_state.ray_state; + + int inactive_ray = dequeue_ray_index(QUEUE_INACTIVE_RAYS, + kernel_split_state.queue_data, kernel_split_params.queue_size, kernel_split_params.queue_index); + + if(!IS_STATE(ray_state, inactive_ray, RAY_INACTIVE)) { + return false; + } + +#define SPLIT_DATA_ENTRY(type, name, num) \ + kernel_split_state.name[inactive_ray] = kernel_split_state.name[ray_index]; + SPLIT_DATA_ENTRIES_BRANCHED_SHARED +#undef SPLIT_DATA_ENTRY + + kernel_split_state.branched_state[inactive_ray].shared_sample_count = 0; + kernel_split_state.branched_state[inactive_ray].original_ray = ray_index; + kernel_split_state.branched_state[inactive_ray].waiting_on_shared_samples = false; + + PathRadiance *L = &kernel_split_state.path_radiance[ray_index]; + PathRadiance *inactive_L = &kernel_split_state.path_radiance[inactive_ray]; + + path_radiance_init(inactive_L, kernel_data.film.use_light_pass); + inactive_L->direct_throughput = L->direct_throughput; + path_radiance_copy_indirect(inactive_L, L); + + ray_state[inactive_ray] = RAY_REGENERATED; + ADD_RAY_FLAG(ray_state, inactive_ray, RAY_BRANCHED_INDIRECT_SHARED); + ADD_RAY_FLAG(ray_state, inactive_ray, IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT)); + + atomic_fetch_and_inc_uint32((ccl_global uint*)&kernel_split_state.branched_state[ray_index].shared_sample_count); + + return true; +} + /* bounce off surface and integrate indirect light */ ccl_device_noinline bool kernel_split_branched_path_surface_indirect_light_iter(KernelGlobals *kg, int ray_index, float num_samples_adjust, ShaderData *saved_sd, - bool reset_path_state) + bool reset_path_state, + bool wait_for_shared) { SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index]; @@ -155,12 +192,25 @@ ccl_device_noinline bool kernel_split_branched_path_surface_indirect_light_iter( /* start the indirect path */ *tp *= num_samples_inv; + if(kernel_split_branched_indirect_start_shared(kg, ray_index)) { + continue; + } + return true; } branched_state->next_sample = 0; } + branched_state->next_closure = sd->num_closure; + + if(wait_for_shared) { + branched_state->waiting_on_shared_samples = (branched_state->shared_sample_count > 0); + if(branched_state->waiting_on_shared_samples) { + return true; + } + } + return false; } diff --git a/intern/cycles/kernel/split/kernel_do_volume.h b/intern/cycles/kernel/split/kernel_do_volume.h index 694b777f429..9f8dd2392d9 100644 --- a/intern/cycles/kernel/split/kernel_do_volume.h +++ b/intern/cycles/kernel/split/kernel_do_volume.h @@ -75,11 +75,30 @@ ccl_device_noinline bool kernel_split_branched_path_volume_indirect_light_iter(K branched_state->next_sample = j+1; branched_state->num_samples = num_samples; + /* Attempting to share too many samples is slow for volumes as it causes us to + * loop here more and have many calls to kernel_volume_integrate which evaluates + * shaders. The many expensive shader evaluations cause the work load to become + * unbalanced and many threads to become idle in this kernel. Limiting the + * number of shared samples here helps quite a lot. + */ + if(branched_state->shared_sample_count < 2) { + if(kernel_split_branched_indirect_start_shared(kg, ray_index)) { + continue; + } + } + return true; } # endif } + branched_state->next_sample = num_samples; + + branched_state->waiting_on_shared_samples = (branched_state->shared_sample_count > 0); + if(branched_state->waiting_on_shared_samples) { + return true; + } + kernel_split_branched_path_indirect_loop_end(kg, ray_index); /* todo: avoid this calculation using decoupled ray marching */ diff --git a/intern/cycles/kernel/split/kernel_enqueue_inactive.h b/intern/cycles/kernel/split/kernel_enqueue_inactive.h new file mode 100644 index 00000000000..496355bbc3a --- /dev/null +++ b/intern/cycles/kernel/split/kernel_enqueue_inactive.h @@ -0,0 +1,46 @@ +/* + * Copyright 2011-2017 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +CCL_NAMESPACE_BEGIN + +ccl_device void kernel_enqueue_inactive(KernelGlobals *kg, + ccl_local_param unsigned int *local_queue_atomics) +{ +#ifdef __BRANCHED_PATH__ + /* Enqeueue RAY_INACTIVE rays into QUEUE_INACTIVE_RAYS queue. */ + if(ccl_local_id(0) == 0 && ccl_local_id(1) == 0) { + *local_queue_atomics = 0; + } + ccl_barrier(CCL_LOCAL_MEM_FENCE); + + int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0); + + char enqueue_flag = 0; + if(IS_STATE(kernel_split_state.ray_state, ray_index, RAY_INACTIVE)) { + enqueue_flag = 1; + } + + enqueue_ray_index_local(ray_index, + QUEUE_INACTIVE_RAYS, + enqueue_flag, + kernel_split_params.queue_size, + local_queue_atomics, + kernel_split_state.queue_data, + kernel_split_params.queue_index); +#endif /* __BRANCHED_PATH__ */ +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/split/kernel_next_iteration_setup.h b/intern/cycles/kernel/split/kernel_next_iteration_setup.h index 71017fed19e..7758e35fd32 100644 --- a/intern/cycles/kernel/split/kernel_next_iteration_setup.h +++ b/intern/cycles/kernel/split/kernel_next_iteration_setup.h @@ -147,6 +147,7 @@ ccl_device void kernel_next_iteration_setup(KernelGlobals *kg, ray_index, 1.0f, &kernel_split_state.branched_state[ray_index].sd, + true, true)) { ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED); @@ -193,6 +194,7 @@ ccl_device void kernel_next_iteration_setup(KernelGlobals *kg, ray_index, 1.0f, &kernel_split_state.branched_state[ray_index].sd, + true, true)) { ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED); diff --git a/intern/cycles/kernel/split/kernel_queue_enqueue.h b/intern/cycles/kernel/split/kernel_queue_enqueue.h index e2e841f36d3..66ce2dfb6f1 100644 --- a/intern/cycles/kernel/split/kernel_queue_enqueue.h +++ b/intern/cycles/kernel/split/kernel_queue_enqueue.h @@ -51,7 +51,8 @@ ccl_device void kernel_queue_enqueue(KernelGlobals *kg, int queue_number = -1; if(IS_STATE(kernel_split_state.ray_state, ray_index, RAY_HIT_BACKGROUND) || - IS_STATE(kernel_split_state.ray_state, ray_index, RAY_UPDATE_BUFFER)) { + IS_STATE(kernel_split_state.ray_state, ray_index, RAY_UPDATE_BUFFER) || + IS_STATE(kernel_split_state.ray_state, ray_index, RAY_TO_REGENERATE)) { queue_number = QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS; } else if(IS_STATE(kernel_split_state.ray_state, ray_index, RAY_ACTIVE) || diff --git a/intern/cycles/kernel/split/kernel_scene_intersect.h b/intern/cycles/kernel/split/kernel_scene_intersect.h index 5dc94caec85..45984ca509b 100644 --- a/intern/cycles/kernel/split/kernel_scene_intersect.h +++ b/intern/cycles/kernel/split/kernel_scene_intersect.h @@ -43,11 +43,21 @@ ccl_device void kernel_scene_intersect(KernelGlobals *kg) } /* All regenerated rays become active here */ - if(IS_STATE(kernel_split_state.ray_state, ray_index, RAY_REGENERATED)) - ASSIGN_RAY_STATE(kernel_split_state.ray_state, ray_index, RAY_ACTIVE); + if(IS_STATE(kernel_split_state.ray_state, ray_index, RAY_REGENERATED)) { +#ifdef __BRANCHED_PATH__ + if(kernel_split_state.branched_state[ray_index].waiting_on_shared_samples) { + kernel_split_path_end(kg, ray_index); + } + else +#endif /* __BRANCHED_PATH__ */ + { + ASSIGN_RAY_STATE(kernel_split_state.ray_state, ray_index, RAY_ACTIVE); + } + } - if(!IS_STATE(kernel_split_state.ray_state, ray_index, RAY_ACTIVE)) + if(!IS_STATE(kernel_split_state.ray_state, ray_index, RAY_ACTIVE)) { return; + } #ifdef __KERNEL_DEBUG__ DebugData *debug_data = &kernel_split_state.debug_data[ray_index]; diff --git a/intern/cycles/kernel/split/kernel_shadow_blocked_dl.h b/intern/cycles/kernel/split/kernel_shadow_blocked_dl.h index 386fbbc4d09..78e61709b01 100644 --- a/intern/cycles/kernel/split/kernel_shadow_blocked_dl.h +++ b/intern/cycles/kernel/split/kernel_shadow_blocked_dl.h @@ -29,6 +29,14 @@ ccl_device void kernel_shadow_blocked_dl(KernelGlobals *kg) kernel_split_state.queue_data, kernel_split_params.queue_size, 1); } +#ifdef __BRANCHED_PATH__ + /* TODO(mai): move this somewhere else? */ + if(thread_index == 0) { + /* Clear QUEUE_INACTIVE_RAYS before next kernel. */ + kernel_split_params.queue_index[QUEUE_INACTIVE_RAYS] = 0; + } +#endif /* __BRANCHED_PATH__ */ + if(ray_index == QUEUE_EMPTY_SLOT) return; diff --git a/intern/cycles/kernel/split/kernel_split_common.h b/intern/cycles/kernel/split/kernel_split_common.h index 57f070d51e0..08f0124b529 100644 --- a/intern/cycles/kernel/split/kernel_split_common.h +++ b/intern/cycles/kernel/split/kernel_split_common.h @@ -56,7 +56,20 @@ ccl_device_inline void kernel_split_path_end(KernelGlobals *kg, int ray_index) ccl_global char *ray_state = kernel_split_state.ray_state; #ifdef __BRANCHED_PATH__ - if(IS_FLAG(ray_state, ray_index, RAY_BRANCHED_LIGHT_INDIRECT)) { + if(IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT_SHARED)) { + int orig_ray = kernel_split_state.branched_state[ray_index].original_ray; + + PathRadiance *L = &kernel_split_state.path_radiance[ray_index]; + PathRadiance *orig_ray_L = &kernel_split_state.path_radiance[orig_ray]; + + path_radiance_sum_indirect(L); + path_radiance_accum_sample(orig_ray_L, L, 1); + + atomic_fetch_and_dec_uint32((ccl_global uint*)&kernel_split_state.branched_state[orig_ray].shared_sample_count); + + ASSIGN_RAY_STATE(ray_state, ray_index, RAY_INACTIVE); + } + else if(IS_FLAG(ray_state, ray_index, RAY_BRANCHED_LIGHT_INDIRECT)) { ASSIGN_RAY_STATE(ray_state, ray_index, RAY_LIGHT_INDIRECT_NEXT_ITER); } else if(IS_FLAG(ray_state, ray_index, RAY_BRANCHED_VOLUME_INDIRECT)) { diff --git a/intern/cycles/kernel/split/kernel_split_data_types.h b/intern/cycles/kernel/split/kernel_split_data_types.h index bb1aca2acbf..4bb2f0d3d80 100644 --- a/intern/cycles/kernel/split/kernel_split_data_types.h +++ b/intern/cycles/kernel/split/kernel_split_data_types.h @@ -95,6 +95,10 @@ typedef ccl_global struct SplitBranchedState { VolumeStack volume_stack[VOLUME_STACK_SIZE]; # endif /* __VOLUME__ */ #endif /*__SUBSURFACE__ */ + + int shared_sample_count; /* number of branched samples shared with other threads */ + int original_ray; /* index of original ray when sharing branched samples */ + bool waiting_on_shared_samples; } SplitBranchedState; #define SPLIT_DATA_BRANCHED_ENTRIES \ @@ -137,6 +141,25 @@ typedef ccl_global struct SplitBranchedState { SPLIT_DATA_BRANCHED_ENTRIES \ SPLIT_DATA_DEBUG_ENTRIES \ +/* entries to be copied to inactive rays when sharing branched samples (TODO: which are actually needed?) */ +#define SPLIT_DATA_ENTRIES_BRANCHED_SHARED \ + SPLIT_DATA_ENTRY(ccl_global RNG, rng, 1) \ + SPLIT_DATA_ENTRY(ccl_global float3, throughput, 1) \ + SPLIT_DATA_ENTRY(ccl_global float, L_transparent, 1) \ + SPLIT_DATA_ENTRY(PathRadiance, path_radiance, 1) \ + SPLIT_DATA_ENTRY(ccl_global Ray, ray, 1) \ + SPLIT_DATA_ENTRY(ccl_global PathState, path_state, 1) \ + SPLIT_DATA_ENTRY(ccl_global Intersection, isect, 1) \ + SPLIT_DATA_ENTRY(ccl_global BsdfEval, bsdf_eval, 1) \ + SPLIT_DATA_ENTRY(ccl_global int, is_lamp, 1) \ + SPLIT_DATA_ENTRY(ccl_global Ray, light_ray, 1) \ + SPLIT_DATA_ENTRY(ShaderData, sd, 1) \ + SPLIT_DATA_ENTRY(ShaderData, sd_DL_shadow, 1) \ + SPLIT_DATA_SUBSURFACE_ENTRIES \ + SPLIT_DATA_VOLUME_ENTRIES \ + SPLIT_DATA_BRANCHED_ENTRIES \ + SPLIT_DATA_DEBUG_ENTRIES \ + /* struct that holds pointers to data in the shared state buffer */ typedef struct SplitData { #define SPLIT_DATA_ENTRY(type, name, num) type *name; diff --git a/intern/cycles/kernel/split/kernel_subsurface_scatter.h b/intern/cycles/kernel/split/kernel_subsurface_scatter.h index 1dffe1b179e..d5083b23f80 100644 --- a/intern/cycles/kernel/split/kernel_subsurface_scatter.h +++ b/intern/cycles/kernel/split/kernel_subsurface_scatter.h @@ -169,6 +169,7 @@ ccl_device_noinline bool kernel_split_branched_path_subsurface_indirect_light_it ray_index, num_samples_inv, bssrdf_sd, + false, false)) { branched_state->ss_next_closure = i; @@ -187,6 +188,13 @@ ccl_device_noinline bool kernel_split_branched_path_subsurface_indirect_light_it branched_state->ss_next_sample = 0; } + branched_state->ss_next_closure = sd->num_closure; + + branched_state->waiting_on_shared_samples = (branched_state->shared_sample_count > 0); + if(branched_state->waiting_on_shared_samples) { + return true; + } + kernel_split_branched_path_indirect_loop_end(kg, ray_index); return false; @@ -257,21 +265,20 @@ ccl_device void kernel_subsurface_scatter(KernelGlobals *kg) /* do bssrdf scatter step if we picked a bssrdf closure */ if(sc) { uint lcg_state = lcg_state_init(&rng, state->rng_offset, state->sample, 0x68bc21eb); - float bssrdf_u, bssrdf_v; path_state_rng_2D(kg, - &rng, - state, - PRNG_BSDF_U, - &bssrdf_u, &bssrdf_v); + &rng, + state, + PRNG_BSDF_U, + &bssrdf_u, &bssrdf_v); subsurface_scatter_step(kg, - sd, - state, - state->flag, - sc, - &lcg_state, - bssrdf_u, bssrdf_v, - false); + sd, + state, + state->flag, + sc, + &lcg_state, + bssrdf_u, bssrdf_v, + false); } } else { diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index f04f765686e..9578fcf2687 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -79,13 +79,13 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * #ifdef __PRINCIPLED__ case CLOSURE_BSDF_PRINCIPLED_ID: { uint specular_offset, roughness_offset, specular_tint_offset, anisotropic_offset, sheen_offset, - sheen_tint_offset, clearcoat_offset, clearcoat_gloss_offset, eta_offset, transmission_offset, + sheen_tint_offset, clearcoat_offset, clearcoat_roughness_offset, eta_offset, transmission_offset, anisotropic_rotation_offset, transmission_roughness_offset; uint4 data_node2 = read_node(kg, offset); float3 T = stack_load_float3(stack, data_node.y); decode_node_uchar4(data_node.z, &specular_offset, &roughness_offset, &specular_tint_offset, &anisotropic_offset); - decode_node_uchar4(data_node.w, &sheen_offset, &sheen_tint_offset, &clearcoat_offset, &clearcoat_gloss_offset); + decode_node_uchar4(data_node.w, &sheen_offset, &sheen_tint_offset, &clearcoat_offset, &clearcoat_roughness_offset); decode_node_uchar4(data_node2.x, &eta_offset, &transmission_offset, &anisotropic_rotation_offset, &transmission_roughness_offset); // get Disney principled parameters @@ -98,7 +98,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * float sheen = stack_load_float(stack, sheen_offset); float sheen_tint = stack_load_float(stack, sheen_tint_offset); float clearcoat = stack_load_float(stack, clearcoat_offset); - float clearcoat_gloss = stack_load_float(stack, clearcoat_gloss_offset); + float clearcoat_roughness = stack_load_float(stack, clearcoat_roughness_offset); float transmission = stack_load_float(stack, transmission_offset); float anisotropic_rotation = stack_load_float(stack, anisotropic_rotation_offset); float transmission_roughness = stack_load_float(stack, transmission_roughness_offset); @@ -141,8 +141,8 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * float3 weight = sd->svm_closure_weight * mix_weight; #ifdef __SUBSURFACE__ - float3 albedo = subsurface_color * subsurface + base_color * (1.0f - subsurface); - float3 subsurf_weight = weight * albedo * diffuse_weight; + float3 mixed_ss_base_color = subsurface_color * subsurface + base_color * (1.0f - subsurface); + float3 subsurf_weight = weight * mixed_ss_base_color * diffuse_weight; float subsurf_sample_weight = fabsf(average(subsurf_weight)); /* disable in case of diffuse ancestor, can't see it well then and @@ -154,11 +154,11 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * /* need to set the base color in this case such that the * rays get the correctly mixed color after transmitting * the object */ - base_color = albedo; + base_color = mixed_ss_base_color; } /* diffuse */ - if(fabsf(average(base_color)) > CLOSURE_WEIGHT_CUTOFF) { + if(fabsf(average(mixed_ss_base_color)) > CLOSURE_WEIGHT_CUTOFF) { if(subsurface < CLOSURE_WEIGHT_CUTOFF && diffuse_weight > CLOSURE_WEIGHT_CUTOFF) { float3 diff_weight = weight * base_color * diffuse_weight; @@ -186,7 +186,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * bssrdf->sample_weight = subsurf_sample_weight; bssrdf->radius = radius.x; bssrdf->texture_blur = texture_blur; - bssrdf->albedo = albedo.x; + bssrdf->albedo = subsurface_color.x; bssrdf->sharpness = sharpness; bssrdf->N = N; bssrdf->roughness = roughness; @@ -200,7 +200,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * bssrdf->sample_weight = subsurf_sample_weight; bssrdf->radius = radius.y; bssrdf->texture_blur = texture_blur; - bssrdf->albedo = albedo.y; + bssrdf->albedo = subsurface_color.y; bssrdf->sharpness = sharpness; bssrdf->N = N; bssrdf->roughness = roughness; @@ -214,7 +214,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * bssrdf->sample_weight = subsurf_sample_weight; bssrdf->radius = radius.z; bssrdf->texture_blur = texture_blur; - bssrdf->albedo = albedo.z; + bssrdf->albedo = subsurface_color.z; bssrdf->sharpness = sharpness; bssrdf->N = N; bssrdf->roughness = roughness; @@ -292,9 +292,9 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * /* setup bsdf */ if(distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID || roughness <= 0.075f) /* use single-scatter GGX */ - sd->flag |= bsdf_microfacet_ggx_aniso_fresnel_setup(bsdf); + sd->flag |= bsdf_microfacet_ggx_aniso_fresnel_setup(bsdf, sd); else /* use multi-scatter GGX */ - sd->flag |= bsdf_microfacet_multi_ggx_aniso_fresnel_setup(bsdf); + sd->flag |= bsdf_microfacet_multi_ggx_aniso_fresnel_setup(bsdf, sd); } } #ifdef __CAUSTICS_TRICKS__ @@ -332,7 +332,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * bsdf->extra->cspec0 = cspec0; /* setup bsdf */ - sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf); + sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd); } } @@ -377,7 +377,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * bsdf->extra->cspec0 = cspec0; /* setup bsdf */ - sd->flag |= bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf); + sd->flag |= bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf, sd); } } } @@ -398,14 +398,14 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * bsdf->ior = 1.5f; bsdf->extra = extra; - bsdf->alpha_x = 0.1f * (1.0f - clearcoat_gloss) + 0.001f * clearcoat_gloss; - bsdf->alpha_y = 0.1f * (1.0f - clearcoat_gloss) + 0.001f * clearcoat_gloss; + bsdf->alpha_x = clearcoat_roughness * clearcoat_roughness; + bsdf->alpha_y = clearcoat_roughness * clearcoat_roughness; bsdf->extra->cspec0 = make_float3(0.04f, 0.04f, 0.04f); bsdf->extra->clearcoat = clearcoat; /* setup bsdf */ - sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(bsdf); + sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(bsdf, sd); } } #ifdef __CAUSTICS_TRICKS__ @@ -725,6 +725,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * HairBsdf *bsdf = (HairBsdf*)bsdf_alloc(sd, sizeof(HairBsdf), weight); if(bsdf) { + bsdf->N = N; bsdf->roughness1 = param1; bsdf->roughness2 = param2; bsdf->offset = -stack_load_float(stack, data_node.z); diff --git a/intern/cycles/render/constant_fold.cpp b/intern/cycles/render/constant_fold.cpp index 2569d9eec27..943b218f0e4 100644 --- a/intern/cycles/render/constant_fold.cpp +++ b/intern/cycles/render/constant_fold.cpp @@ -160,6 +160,14 @@ bool ConstantFolder::try_bypass_or_make_constant(ShaderInput *input, bool clamp) bypass(input->link); return true; } + else { + /* disconnect other inputs if we can't fully bypass due to clamp */ + foreach(ShaderInput *other, node->inputs) { + if(other != input && other->link) { + graph->disconnect(other); + } + } + } return false; } diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp index 625dd3ded39..93d88c5642c 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -224,6 +224,10 @@ void LightManager::disable_ineffective_light(Device *device, Scene *scene) bool LightManager::object_usable_as_light(Object *object) { Mesh *mesh = object->mesh; + /* Skip objects with NaNs */ + if (!object->bounds.valid()) { + return false; + } /* Skip if we are not visible for BSDFs. */ if(!(object->visibility & (PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY|PATH_RAY_TRANSMIT))) { return false; diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 57b475e5cd0..166156f7ac3 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -2308,13 +2308,13 @@ NODE_DEFINE(PrincipledBsdfNode) SOCKET_IN_FLOAT(subsurface, "Subsurface", 0.0f); SOCKET_IN_VECTOR(subsurface_radius, "Subsurface Radius", make_float3(0.1f, 0.1f, 0.1f)); SOCKET_IN_FLOAT(specular, "Specular", 0.0f); - SOCKET_IN_FLOAT(roughness, "Roughness", 0.0f); + SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f); SOCKET_IN_FLOAT(specular_tint, "Specular Tint", 0.0f); SOCKET_IN_FLOAT(anisotropic, "Anisotropic", 0.0f); SOCKET_IN_FLOAT(sheen, "Sheen", 0.0f); SOCKET_IN_FLOAT(sheen_tint, "Sheen Tint", 0.0f); SOCKET_IN_FLOAT(clearcoat, "Clearcoat", 0.0f); - SOCKET_IN_FLOAT(clearcoat_gloss, "Clearcoat Gloss", 0.0f); + SOCKET_IN_FLOAT(clearcoat_roughness, "Clearcoat Roughness", 0.03f); SOCKET_IN_FLOAT(ior, "IOR", 0.0f); SOCKET_IN_FLOAT(transmission, "Transmission", 0.0f); SOCKET_IN_FLOAT(transmission_roughness, "Transmission Roughness", 0.0f); @@ -2351,7 +2351,7 @@ void PrincipledBsdfNode::attributes(Shader *shader, AttributeRequestSet *attribu void PrincipledBsdfNode::compile(SVMCompiler& compiler, ShaderInput *p_metallic, ShaderInput *p_subsurface, ShaderInput *p_subsurface_radius, ShaderInput *p_specular, ShaderInput *p_roughness, ShaderInput *p_specular_tint, ShaderInput *p_anisotropic, - ShaderInput *p_sheen, ShaderInput *p_sheen_tint, ShaderInput *p_clearcoat, ShaderInput *p_clearcoat_gloss, + ShaderInput *p_sheen, ShaderInput *p_sheen_tint, ShaderInput *p_clearcoat, ShaderInput *p_clearcoat_roughness, ShaderInput *p_ior, ShaderInput *p_transmission, ShaderInput *p_anisotropic_rotation, ShaderInput *p_transmission_roughness) { ShaderInput *base_color_in = input("Base Color"); @@ -2374,7 +2374,7 @@ void PrincipledBsdfNode::compile(SVMCompiler& compiler, ShaderInput *p_metallic, int sheen_offset = compiler.stack_assign(p_sheen); int sheen_tint_offset = compiler.stack_assign(p_sheen_tint); int clearcoat_offset = compiler.stack_assign(p_clearcoat); - int clearcoat_gloss_offset = compiler.stack_assign(p_clearcoat_gloss); + int clearcoat_roughness_offset = compiler.stack_assign(p_clearcoat_roughness); int ior_offset = compiler.stack_assign(p_ior); int transmission_offset = compiler.stack_assign(p_transmission); int transmission_roughness_offset = compiler.stack_assign(p_transmission_roughness); @@ -2391,7 +2391,7 @@ void PrincipledBsdfNode::compile(SVMCompiler& compiler, ShaderInput *p_metallic, compiler.add_node(normal_offset, tangent_offset, compiler.encode_uchar4(specular_offset, roughness_offset, specular_tint_offset, anisotropic_offset), - compiler.encode_uchar4(sheen_offset, sheen_tint_offset, clearcoat_offset, clearcoat_gloss_offset)); + compiler.encode_uchar4(sheen_offset, sheen_tint_offset, clearcoat_offset, clearcoat_roughness_offset)); compiler.add_node(compiler.encode_uchar4(ior_offset, transmission_offset, anisotropic_rotation_offset, transmission_roughness_offset), distribution, SVM_STACK_INVALID, SVM_STACK_INVALID); @@ -2419,7 +2419,7 @@ void PrincipledBsdfNode::compile(SVMCompiler& compiler) { compile(compiler, input("Metallic"), input("Subsurface"), input("Subsurface Radius"), input("Specular"), input("Roughness"), input("Specular Tint"), input("Anisotropic"), input("Sheen"), input("Sheen Tint"), - input("Clearcoat"), input("Clearcoat Gloss"), input("IOR"), input("Transmission"), + input("Clearcoat"), input("Clearcoat Roughness"), input("IOR"), input("Transmission"), input("Anisotropic Rotation"), input("Transmission Roughness")); } diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index aac6ce2f375..c6ab47fcc84 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -252,6 +252,7 @@ public: class PointDensityTextureNode : public ShaderNode { public: SHADER_NODE_NO_CLONE_CLASS(PointDensityTextureNode) + virtual int get_group() { return NODE_GROUP_LEVEL_3; } ~PointDensityTextureNode(); ShaderNode *clone() const; @@ -377,13 +378,13 @@ public: bool has_bssrdf_bump(); void compile(SVMCompiler& compiler, ShaderInput *metallic, ShaderInput *subsurface, ShaderInput *subsurface_radius, ShaderInput *specular, ShaderInput *roughness, ShaderInput *specular_tint, ShaderInput *anisotropic, - ShaderInput *sheen, ShaderInput *sheen_tint, ShaderInput *clearcoat, ShaderInput *clearcoat_gloss, + ShaderInput *sheen, ShaderInput *sheen_tint, ShaderInput *clearcoat, ShaderInput *clearcoat_roughness, ShaderInput *ior, ShaderInput *transmission, ShaderInput *anisotropic_rotation, ShaderInput *transmission_roughness); float3 base_color; float3 subsurface_color, subsurface_radius; float metallic, subsurface, specular, roughness, specular_tint, anisotropic, - sheen, sheen_tint, clearcoat, clearcoat_gloss, ior, transmission, + sheen, sheen_tint, clearcoat, clearcoat_roughness, ior, transmission, anisotropic_rotation, transmission_roughness; float3 normal, clearcoat_normal, tangent; float surface_mix_weight; diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp index 6bff29d1c76..a794f233718 100644 --- a/intern/cycles/render/osl.cpp +++ b/intern/cycles/render/osl.cpp @@ -156,6 +156,7 @@ void OSLShaderManager::device_free(Device *device, DeviceScene *dscene, Scene *s og->surface_state.clear(); og->volume_state.clear(); og->displacement_state.clear(); + og->bump_state.clear(); og->background_state.reset(); } diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index 08909943c49..ae462a1084a 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -722,6 +722,7 @@ DeviceRequestedFeatures Session::get_requested_device_features() requested_features.use_baking = bake_manager->get_baking(); requested_features.use_integrator_branched = (scene->integrator->method == Integrator::BRANCHED_PATH); requested_features.use_transparent &= scene->integrator->transparent_shadows; + requested_features.use_denoising = params.use_denoising; return requested_features; } diff --git a/intern/cycles/test/util_string_test.cpp b/intern/cycles/test/util_string_test.cpp index 22ec8e0ee8e..6c059ba5d12 100644 --- a/intern/cycles/test/util_string_test.cpp +++ b/intern/cycles/test/util_string_test.cpp @@ -245,4 +245,41 @@ TEST(util_string_remove_trademark, both) EXPECT_EQ(str, "foo bar zzz"); } +TEST(util_string_remove_trademark, both_space) +{ + string str = string_remove_trademark("foo bar(TM) (R) zzz"); + EXPECT_EQ(str, "foo bar zzz"); +} + +TEST(util_string_remove_trademark, both_space_around) +{ + string str = string_remove_trademark("foo bar (TM) (R) zzz"); + EXPECT_EQ(str, "foo bar zzz"); +} + +TEST(util_string_remove_trademark, trademark_space_suffix) +{ + string str = string_remove_trademark("foo bar (TM)"); + EXPECT_EQ(str, "foo bar"); +} + +TEST(util_string_remove_trademark, trademark_space_middle) +{ + string str = string_remove_trademark("foo bar (TM) baz"); + EXPECT_EQ(str, "foo bar baz"); +} + + +TEST(util_string_remove_trademark, r_space_suffix) +{ + string str = string_remove_trademark("foo bar (R)"); + EXPECT_EQ(str, "foo bar"); +} + +TEST(util_string_remove_trademark, r_space_middle) +{ + string str = string_remove_trademark("foo bar (R) baz"); + EXPECT_EQ(str, "foo bar baz"); +} + CCL_NAMESPACE_END diff --git a/intern/cycles/util/util_atomic.h b/intern/cycles/util/util_atomic.h index 6c52117ef9a..643af87a65f 100644 --- a/intern/cycles/util/util_atomic.h +++ b/intern/cycles/util/util_atomic.h @@ -35,6 +35,7 @@ ATOMIC_INLINE void atomic_update_max_z(size_t *maximum_value, size_t value) #define atomic_add_and_fetch_float(p, x) atomic_add_and_fetch_fl((p), (x)) #define atomic_fetch_and_inc_uint32(p) atomic_fetch_and_add_uint32((p), 1) +#define atomic_fetch_and_dec_uint32(p) atomic_fetch_and_add_uint32((p), -1) #define CCL_LOCAL_MEM_FENCE 0 #define ccl_barrier(flags) (void)0 @@ -68,6 +69,7 @@ ccl_device_inline float atomic_add_and_fetch_float(volatile ccl_global float *so #define atomic_fetch_and_add_uint32(p, x) atomic_add((p), (x)) #define atomic_fetch_and_inc_uint32(p) atomic_inc((p)) +#define atomic_fetch_and_dec_uint32(p) atomic_dec((p)) #define CCL_LOCAL_MEM_FENCE CLK_LOCAL_MEM_FENCE #define ccl_barrier(flags) barrier(flags) @@ -79,7 +81,9 @@ ccl_device_inline float atomic_add_and_fetch_float(volatile ccl_global float *so #define atomic_add_and_fetch_float(p, x) (atomicAdd((float*)(p), (float)(x)) + (float)(x)) #define atomic_fetch_and_add_uint32(p, x) atomicAdd((unsigned int*)(p), (unsigned int)(x)) +#define atomic_fetch_and_sub_uint32(p, x) atomicSub((unsigned int*)(p), (unsigned int)(x)) #define atomic_fetch_and_inc_uint32(p) atomic_fetch_and_add_uint32((p), 1) +#define atomic_fetch_and_dec_uint32(p) atomic_fetch_and_sub_uint32((p), 1) #define CCL_LOCAL_MEM_FENCE #define ccl_barrier(flags) __syncthreads() diff --git a/intern/cycles/util/util_debug.cpp b/intern/cycles/util/util_debug.cpp index ab038d2b9fb..10895f2e918 100644 --- a/intern/cycles/util/util_debug.cpp +++ b/intern/cycles/util/util_debug.cpp @@ -184,8 +184,8 @@ std::ostream& operator <<(std::ostream &os, << " Device type : " << opencl_device_type << "\n" << " Kernel type : " << opencl_kernel_type << "\n" << " Debug : " << string_from_bool(debug_flags.opencl.debug) << "\n" - << " Single program : " << string_from_bool(debug_flags.opencl.single_program) - << "\n"; + << " Single program : " << string_from_bool(debug_flags.opencl.single_program) << "\n" + << " Memory limit : " << string_human_readable_size(debug_flags.opencl.mem_limit) << "\n"; return os; } diff --git a/intern/cycles/util/util_debug.h b/intern/cycles/util/util_debug.h index 4505d584490..450cd900a9f 100644 --- a/intern/cycles/util/util_debug.h +++ b/intern/cycles/util/util_debug.h @@ -115,6 +115,10 @@ public: /* Use single program */ bool single_program; + + /* TODO(mai): Currently this is only for OpenCL, but we should have it implemented for all devices. */ + /* Artificial memory limit in bytes (0 if disabled). */ + size_t mem_limit; }; /* Get instance of debug flags registry. */ diff --git a/intern/cycles/util/util_logging.h b/intern/cycles/util/util_logging.h index ecf9c9cfee0..492f830e67c 100644 --- a/intern/cycles/util/util_logging.h +++ b/intern/cycles/util/util_logging.h @@ -19,28 +19,30 @@ #if defined(WITH_CYCLES_LOGGING) && !defined(__KERNEL_GPU__) # include <glog/logging.h> -#else -# include <iostream> #endif +#include <iostream> + CCL_NAMESPACE_BEGIN #if !defined(WITH_CYCLES_LOGGING) || defined(__KERNEL_GPU__) -class StubStream : public std::ostream { - public: - StubStream() : std::ostream(NULL) { } +class StubStream { +public: + template<class T> + StubStream& operator<<(const T&) { + return *this; + } }; class LogMessageVoidify { public: LogMessageVoidify() { } - void operator&(::std::ostream&) { } + void operator&(StubStream&) { } }; # define LOG_SUPPRESS() (true) ? (void) 0 : LogMessageVoidify() & StubStream() # define LOG(severity) LOG_SUPPRESS() # define VLOG(severity) LOG_SUPPRESS() - #endif #define VLOG_ONCE(level, flag) if(!flag) flag = true, VLOG(level) diff --git a/intern/cycles/util/util_math_float3.h b/intern/cycles/util/util_math_float3.h index 5327d9f7cc6..bb04c4aa2d9 100644 --- a/intern/cycles/util/util_math_float3.h +++ b/intern/cycles/util/util_math_float3.h @@ -374,9 +374,9 @@ ccl_device_inline bool isfinite3_safe(float3 v) ccl_device_inline float3 ensure_finite3(float3 v) { - if(!isfinite_safe(v.x)) v.x = 0.0; - if(!isfinite_safe(v.y)) v.y = 0.0; - if(!isfinite_safe(v.z)) v.z = 0.0; + if(!isfinite_safe(v.x)) v.x = 0.0f; + if(!isfinite_safe(v.y)) v.y = 0.0f; + if(!isfinite_safe(v.z)) v.z = 0.0f; return v; } diff --git a/intern/cycles/util/util_progress.h b/intern/cycles/util/util_progress.h index bc672669e1f..cd4fe52fdc9 100644 --- a/intern/cycles/util/util_progress.h +++ b/intern/cycles/util/util_progress.h @@ -226,6 +226,7 @@ public: int get_current_sample() { + thread_scoped_lock lock(progress_mutex); /* Note that the value here always belongs to the last tile that updated, * so it's only useful if there is only one active tile. */ return current_tile_sample; @@ -233,11 +234,13 @@ public: int get_rendered_tiles() { + thread_scoped_lock lock(progress_mutex); return rendered_tiles; } int get_denoised_tiles() { + thread_scoped_lock lock(progress_mutex); return denoised_tiles; } diff --git a/intern/cycles/util/util_string.cpp b/intern/cycles/util/util_string.cpp index a1008d510d1..94ad512982c 100644 --- a/intern/cycles/util/util_string.cpp +++ b/intern/cycles/util/util_string.cpp @@ -148,6 +148,12 @@ void string_replace(string& haystack, const string& needle, const string& other) string string_remove_trademark(const string &s) { string result = s; + + /* Special case, so we don;t leave sequential spaces behind. */ + /* TODO(sergey): Consider using regex perhaps? */ + string_replace(result, " (TM)", ""); + string_replace(result, " (R)", ""); + string_replace(result, "(TM)", ""); string_replace(result, "(R)", ""); diff --git a/intern/elbeem/intern/isosurface.cpp b/intern/elbeem/intern/isosurface.cpp index fb61fb416b4..de7bfe8e687 100644 --- a/intern/elbeem/intern/isosurface.cpp +++ b/intern/elbeem/intern/isosurface.cpp @@ -15,6 +15,7 @@ #include "particletracer.h" #include <algorithm> #include <stdio.h> +#include <cmath> #ifdef sun #include "ieeefp.h" @@ -25,6 +26,8 @@ #define round(x) (x) #endif +using std::isfinite; + /****************************************************************************** * Constructor *****************************************************************************/ @@ -937,17 +940,10 @@ void IsoSurface::smoothSurface(float sigma, bool normSmooth) ew[(j+2)%3]); } - // NT important, check this... -#ifndef WIN32 - if(! finite(cornerareas[i][0]) ) cornerareas[i][0]=1e-6; - if(! finite(cornerareas[i][1]) ) cornerareas[i][1]=1e-6; - if(! finite(cornerareas[i][2]) ) cornerareas[i][2]=1e-6; -#else // WIN32 - // FIXME check as well... - if(! (cornerareas[i][0]>=0.0) ) cornerareas[i][0]=1e-6; - if(! (cornerareas[i][1]>=0.0) ) cornerareas[i][1]=1e-6; - if(! (cornerareas[i][2]>=0.0) ) cornerareas[i][2]=1e-6; -#endif // WIN32 + // FIX T50887: ensure pointareas are finite + if (!isfinite(cornerareas[i][0])) cornerareas[i][0] = 1e-6; + if (!isfinite(cornerareas[i][1])) cornerareas[i][1] = 1e-6; + if (!isfinite(cornerareas[i][2])) cornerareas[i][2] = 1e-6; pointareas[mIndices[i*3+0]] += cornerareas[i][0]; pointareas[mIndices[i*3+1]] += cornerareas[i][1]; @@ -1096,17 +1092,10 @@ void IsoSurface::smoothNormals(float sigma) { ew[(j+2)%3]); } - // NT important, check this... -#ifndef WIN32 - if(! finite(cornerareas[i][0]) ) cornerareas[i][0]=1e-6; - if(! finite(cornerareas[i][1]) ) cornerareas[i][1]=1e-6; - if(! finite(cornerareas[i][2]) ) cornerareas[i][2]=1e-6; -#else // WIN32 - // FIXME check as well... - if(! (cornerareas[i][0]>=0.0) ) cornerareas[i][0]=1e-6; - if(! (cornerareas[i][1]>=0.0) ) cornerareas[i][1]=1e-6; - if(! (cornerareas[i][2]>=0.0) ) cornerareas[i][2]=1e-6; -#endif // WIN32 + // FIX T50887: ensure pointareas are finite + if (!isfinite(cornerareas[i][0])) cornerareas[i][0] = 1e-6; + if (!isfinite(cornerareas[i][1])) cornerareas[i][1] = 1e-6; + if (!isfinite(cornerareas[i][2])) cornerareas[i][2] = 1e-6; pointareas[mIndices[i*3+0]] += cornerareas[i][0]; pointareas[mIndices[i*3+1]] += cornerareas[i][1]; diff --git a/intern/elbeem/intern/solver_util.cpp b/intern/elbeem/intern/solver_util.cpp index 6eca427c787..f0c7bce2b4e 100644 --- a/intern/elbeem/intern/solver_util.cpp +++ b/intern/elbeem/intern/solver_util.cpp @@ -855,6 +855,10 @@ void LbmFsgrSolver::advanceParticles() { if(k<=mSizez-1-cutval){ CellFlagType pflag = RFLAG(level, i,j,k, workSet); //errMsg("PIT move"," at "<<PRINT_IJK<<" flag"<<convertCellFlagType2String(pflag) ); + if (pflag & CFMbndOutflow) { + DEL_PART; + continue; + } if(pflag & (CFBnd)) { handleObstacleParticle(p); continue; diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h index 6887063eae9..967d3f58143 100644 --- a/intern/ghost/GHOST_C-api.h +++ b/intern/ghost/GHOST_C-api.h @@ -43,7 +43,7 @@ extern "C" { * Creates a "handle" for a C++ GHOST object. * A handle is just an opaque pointer to an empty struct. * In the API the pointer is casted to the actual C++ class. - * \param name Name of the handle to create. + * The 'name' argument to the macro is the name of the handle to create. */ GHOST_DECLARE_HANDLE(GHOST_SystemHandle); diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 9f03b5e9537..b0dae432643 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -941,6 +941,8 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, GHOST_ASSERT(system, "GHOST_SystemWin32::s_wndProc(): system not initialized"); if (hwnd) { +#if 0 + // Disabled due to bug in Intel drivers, see T51959 if(msg == WM_NCCREATE) { // Tell Windows to automatically handle scaling of non-client areas // such as the caption bar. EnableNonClientDpiScaling was introduced in Windows 10 @@ -954,6 +956,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, } } } +#endif GHOST_WindowWin32 *window = (GHOST_WindowWin32 *)::GetWindowLongPtr(hwnd, GWLP_USERDATA); if (window) { diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h index b234291396b..5168c48ca2f 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.h +++ b/intern/ghost/intern/GHOST_WindowCocoa.h @@ -56,7 +56,7 @@ public: * \param systemCocoa The associated system class to forward events to * \param title The text shown in the title bar of the window. * \param left The coordinate of the left edge of the window. - * \param top The coordinate of the top edge of the window. + * \param bottom The coordinate of the bottom edge of the window. * \param width The width the window. * \param height The height the window. * \param state The state the window is initially opened with. diff --git a/intern/guardedalloc/intern/mallocn_lockfree_impl.c b/intern/guardedalloc/intern/mallocn_lockfree_impl.c index ce8a5b29ece..b4838cdca18 100644 --- a/intern/guardedalloc/intern/mallocn_lockfree_impl.c +++ b/intern/guardedalloc/intern/mallocn_lockfree_impl.c @@ -64,9 +64,9 @@ enum { MEMHEAD_ALIGN_FLAG = 2, }; -#define MEMHEAD_FROM_PTR(ptr) (((MemHead*) vmemh) - 1) +#define MEMHEAD_FROM_PTR(ptr) (((MemHead*) ptr) - 1) #define PTR_FROM_MEMHEAD(memhead) (memhead + 1) -#define MEMHEAD_ALIGNED_FROM_PTR(ptr) (((MemHeadAligned*) vmemh) - 1) +#define MEMHEAD_ALIGNED_FROM_PTR(ptr) (((MemHeadAligned*) ptr) - 1) #define MEMHEAD_IS_MMAP(memhead) ((memhead)->len & (size_t) MEMHEAD_MMAP_FLAG) #define MEMHEAD_IS_ALIGNED(memhead) ((memhead)->len & (size_t) MEMHEAD_ALIGN_FLAG) diff --git a/intern/libmv/ChangeLog b/intern/libmv/ChangeLog index 45be9c25afa..81096dd90c9 100644 --- a/intern/libmv/ChangeLog +++ b/intern/libmv/ChangeLog @@ -1,3 +1,156 @@ +commit efd7a93317e0278b99e66785f667823e451daef1 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Tue May 9 10:16:42 2017 +0200 + + Fix strict compiler warnings, unused variables + +commit 8efd47e13dfdd3f7209bc96f26d0b13127dd6376 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Wed Dec 14 10:44:57 2016 +0100 + + Fix T50243: libmv_panography_test is broken + + There was fully wrong logic in comparison: was actually accessing memory + past the array boundary. Run test manually and the figure seems correct + to me now. + + Spotted by @LazyDodo, thanks! + +commit 6dfb9cd1bd14669d84be789000ce234747fb00ff +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Thu Jul 14 11:49:38 2016 +0200 + + Fix some strict compiler warnings + + One of them was a real bug! + +commit f61adaecf7b29ebe6677be0e1c825f0a8d475e4b +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Wed May 31 11:22:34 2017 +0200 + + Enable explicit schur complement for BA step + + This is something we do in Blender and only reason it was not + enabled for standalone Libmv is because we did not have fresh + enough version of Ceres bundled. + +commit fc5d3a1d4880c6658aff693c1c1e8c10c96ce1a7 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Wed Nov 2 15:32:11 2016 +0100 + + Update tests to make tests pass after recent Ceres update + + Just a precision issue, difference is around 1e-7. Should be fine to + simply update expected value. + +commit e1ac9f6124110c1a90d8e417bea47acfcbdcca42 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Wed May 31 10:54:48 2017 +0200 + + Update Ceres to latest release 1.12.0 + +commit ac1571352b4962f110929b963f8616d7310ceea5 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Fri Apr 7 17:10:44 2017 +0200 + + Fix crash of keyframe selection on 32bit linux + +commit 5f8df3da965686df39a6ae5c9f17482075017bf4 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Tue Jan 19 14:00:53 2016 +0500 + + Solve some strict warnings in tests + +commit 8ea3a5d752a9ce3337ab7643897472a4d33747f1 +Author: Brecht Van Lommel <brechtvanlommel@gmail.com> +Date: Sat Feb 18 23:52:31 2017 +0100 + + Fix a few compiler warnings with macOS / clang. + +commit ffbe81461770e70736e80b8cab8e6eb1f8b27160 +Author: Mike Erwin <significant.bit@gmail.com> +Date: Wed May 31 10:43:08 2017 +0200 + + Fix comparison of identicals + + Some of these check that dimensions match before running code that + assumes they do match. + + Found with PVS-Studio T48917. + +commit 206c01999cde16c1c6c43a8e13ffa86020821d98 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Wed May 31 10:39:16 2017 +0200 + + Add basic track masking API in place + + This brings back ability to mask non-interesting parts of + specific track (the feature got lost with new auto-track API). + + Added it back by extending frame accessor class. This isn't really + a frame thing, but we don't have other type of accessor here. + + Surely, we can use old-style API here and pass mask via region + tracker options for this particular case, but then it becomes much + less obvious how real auto-tracker will access this mask with old + style API. + + So seems we do need an accessor for such data, just matter of + finding better place than frame accessor. + +commit faa069cb826892780356477cc10602390fecf06b +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Wed May 31 10:36:26 2017 +0200 + + Tests: Tweak epsilon to avoid what looks a false-positive failure + +commit 7c84e45c1d330871477ba3516f57178e5b9d101f +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Wed May 31 10:15:43 2017 +0200 + + CMake: Fix mistake in closing branch + +commit cb769a0d319a8c95948153d78a4c3378a0142ece +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Thu Jul 21 12:52:33 2016 +0200 + + Set of fixes for MSVC215 + + - Move GLOG/GFLAGS defines to a more global scope, + this way ANY of our own libraries will use proper + declspec. + + - Compile png/zlib/openexif on Windows as well since + those are required for a correct linking. + +commit bb95c8654fd2cea72d66ed04cd825cc3712ea804 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Wed Jul 20 18:14:46 2016 +0200 + + Disable unexisting Ceres option + + Explicit Schur complement requires having + newer Ceres than we currently have bundled. + +commit a2e12c959ef32cc9382244d1581992c2f7aa9c09 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Wed Jul 20 18:04:57 2016 +0200 + + Various fixes for MSVC + + - Update Eigen to 3.2.7 since this brings crucial + fixes for MSVC 2015. + + - Switch to STATIC build by default. + + There are issues building current sources as dynamic + libraries with MSVC2015 and additionally building + dynamic Ceres is not recommended anyway, so let's + not do this for the time being. + + If anyone finds a way to make this all working -- + it'llsurely be a welcome addition. + commit 7a676106720fb126a27ff010abdd8bb65d7e0d9a Author: Sergey Sharybin <sergey.vfx@gmail.com> Date: Mon Jan 4 18:30:12 2016 +0500 @@ -365,239 +518,3 @@ Date: Thu May 8 15:50:26 2014 +0200 Reviewed By: sergey Differential Revision: https://developer.blender.org/D516 - -commit 4405dff60ea08d454b64da1a7c0595d9328cf8a3 -Author: Keir Mierle <mierle@gmail.com> -Date: Thu May 8 15:38:14 2014 +0200 - - Add public SetMarkers to AutoTrack - - Reviewers: sergey - - Reviewed By: sergey - - Differential Revision: https://developer.blender.org/D515 - -commit c90837f6db276a3b1f610eaad509155f6a43b24f -Author: Keir Mierle <mierle@gmail.com> -Date: Thu May 8 15:17:48 2014 +0200 - - Make autotrack skeleton compile - - Reviewers: sergey - - Reviewed By: sergey - - Differential Revision: https://developer.blender.org/D514 - -commit be01baa2e82e36f63e548f073157e68d2ff870c0 -Author: Keir Mierle <mierle@gmail.com> -Date: Wed May 7 18:48:55 2014 +0200 - - Add preliminary TrackMarkerToFrame in autotrack - - Reviewers: sergey - - Reviewed By: sergey - - Differential Revision: https://developer.blender.org/D509 - -commit 0cab028d591b3d08672ca86eb6c6e4ac1aacf1d0 -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Wed May 7 17:59:11 2014 +0200 - - Remove assert from ArrayND Resize - - That assert broke initialization of arrays which doesn't - own the data since constructor uses Resize to set shape - and strides. - - Strides are still to be fixed, but that's for later. - -commit 64f9c118029a9351e9023e96527c120e1d724d5b -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Wed May 7 17:42:21 2014 +0200 - - Fix ArrayND freeing the data it doesn't own - - Can't really guarantee it works fully correct now, - but at least this check is needed anyway and compilation - works just fine. - - Reviewers: keir - - Reviewed By: keir - - Differential Revision: https://developer.blender.org/D508 - -commit 0618f1c8e88dfc738cdde55784da80b889905e7c -Author: Keir Mierle <mierle@gmail.com> -Date: Wed May 7 12:03:32 2014 +0200 - - Minor changes - - Reviewers: sergey - - Reviewed By: sergey - - Differential Revision: https://developer.blender.org/D505 - -commit 5c34335e1bb90c4ed701ee830c718ed4e20dbffa -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Wed May 7 11:12:23 2014 +0200 - - Fix compilation error in frame accessor - - - int64 is not a standard type, we've got int64_t defined in - std int. We also have an msvc port of this header, so should - not be an issue. - - - Fixed inconsistency in usage of CacheKey and Key, used Key. - - - Some functions weren't marked as virtual. - - Additional change: added self to authors. - - Reviewers: keir - - Reviewed By: keir - - Differential Revision: https://developer.blender.org/D504 - -commit 06bc207614e262cd688e2c3ed820ade7c77bdb66 -Author: Keir Mierle <mierle@gmail.com> -Date: Tue May 6 22:30:59 2014 +0200 - - Start new Tracks implementation - - This adds the new Tracks implementation, as well as a - trivial test to show it compiles. - - Reviewers: sergey - - Reviewed By: sergey - - Differential Revision: https://developer.blender.org/D502 - -commit 25ce061e6da69881460ba7718bb0d660a2380a02 -Author: Keir Mierle <mierle@gmail.com> -Date: Tue May 6 19:10:51 2014 +0200 - - Add Reconstruction class for new API - - This starts the new Reconstruction class (with support for e.g. planes). This - also starts the new namespace "mv" which will eventually have all the symbols - we wish to export. - - Reviewers: sergey - - Reviewed By: sergey - - Differential Revision: https://developer.blender.org/D501 - -commit 0a6af3e29016048978aea607673340500e050339 -Author: Keir Mierle <mierle@gmail.com> -Date: Tue May 6 17:52:53 2014 +0200 - - Add a new Tracks implementation - - Reviewers: sergey - - Reviewed By: sergey - - Differential Revision: https://developer.blender.org/D500 - -commit 887b68d29c2b198f4939f9ab5153881aa2c1806e -Author: Keir Mierle <mierle@gmail.com> -Date: Tue May 6 17:01:39 2014 +0200 - - Initial commit of unfinished AutoTrack API - - This starts the creating the new AutoTrack API. The new API will - make it possible for libmv to do full autotracking, including - predictive tracking and also support multiple motion models (3D - planes etc). - - The first goal (not in this patch) is to convert Blender to use - the new API without adding any new functionality. - - Note: This does not add any of the API to the build system! - It likely does not compile. - - Reviewers: sergey - - Reviewed By: sergey - - Differential Revision: https://developer.blender.org/D499 - -commit 08cc227d431d257d27f300fbb8e6991e663302da -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Tue May 6 13:09:22 2014 +0200 - - Fix homography test failure - - It was caused by assuming that reconstructed homography matrix - should look exactly the same as the matrix used to generate a - test case. - - It's not actually valid assumption because different-looking - matrices could correspond to the same exact transform. - - In this change we make it so actual "re-projected" vectors - are being checked, not the values in matrix. This makes it - more predictable verification. - - Reviewers: keir - - Reviewed By: keir - - Differential Revision: https://developer.blender.org/D488 - -commit 0b7d83dc9627447dc7df64d7e3a468aefe9ddc13 -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Wed Apr 23 19:14:55 2014 +0600 - - Fix compilation on OSX after previous commit - - EXPECT_EQ wasn't defined in the scope. - -commit d14049e00dabf8fdf49056779f0a3718fbb39e8f -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Wed Apr 23 15:08:16 2014 +0600 - - Move aligned malloc implementation into own file - - It was rather stupid having it in brute region tracker, - now it is in own file in base library (which was also - added in this commit, before this it consist of header - files only). - - Reviewers: keir - - Reviewed By: keir - - Differential Revision: https://developer.blender.org/D479 - -commit 0ddf3851bfcb8de43660b119a25a77a25674200d -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Mon Apr 21 14:14:03 2014 +0600 - - Optimization of PearsonProductMomentCorrelation - - Pass the arrays by reference rather than by value, - should give some percent of speedup. - - Also don't pass the dimensions to the function but - get them from the images themselves. - - Hopefully this will give some %% of tracker speedup. - -commit f68fdbe5896a6c5bd8b500caeec61b876c5e44c6 -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Mon Apr 21 14:10:43 2014 +0600 - - Fix wrong assert in ResizeImage() - - The assert didn't make any sense because ComputeBoundingBox() - is intended to return bounding box in the following way: - (xmin, xmax, ymin, ymax). diff --git a/intern/libmv/bundle.sh b/intern/libmv/bundle.sh index 27e012f665f..d155d050782 100755 --- a/intern/libmv/bundle.sh +++ b/intern/libmv/bundle.sh @@ -120,6 +120,7 @@ if(WITH_LIBMV) add_definitions(\${GFLAGS_DEFINES}) add_definitions(\${GLOG_DEFINES}) add_definitions(\${CERES_DEFINES}) + add_definitions(-DLIBMV_GFLAGS_NAMESPACE=\${GFLAGS_NAMESPACE}) list(APPEND INC \${GFLAGS_INCLUDE_DIRS} diff --git a/intern/libmv/intern/track_region.cc b/intern/libmv/intern/track_region.cc index d395b6457d7..8989897e09f 100644 --- a/intern/libmv/intern/track_region.cc +++ b/intern/libmv/intern/track_region.cc @@ -36,7 +36,7 @@ /* define this to generate PNG images with content of search areas on every itteration of tracking */ -#define DUMP_ALWAYS +#undef DUMP_ALWAYS using libmv::FloatImage; using libmv::TrackRegionOptions; diff --git a/intern/memutil/MEM_CacheLimiterC-Api.h b/intern/memutil/MEM_CacheLimiterC-Api.h index 0fe5469a4d4..b5680890eb8 100644 --- a/intern/memutil/MEM_CacheLimiterC-Api.h +++ b/intern/memutil/MEM_CacheLimiterC-Api.h @@ -61,8 +61,8 @@ bool MEM_CacheLimiter_is_disabled(void); * Create new MEM_CacheLimiter object * managed objects are destructed with the data_destructor * - * @param data_destructor - * @return A new MEM_CacheLimter object + * \param data_destructor + * \return A new MEM_CacheLimter object */ MEM_CacheLimiterC *new_MEM_CacheLimiter(MEM_CacheLimiter_Destruct_Func data_destructor, @@ -73,7 +73,7 @@ MEM_CacheLimiterC *new_MEM_CacheLimiter(MEM_CacheLimiter_Destruct_Func data_dest * * Frees the memory of the CacheLimiter but does not touch managed objects! * - * @param This "This" pointer + * \param This "This" pointer */ void delete_MEM_CacheLimiter(MEM_CacheLimiterC *This); @@ -81,8 +81,8 @@ void delete_MEM_CacheLimiter(MEM_CacheLimiterC *This); /** * Manage object * - * @param This "This" pointer, data data object to manage - * @return CacheLimiterHandle to ref, unref, touch the managed object + * \param This "This" pointer, data data object to manage + * \return CacheLimiterHandle to ref, unref, touch the managed object */ MEM_CacheLimiterHandleC *MEM_CacheLimiter_insert(MEM_CacheLimiterC *This, void *data); @@ -90,7 +90,7 @@ MEM_CacheLimiterHandleC *MEM_CacheLimiter_insert(MEM_CacheLimiterC *This, void * /** * Free objects until memory constraints are satisfied * - * @param This "This" pointer + * \param This "This" pointer */ void MEM_CacheLimiter_enforce_limits(MEM_CacheLimiterC *This); @@ -99,7 +99,7 @@ void MEM_CacheLimiter_enforce_limits(MEM_CacheLimiterC *This); * Unmanage object previously inserted object. * Does _not_ delete managed object! * - * @param This "This" pointer, handle of object + * \param handle of object */ void MEM_CacheLimiter_unmanage(MEM_CacheLimiterHandleC *handle); @@ -108,7 +108,7 @@ void MEM_CacheLimiter_unmanage(MEM_CacheLimiterHandleC *handle); /** * Raise priority of object (put it at the tail of the deletion chain) * - * @param handle of object + * \param handle of object */ void MEM_CacheLimiter_touch(MEM_CacheLimiterHandleC *handle); @@ -117,7 +117,7 @@ void MEM_CacheLimiter_touch(MEM_CacheLimiterHandleC *handle); * Increment reference counter. Objects with reference counter != 0 are _not_ * deleted. * - * @param handle of object + * \param handle of object */ void MEM_CacheLimiter_ref(MEM_CacheLimiterHandleC *handle); @@ -126,7 +126,7 @@ void MEM_CacheLimiter_ref(MEM_CacheLimiterHandleC *handle); * Decrement reference counter. Objects with reference counter != 0 are _not_ * deleted. * - * @param handle of object + * \param handle of object */ void MEM_CacheLimiter_unref(MEM_CacheLimiterHandleC *handle); @@ -134,7 +134,7 @@ void MEM_CacheLimiter_unref(MEM_CacheLimiterHandleC *handle); /** * Get reference counter. * - * @param handle of object + * \param handle of object */ int MEM_CacheLimiter_get_refcount(MEM_CacheLimiterHandleC *handle); @@ -142,7 +142,7 @@ int MEM_CacheLimiter_get_refcount(MEM_CacheLimiterHandleC *handle); /** * Get pointer to managed object * - * @param handle of object + * \param handle of object */ void *MEM_CacheLimiter_get(MEM_CacheLimiterHandleC *handle); diff --git a/intern/opensubdiv/opensubdiv_capi.cc b/intern/opensubdiv/opensubdiv_capi.cc index 52ce98fe74b..91803551f12 100644 --- a/intern/opensubdiv/opensubdiv_capi.cc +++ b/intern/opensubdiv/opensubdiv_capi.cc @@ -33,6 +33,7 @@ #include <stdlib.h> #include <GL/glew.h> +#include <opensubdiv/version.h> #include <opensubdiv/osd/glMesh.h> /* CPU Backend */ @@ -381,3 +382,8 @@ int openSubdiv_supportGPUDisplay(void) (GLEW_ARB_texture_buffer_object || GLEW_EXT_texture_buffer_object))); /* also ARB_explicit_attrib_location? */ } + +int openSubdiv_getVersionHex(void) +{ + return OPENSUBDIV_VERSION_NUMBER; +} diff --git a/intern/opensubdiv/opensubdiv_capi.h b/intern/opensubdiv/opensubdiv_capi.h index c3a194813e6..281bd3f010d 100644 --- a/intern/opensubdiv/opensubdiv_capi.h +++ b/intern/opensubdiv/opensubdiv_capi.h @@ -152,6 +152,8 @@ void openSubdiv_init(bool gpu_legacy_support); void openSubdiv_cleanup(void); bool openSubdiv_gpu_legacy_support(void); +int openSubdiv_getVersionHex(void); + #ifdef __cplusplus } #endif diff --git a/release/datafiles/blender_icons.svg b/release/datafiles/blender_icons.svg index d88788fa904..a9c0fd431eb 100644 --- a/release/datafiles/blender_icons.svg +++ b/release/datafiles/blender_icons.svg @@ -31358,6 +31358,136 @@ fx="-0.78262758" fy="294.63174" r="6.6750002" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient33897" + id="radialGradient29130" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.6249996,2.7477764e-7,-3.1704883e-7,1.874986,-24.234082,-761.21063)" + cx="39.528847" + cy="871.2453" + fx="39.528847" + fy="871.2453" + r="2.0000005" /> + <linearGradient + inkscape:collect="always" + id="linearGradient33897"> + <stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="0" + id="stop33893" /> + <stop + style="stop-color:#ffffff;stop-opacity:0;" + offset="1" + id="stop33895" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient319-367" + id="linearGradient63713" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)" + x1="104.90227" + y1="53.227627" + x2="114.94328" + y2="60.73848" /> + <linearGradient + id="linearGradient319-367"> + <stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="0" + id="stop320-53" /> + <stop + style="stop-color:#ffffff;stop-opacity:0;" + offset="1" + id="stop321-562" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient319-367" + id="linearGradient63715" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(207,-246.99988)" + x1="-56.65625" + y1="342.03125" + x2="-53.1875" + y2="342.0625" /> + <linearGradient + id="linearGradient3043"> + <stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="0" + id="stop3045" /> + <stop + style="stop-color:#ffffff;stop-opacity:0;" + offset="1" + id="stop3047" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient319-367" + id="linearGradient63886" + x1="149.53125" + y1="95.781372" + x2="149.40625" + y2="103.12512" + gradientUnits="userSpaceOnUse" /> + <linearGradient + id="linearGradient3050"> + <stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="0" + id="stop3052" /> + <stop + style="stop-color:#ffffff;stop-opacity:0;" + offset="1" + id="stop3054" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient63892" + id="linearGradient63894" + x1="127.85783" + y1="115.03898" + x2="137.88899" + y2="121.44501" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + id="linearGradient63892"> + <stop + style="stop-color:#ba5d00;stop-opacity:1" + offset="0" + id="stop63888" /> + <stop + id="stop63896" + offset="0.5" + style="stop-color:#fa9a3a;stop-opacity:1" /> + <stop + style="stop-color:#ffffff;stop-opacity:1" + offset="1" + id="stop63890" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient319-367" + id="linearGradient63719" + gradientUnits="userSpaceOnUse" + x1="132" + y1="117.26753" + x2="142.72656" + y2="127.72736" /> + <linearGradient + id="linearGradient3062"> + <stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="0" + id="stop3064" /> + <stop + style="stop-color:#ffffff;stop-opacity:0;" + offset="1" + id="stop3066" /> + </linearGradient> </defs> <sodipodi:namedview id="base" @@ -92721,6 +92851,406 @@ style="display:inline;overflow:visible;visibility:visible;fill:none;stroke:#a8df84;stroke-width:2.93474906;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" id="path39834-2" inkscape:connector-curvature="0" /> + <g + id="g1418" + transform="matrix(1.6674711,0,0,1.6674711,-416.35106,-776.00982)" + style="display:inline;enable-background:new"> + <path + style="fill:none;stroke:#4b2f1e;stroke-width:2.75;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="path1374" + sodipodi:type="arc" + sodipodi:cx="41" + sodipodi:cy="873.36212" + sodipodi:rx="4.2499995" + sodipodi:ry="4.2499995" + sodipodi:start="6.1086524" + sodipodi:end="7.5049158" + sodipodi:open="true" + d="m 45.185432,872.62412 c 0.358149,2.03116 -0.793733,4.02628 -2.731847,4.73169" /> + <path + style="fill:none;stroke:#4b2f1e;stroke-width:2.75;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="path1376" + sodipodi:type="arc" + sodipodi:cx="41" + sodipodi:cy="873.36212" + sodipodi:rx="7" + sodipodi:ry="7" + sodipodi:start="4.4505896" + sodipodi:end="4.9741884" + sodipodi:open="true" + d="m 39.188267,866.60064 c 1.186888,-0.31802 2.436579,-0.31802 3.623467,0" /> + <path + d="m 47.76148,875.17385 c -0.318025,1.18689 -0.942871,2.26916 -1.811733,3.13802" + sodipodi:open="true" + sodipodi:end="0.78539816" + sodipodi:start="0.26179939" + sodipodi:ry="6.9999995" + sodipodi:rx="6.9999995" + sodipodi:cy="873.36212" + sodipodi:cx="41" + sodipodi:type="arc" + id="path1378" + style="fill:none;stroke:#4b2f1e;stroke-width:2.75;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" /> + <path + d="m 39.546414,877.35581 c -1.938113,-0.70541 -3.089995,-2.70053 -2.731846,-4.73169" + sodipodi:open="true" + sodipodi:end="3.3161256" + sodipodi:start="1.9198622" + sodipodi:ry="4.2499995" + sodipodi:rx="4.2499995" + sodipodi:cy="873.36212" + sodipodi:cx="41" + sodipodi:type="arc" + id="path1380" + style="fill:none;stroke:#4b2f1e;stroke-width:2.75;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" /> + <path + style="fill:none;stroke:#4b2f1e;stroke-width:2.75;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="path1382" + sodipodi:type="arc" + sodipodi:cx="41" + sodipodi:cy="873.36212" + sodipodi:rx="6.9999995" + sodipodi:ry="6.9999995" + sodipodi:start="2.3561945" + sodipodi:end="2.8797933" + sodipodi:open="true" + d="m 36.050253,878.31187 c -0.868862,-0.86886 -1.493708,-1.95113 -1.811733,-3.13802" /> + <rect + ry="2.75" + rx="2.75" + y="870.61212" + x="38.25" + height="5.5" + width="5.5000005" + id="rect1384" + style="fill:#4b2f1e;fill-opacity:1;fill-rule:nonzero;stroke:none" /> + <rect + style="fill:#000000;fill-opacity:0;fill-rule:nonzero;stroke:none" + id="rect1386" + width="20" + height="20" + x="31" + y="862.36212" + rx="0" + ry="0" /> + <rect + style="fill:#ff7d1f;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="rect1388" + width="4.0000005" + height="4" + x="39" + y="871.36212" + rx="2" + ry="2" /> + <rect + ry="1.5" + rx="1.5000004" + y="871.86212" + x="39.5" + height="3" + width="3.0000007" + id="rect1390" + style="fill:none;stroke:url(#radialGradient29130);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" /> + <path + style="fill:none;stroke:#ffb36b;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="path1392" + sodipodi:type="arc" + sodipodi:cx="41" + sodipodi:cy="873.36212" + sodipodi:rx="4.2499995" + sodipodi:ry="4.2499995" + sodipodi:start="1.9198622" + sodipodi:end="3.3161256" + sodipodi:open="true" + d="m 39.546414,877.35581 c -1.938113,-0.70541 -3.089995,-2.70053 -2.731846,-4.73169" /> + <path + d="m 36.050253,878.31187 c -0.868862,-0.86886 -1.493708,-1.95113 -1.811733,-3.13802" + sodipodi:open="true" + sodipodi:end="2.8797933" + sodipodi:start="2.3561945" + sodipodi:ry="6.9999995" + sodipodi:rx="6.9999995" + sodipodi:cy="873.36212" + sodipodi:cx="41" + sodipodi:type="arc" + id="path1394" + style="fill:none;stroke:#ffb36b;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" /> + <path + d="m 38.875,877.04273 c -0.321653,-0.18571 -0.617575,-0.41278 -0.880204,-0.6754" + sodipodi:open="true" + sodipodi:end="2.3561945" + sodipodi:start="2.0943951" + sodipodi:ry="4.2499995" + sodipodi:rx="4.2499995" + sodipodi:cy="873.36212" + sodipodi:cx="41" + sodipodi:type="arc" + id="path1396" + style="opacity:0.7;fill:none;stroke:#ff8919;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" /> + <path + style="opacity:0.7;fill:none;stroke:#ff8919;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="path1398" + sodipodi:type="arc" + sodipodi:cx="41" + sodipodi:cy="873.36212" + sodipodi:rx="6.9999995" + sodipodi:ry="6.9999995" + sodipodi:start="2.3561945" + sodipodi:end="2.6179939" + sodipodi:open="true" + d="m 36.050253,878.31187 c -0.432565,-0.43257 -0.806561,-0.91997 -1.11243,-1.44975" /> + <path + style="fill:none;stroke:#4b2f1e;stroke-width:2.75;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="path1400" + sodipodi:type="arc" + sodipodi:cx="-41" + sodipodi:cy="-873.36212" + sodipodi:rx="4.2500005" + sodipodi:ry="4.2500005" + sodipodi:start="0.87266463" + sodipodi:end="2.268928" + sodipodi:open="true" + d="m -38.268152,-870.10643 c -1.579966,1.32575 -3.88373,1.32575 -5.463696,0" + inkscape:transform-center-x="-2.2499995" + inkscape:transform-center-y="-2.25" + transform="scale(-1,-1)" /> + <path + d="m -38.268152,-870.10643 c -1.579966,1.32575 -3.88373,1.32575 -5.463696,0" + sodipodi:open="true" + sodipodi:end="2.268928" + sodipodi:start="0.87266463" + sodipodi:ry="4.2500005" + sodipodi:rx="4.2500005" + sodipodi:cy="-873.36212" + sodipodi:cx="-41" + sodipodi:type="arc" + id="path1402" + style="fill:none;stroke:#ffb36b;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + inkscape:transform-center-x="-2.2499995" + inkscape:transform-center-y="-2.25" + transform="scale(-1,-1)" /> + <path + style="fill:none;stroke:#ffb36b;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="path1404" + sodipodi:type="arc" + sodipodi:cx="-41" + sodipodi:cy="-873.36212" + sodipodi:rx="7.0000005" + sodipodi:ry="7.0000005" + sodipodi:start="1.3089969" + sodipodi:end="1.8325957" + sodipodi:open="true" + d="m -39.188266,-866.60064 c -1.186888,0.31803 -2.436579,0.31803 -3.623467,0" + inkscape:transform-center-y="-3.7500001" + transform="scale(-1,-1)" + inkscape:transform-center-x="-3.7499995" /> + <path + style="opacity:0.3;fill:none;stroke:#ffe4cb;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="path1406" + sodipodi:type="arc" + sodipodi:cx="41" + sodipodi:cy="873.36212" + sodipodi:rx="4.25" + sodipodi:ry="4.25" + sodipodi:start="4.0142573" + sodipodi:end="4.9741884" + sodipodi:open="true" + d="m 38.268153,870.10643 c 1.062216,-0.8913 2.492452,-1.20838 3.831828,-0.84949" /> + <path + d="m 39.188267,866.60064 c 1.186888,-0.31802 2.436579,-0.31802 3.623467,0" + sodipodi:open="true" + sodipodi:end="4.9741884" + sodipodi:start="4.4505896" + sodipodi:ry="7" + sodipodi:rx="7" + sodipodi:cy="873.36212" + sodipodi:cx="41" + sodipodi:type="arc" + id="path1408" + style="opacity:0.3;fill:none;stroke:#ffe4cb;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" /> + <path + style="opacity:0.6;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="path1410" + sodipodi:type="arc" + sodipodi:cx="41" + sodipodi:cy="873.36212" + sodipodi:rx="6.9999995" + sodipodi:ry="6.9999995" + sodipodi:start="4.4505896" + sodipodi:end="4.712389" + sodipodi:open="true" + d="M 39.188267,866.60064 C 39.779161,866.44231 40.388261,866.36212 41,866.36212" /> + <path + d="m 38.268153,870.10643 c 0.475408,-0.39891 1.032412,-0.68887 1.631866,-0.84949" + sodipodi:open="true" + sodipodi:end="4.4505896" + sodipodi:start="4.0142573" + sodipodi:ry="4.25" + sodipodi:rx="4.25" + sodipodi:cy="873.36212" + sodipodi:cx="41" + sodipodi:type="arc" + id="path1412" + style="opacity:0.6;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 + sodipodi:open="true" + style="fill:none;stroke:#ffb36b;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="path1414" + sodipodi:type="arc" + sodipodi:cx="41" + sodipodi:cy="873.36212" + sodipodi:rx="7" + sodipodi:ry="7" + sodipodi:start="0.26179939" + sodipodi:end="0.78539816" + d="m 47.761481,875.17385 c -0.318026,1.18689 -0.942871,2.26916 -1.811734,3.13802" /> + <path + d="m 45.185432,872.62412 c 0.358149,2.03116 -0.793733,4.02628 -2.731847,4.73169" + sodipodi:end="7.5049158" + sodipodi:start="6.1086524" + sodipodi:ry="4.2499995" + sodipodi:rx="4.2499995" + sodipodi:cy="873.36212" + sodipodi:cx="41" + sodipodi:type="arc" + id="path1416" + style="fill:none;stroke:#ffb36b;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + sodipodi:open="true" /> + </g> + <g + transform="matrix(1.6674711,0,0,1.6674711,-138.14039,-258.06137)" + style="display:inline;enable-background:new" + id="g63699"> + <path + inkscape:connector-curvature="0" + style="opacity:0.3;fill:none;stroke:#422200;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 -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 v 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 V 557 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 z" + id="path63697" /> + <g + id="g63687" + transform="translate(-252,462.99988)"> + <g + transform="translate(-179,199.50012)" + id="g63679"> + <path + inkscape:connector-curvature="0" + id="path63667" + d="m 328.5,-107.25 -4.5,1.75 v 6.5 l 4.5,2.25 4.5,-2.25 v -6.5 z" + style="fill:#422200;fill-opacity:1;fill-rule:evenodd;stroke:#422200;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" /> + <g + transform="translate(179,-179)" + id="g63671"> + <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:#915515;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 v -6.5 l -4.5,-1.75 v 10.5 z" + id="path63669" + sodipodi:nodetypes="ccccc" /> + </g> + <path + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccccc" + 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" + d="M 324,-99.00012 V -105.5 l 4.5,-1.75 0.5,0.25 v 10 l -0.5,0.25 z" + id="path63673" + inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png" + inkscape:export-xdpi="90" + inkscape:export-ydpi="90" /> + <path + inkscape:connector-curvature="0" + style="fill:none;stroke:url(#linearGradient63713);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 332.5,-105.5 v 6.25 l -4,2 -4,-2.00012 V -105.5" + id="path63675" + sodipodi:nodetypes="ccccc" /> + <path + inkscape:connector-curvature="0" + inkscape:export-ydpi="90" + inkscape:export-xdpi="90" + inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png" + sodipodi:nodetypes="ccccc" + style="fill:#f5ca9b;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 z" + id="path63677" /> + </g> + <path + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccc" + style="opacity:0.95999995;fill:none;stroke:url(#linearGradient63715);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="path63681" /> + <rect + style="opacity:0.25;fill:url(#linearGradient63886);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect63683" + width="1" + height="6.7500019" + x="149" + y="96.000122" /> + </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="rect63665" + width="16" + height="16" + x="-113" + y="554" /> + <g + style="display:inline;enable-background:new" + id="g63695" + transform="matrix(0.7882544,0,0,0.7883038,-210.45268,388.9974)" + inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png" + inkscape:export-xdpi="90" + inkscape:export-ydpi="90"> + <circle + sodipodi:ry="8" + sodipodi:rx="8" + sodipodi:cy="118" + sodipodi:cx="132" + r="8" + cy="118" + cx="132" + inkscape:export-ydpi="90" + inkscape:export-xdpi="90" + inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" + id="circle63689" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#422200;stroke-width:1.97436094;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + transform="matrix(0.6425292,0,0,0.642531,44.523834,146.81699)" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" /> + <circle + sodipodi:ry="8" + sodipodi:rx="8" + sodipodi:cy="118" + sodipodi:cx="132" + r="8" + cy="118" + cx="132" + style="opacity:0.8;fill:url(#linearGradient63894);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" + id="circle63691" + inkscape: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)" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" /> + <circle + sodipodi:ry="8" + sodipodi:rx="8" + sodipodi:cy="118" + sodipodi:cx="132" + r="8" + cy="118" + cx="132" + transform="matrix(0.4991181,0,0,0.4991107,63.460522,163.7471)" + style="opacity:0.5;fill:none;stroke:url(#linearGradient63719);stroke-width:2.54167628;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="circle63693" + inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" + inkscape:export-xdpi="90" + inkscape:export-ydpi="90" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.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> <path id="path39836-9" diff --git a/release/datafiles/blender_icons16/icon16_outliner_ob_force_field.dat b/release/datafiles/blender_icons16/icon16_outliner_ob_force_field.dat Binary files differnew file mode 100644 index 00000000000..59817bce4de --- /dev/null +++ b/release/datafiles/blender_icons16/icon16_outliner_ob_force_field.dat diff --git a/release/datafiles/blender_icons16/icon16_outliner_ob_group_instance.dat b/release/datafiles/blender_icons16/icon16_outliner_ob_group_instance.dat Binary files differnew file mode 100644 index 00000000000..072c049c941 --- /dev/null +++ b/release/datafiles/blender_icons16/icon16_outliner_ob_group_instance.dat diff --git a/release/datafiles/blender_icons32/icon32_outliner_ob_force_field.dat b/release/datafiles/blender_icons32/icon32_outliner_ob_force_field.dat Binary files differnew file mode 100644 index 00000000000..bd57178b377 --- /dev/null +++ b/release/datafiles/blender_icons32/icon32_outliner_ob_force_field.dat diff --git a/release/datafiles/blender_icons32/icon32_outliner_ob_group_instance.dat b/release/datafiles/blender_icons32/icon32_outliner_ob_group_instance.dat Binary files differnew file mode 100644 index 00000000000..868f9e4fbcc --- /dev/null +++ b/release/datafiles/blender_icons32/icon32_outliner_ob_group_instance.dat diff --git a/release/datafiles/colormanagement/config.ocio b/release/datafiles/colormanagement/config.ocio index 5bed23cf210..71223ea828e 100644 --- a/release/datafiles/colormanagement/config.ocio +++ b/release/datafiles/colormanagement/config.ocio @@ -304,7 +304,7 @@ colorspaces: equalitygroup: bitdepth: 32f description: | - Log based filmic shaper with 16.5 stops of latitude, and 25 stops of dynamic range. + Log based filmic shaper with 16.5 stops of latitude, and 25 stops of dynamic range isdata: false allocation: lg2 allocationvars: [-12.473931188, 12.526068812] diff --git a/release/scripts/freestyle/modules/freestyle/__init__.py b/release/scripts/freestyle/modules/freestyle/__init__.py index d2795f65b6a..6f6b44224d8 100644 --- a/release/scripts/freestyle/modules/freestyle/__init__.py +++ b/release/scripts/freestyle/modules/freestyle/__init__.py @@ -19,17 +19,20 @@ """ This module provides data types of view map components (0D and 1D elements), base classes for defining line stylization rules -(predicates, functions, chaining iterators, and stroke shaders), as -well as helper functions for style module writing. +(predicates, functions, chaining iterators, and stroke shaders), +as well as helper functions for style module writing. Submodules: -* :mod:`freestyle.types` -* :mod:`freestyle.predicates` -* :mod:`freestyle.functions` -* :mod:`freestyle.chainingiterators` -* :mod:`freestyle.shaders` -* :mod:`freestyle.utils` +.. toctree:: + :maxdepth: 1 + + freestyle.types.rst + freestyle.predicates.rst + freestyle.functions.rst + freestyle.chainingiterators.rst + freestyle.shaders.rst + freestyle.utils.rst """ diff --git a/release/scripts/modules/bl_i18n_utils/settings.py b/release/scripts/modules/bl_i18n_utils/settings.py index 07fc9f0c338..774ca5173d5 100644 --- a/release/scripts/modules/bl_i18n_utils/settings.py +++ b/release/scripts/modules/bl_i18n_utils/settings.py @@ -118,7 +118,7 @@ MSG_COMMENT_PREFIX = "#~ " MSG_CONTEXT_PREFIX = "MSGCTXT:" # The default comment prefix used in po's. -PO_COMMENT_PREFIX= "# " +PO_COMMENT_PREFIX = "# " # The comment prefix used to mark sources of msgids, in po's. PO_COMMENT_PREFIX_SOURCE = "#: " @@ -130,7 +130,7 @@ PO_COMMENT_PREFIX_SOURCE_CUSTOM = "#. :src: " PO_COMMENT_PREFIX_GENERATED = "#. " # The comment prefix used to comment entries in po's. -PO_COMMENT_PREFIX_MSG= "#~ " +PO_COMMENT_PREFIX_MSG = "#~ " # The comment prefix used to mark fuzzy msgids, in po's. PO_COMMENT_FUZZY = "#, fuzzy" diff --git a/release/scripts/modules/nodeitems_utils.py b/release/scripts/modules/nodeitems_utils.py index be6f031217c..904062c36cd 100644 --- a/release/scripts/modules/nodeitems_utils.py +++ b/release/scripts/modules/nodeitems_utils.py @@ -61,13 +61,19 @@ class NodeItem: # if no custom label is defined, fall back to the node type UI name return getattr(bpy.types, self.nodetype).bl_rna.name + @property + def translation_context(self): + if self._label: + return bpy.app.translations.contexts.default + else: + # if no custom label is defined, fall back to the node type UI name + return getattr(bpy.types, self.nodetype).bl_rna.translation_context + # NB: is a staticmethod because called with an explicit self argument # NodeItemCustom sets this as a variable attribute in __init__ @staticmethod def draw(self, layout, context): - default_context = bpy.app.translations.contexts.default - - props = layout.operator("node.add_node", text=self.label, text_ctxt=default_context) + props = layout.operator("node.add_node", text=self.label, text_ctxt=self.translation_context) props.type = self.nodetype props.use_transform = True diff --git a/release/scripts/modules/sys_info.py b/release/scripts/modules/sys_info.py index 5b81df28524..e447d8a4dc5 100644 --- a/release/scripts/modules/sys_info.py +++ b/release/scripts/modules/sys_info.py @@ -151,6 +151,13 @@ def write_sysinfo(filepath): else: output.write("Blender was built without Cycles support\n") + opensubdiv = bpy.app.opensubdiv + output.write("OpenSubdiv: ") + if opensubdiv.supported: + output.write("%s\n" % opensubdiv.version_string) + else: + output.write("Blender was built without OpenSubdiv support\n") + openvdb = bpy.app.openvdb output.write("OpenVDB: ") if openvdb.supported: diff --git a/release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_rigged.py b/release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_rigged.py index 7825a4d0f32..deb23d76d91 100644 --- a/release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_rigged.py +++ b/release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_rigged.py @@ -10,7 +10,7 @@ op.include_armatures = True op.include_shapekeys = False op.deform_bones_only = True op.active_uv_only = True -op.include_uv_textures = True +op.export_texture_type_selection = 'uv' op.use_texture_copies = True op.triangulate = True op.use_object_instantiation = False diff --git a/release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_static.py b/release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_static.py index 9e2efcaa727..ca9de8bf005 100644 --- a/release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_static.py +++ b/release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_static.py @@ -10,7 +10,7 @@ op.include_armatures = False op.include_shapekeys = False op.deform_bones_only = False op.active_uv_only = True -op.include_uv_textures = True +op.export_texture_type_selection = 'uv' op.use_texture_copies = True op.triangulate = True op.use_object_instantiation = False diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py index e52d577b900..d8ef9e1f3ef 100644 --- a/release/scripts/startup/bl_operators/clip.py +++ b/release/scripts/startup/bl_operators/clip.py @@ -782,8 +782,8 @@ class CLIP_OT_setup_tracking_scene(Operator): tree.links.new(mul_shadow.outputs["Image"], mul_image.inputs[2]) tree.links.new(rlayer_fg.outputs["Image"], vector_blur.inputs["Image"]) - tree.links.new(rlayer_fg.outputs["Z"], vector_blur.inputs["Z"]) - tree.links.new(rlayer_fg.outputs["Speed"], vector_blur.inputs["Speed"]) + tree.links.new(rlayer_fg.outputs["Depth"], vector_blur.inputs["Z"]) + tree.links.new(rlayer_fg.outputs["Vector"], vector_blur.inputs["Speed"]) tree.links.new(mul_image.outputs["Image"], alphaover.inputs[1]) tree.links.new(vector_blur.outputs["Image"], alphaover.inputs[2]) diff --git a/release/scripts/startup/bl_ui/properties_animviz.py b/release/scripts/startup/bl_ui/properties_animviz.py index 84bae18dd6f..43c01822b58 100644 --- a/release/scripts/startup/bl_ui/properties_animviz.py +++ b/release/scripts/startup/bl_ui/properties_animviz.py @@ -37,7 +37,7 @@ class MotionPathButtonsPanel: mps = avs.motion_path # Display Range - layout.prop(mps, "type", expand=True) + layout.row().prop(mps, "type", expand=True) split = layout.split() @@ -120,7 +120,7 @@ class OnionSkinButtonsPanel: arm = context.armature - layout.prop(arm, "ghost_type", expand=True) + layout.row().prop(arm, "ghost_type", expand=True) split = layout.split() diff --git a/release/scripts/startup/bl_ui/properties_data_armature.py b/release/scripts/startup/bl_ui/properties_data_armature.py index a2ecf984eb5..8d3ab24b4cf 100644 --- a/release/scripts/startup/bl_ui/properties_data_armature.py +++ b/release/scripts/startup/bl_ui/properties_data_armature.py @@ -57,7 +57,7 @@ class DATA_PT_skeleton(ArmatureButtonsPanel, Panel): arm = context.armature - layout.prop(arm, "pose_position", expand=True) + layout.row().prop(arm, "pose_position", expand=True) col = layout.column() col.label(text="Layers:") @@ -80,7 +80,7 @@ class DATA_PT_display(ArmatureButtonsPanel, Panel): ob = context.object arm = context.armature - layout.prop(arm, "draw_type", expand=True) + layout.row().prop(arm, "draw_type", expand=True) split = layout.split() @@ -215,7 +215,7 @@ class DATA_PT_ghost(ArmatureButtonsPanel, Panel): arm = context.armature - layout.prop(arm, "ghost_type", expand=True) + layout.row().prop(arm, "ghost_type", expand=True) split = layout.split() @@ -252,11 +252,11 @@ class DATA_PT_iksolver_itasc(ArmatureButtonsPanel, Panel): layout.prop(ob.pose, "ik_solver") if itasc: - layout.prop(itasc, "mode", expand=True) + layout.row().prop(itasc, "mode", expand=True) simulation = (itasc.mode == 'SIMULATION') if simulation: layout.label(text="Reiteration:") - layout.prop(itasc, "reiteration_method", expand=True) + layout.row().prop(itasc, "reiteration_method", expand=True) row = layout.row() row.active = not simulation or itasc.reiteration_method != 'NEVER' diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py index 101062095c4..14286045704 100644 --- a/release/scripts/startup/bl_ui/properties_data_camera.py +++ b/release/scripts/startup/bl_ui/properties_data_camera.py @@ -79,7 +79,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel): cam = context.camera - layout.prop(cam, "type", expand=True) + layout.row().prop(cam, "type", expand=True) split = layout.split() diff --git a/release/scripts/startup/bl_ui/properties_data_curve.py b/release/scripts/startup/bl_ui/properties_data_curve.py index ac1eb9505a6..3a3ad31a8ef 100644 --- a/release/scripts/startup/bl_ui/properties_data_curve.py +++ b/release/scripts/startup/bl_ui/properties_data_curve.py @@ -371,10 +371,10 @@ class DATA_PT_paragraph(CurveButtonsPanelText, Panel): text = context.curve layout.label(text="Horizontal Alignment:") - layout.prop(text, "align_x", expand=True) + layout.row().prop(text, "align_x", expand=True) layout.label(text="Vertical Alignment:") - layout.prop(text, "align_y", expand=True) + layout.row().prop(text, "align_y", expand=True) split = layout.split() diff --git a/release/scripts/startup/bl_ui/properties_data_lamp.py b/release/scripts/startup/bl_ui/properties_data_lamp.py index f913ef51381..98aa31ac915 100644 --- a/release/scripts/startup/bl_ui/properties_data_lamp.py +++ b/release/scripts/startup/bl_ui/properties_data_lamp.py @@ -83,7 +83,7 @@ class DATA_PT_lamp(DataButtonsPanel, Panel): lamp = context.lamp - layout.prop(lamp, "type", expand=True) + layout.row().prop(lamp, "type", expand=True) split = layout.split() @@ -210,7 +210,7 @@ class DATA_PT_shadow(DataButtonsPanel, Panel): lamp = context.lamp - layout.prop(lamp, "shadow_method", expand=True) + layout.row().prop(lamp, "shadow_method", expand=True) if lamp.shadow_method == 'NOSHADOW' and lamp.type == 'AREA': split = layout.split() diff --git a/release/scripts/startup/bl_ui/properties_data_metaball.py b/release/scripts/startup/bl_ui/properties_data_metaball.py index a621dc7210f..dd62c4523b1 100644 --- a/release/scripts/startup/bl_ui/properties_data_metaball.py +++ b/release/scripts/startup/bl_ui/properties_data_metaball.py @@ -70,7 +70,7 @@ class DATA_PT_metaball(DataButtonsPanel, Panel): col.prop(mball, "threshold", text="Threshold") layout.label(text="Update:") - layout.prop(mball, "update_method", expand=True) + layout.row().prop(mball, "update_method", expand=True) class DATA_PT_mball_texture_space(DataButtonsPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_game.py b/release/scripts/startup/bl_ui/properties_game.py index 46b34373aa5..636a9707ab9 100644 --- a/release/scripts/startup/bl_ui/properties_game.py +++ b/release/scripts/startup/bl_ui/properties_game.py @@ -343,7 +343,7 @@ class RENDER_PT_game_stereo(RenderButtonsPanel, Panel): stereo_mode = gs.stereo # stereo options: - layout.prop(gs, "stereo", expand=True) + layout.row().prop(gs, "stereo", expand=True) # stereo: if stereo_mode == 'STEREO': @@ -392,7 +392,7 @@ class RENDER_PT_game_shading(RenderButtonsPanel, Panel): gs = context.scene.game_settings - layout.prop(gs, "material_mode", expand=True) + layout.row().prop(gs, "material_mode", expand=True) if gs.material_mode == 'GLSL': split = layout.split() diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index 42e8d5272b3..52835a00796 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -233,7 +233,7 @@ class GreasePencilStrokeEditPanel: if is_3d_view: layout.separator() - + layout.separator() col = layout.column(align=True) @@ -884,9 +884,9 @@ class GreasePencilDataPanel: # Owner Selector if context.space_data.type == 'VIEW_3D': - layout.prop(context.tool_settings, "grease_pencil_source", expand=True) + layout.row().prop(context.tool_settings, "grease_pencil_source", expand=True) elif context.space_data.type == 'CLIP_EDITOR': - layout.prop(context.space_data, "grease_pencil_source", expand=True) + layout.row().prop(context.space_data, "grease_pencil_source", expand=True) # Grease Pencil data selector layout.template_ID(gpd_owner, "grease_pencil", new="gpencil.data_add", unlink="gpencil.data_unlink") @@ -963,7 +963,7 @@ class GreasePencilDataPanel: row.prop(gpl, "line_change", text="Thickness Change", slider=True) row.operator("gpencil.stroke_apply_thickness", icon='STYLUS_PRESSURE', text="") - # Parenting + # Parenting if context.space_data.type == 'VIEW_3D': col = split.column(align=True) col.label(text="Parent:") diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py index 06ae1847d06..73740df37e8 100644 --- a/release/scripts/startup/bl_ui/properties_material.py +++ b/release/scripts/startup/bl_ui/properties_material.py @@ -124,9 +124,10 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel, Panel): ob = context.object slot = context.material_slot space = context.space_data - is_sortable = (len(ob.material_slots) > 1) if ob: + is_sortable = (len(ob.material_slots) > 1) + rows = 1 if is_sortable: rows = 4 @@ -170,7 +171,7 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel, Panel): split.separator() if mat: - layout.prop(mat, "type", expand=True) + layout.row().prop(mat, "type", expand=True) if mat.use_nodes: row = layout.row() row.label(text="", icon='NODETREE') @@ -991,7 +992,7 @@ class MATERIAL_PT_volume_transp(VolumeButtonsPanel, Panel): mat = context.material # don't use node material - layout.prop(mat, "transparency_method", expand=True) + layout.row().prop(mat, "transparency_method", expand=True) class MATERIAL_PT_volume_integration(VolumeButtonsPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py index d7e18f81232..43c8300b558 100644 --- a/release/scripts/startup/bl_ui/properties_object.py +++ b/release/scripts/startup/bl_ui/properties_object.py @@ -294,7 +294,7 @@ class OBJECT_PT_duplication(ObjectButtonsPanel, Panel): ob = context.object - layout.prop(ob, "dupli_type", expand=True) + layout.row().prop(ob, "dupli_type", expand=True) if ob.dupli_type == 'FRAMES': split = layout.split() diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py index e86df975927..23e7c0a6787 100644 --- a/release/scripts/startup/bl_ui/properties_particle.py +++ b/release/scripts/startup/bl_ui/properties_particle.py @@ -284,7 +284,7 @@ class PARTICLE_PT_emission(ParticleButtonsPanel, Panel): col.prop(part, "lifetime_random", slider=True) layout.label(text="Emit From:") - layout.prop(part, "emit_from", expand=True) + layout.row().prop(part, "emit_from", expand=True) row = layout.row() if part.emit_from == 'VERT': @@ -297,7 +297,7 @@ class PARTICLE_PT_emission(ParticleButtonsPanel, Panel): row.prop(part, "use_even_distribution") if part.emit_from == 'FACE' or part.emit_from == 'VOLUME': - layout.prop(part, "distribution", expand=True) + layout.row().prop(part, "distribution", expand=True) row = layout.row() if part.distribution == 'JIT': @@ -578,7 +578,7 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel): layout.enabled = particle_panel_enabled(context, psys) - layout.prop(part, "physics_type", expand=True) + layout.row().prop(part, "physics_type", expand=True) row = layout.row() col = row.column(align=True) @@ -785,7 +785,7 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel): sub.prop(key, "object", text="") sub.prop(key, "system", text="System") - layout.prop(key, "alliance", expand=True) + layout.row().prop(key, "alliance", expand=True) elif part.physics_type == 'FLUID': sub = row.row() # doesn't work yet @@ -933,7 +933,7 @@ class PARTICLE_PT_render(ParticleButtonsPanel, Panel): col.prop(part, "show_unborn") col.prop(part, "use_dead") - layout.prop(part, "render_type", expand=True) + layout.row().prop(part, "render_type", expand=True) split = layout.split() diff --git a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py index c813350be08..cf1d4f38038 100644 --- a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py +++ b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py @@ -68,7 +68,7 @@ class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel): md = context.dynamic_paint - layout.prop(md, "ui_type", expand=True) + layout.row().prop(md, "ui_type", expand=True) if md.ui_type == 'CANVAS': canvas = md.canvas_settings @@ -363,7 +363,7 @@ class PHYSICS_PT_dp_effects(PhysicButtonsPanel, Panel): canvas = context.dynamic_paint.canvas_settings surface = canvas.canvas_surfaces.active - layout.prop(surface, "effect_ui", expand=True) + layout.row().prop(surface, "effect_ui", expand=True) if surface.effect_ui == 'SPREAD': layout.prop(surface, "use_spread") diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py index 2b12fcf982d..3fd47f0b8ca 100644 --- a/release/scripts/startup/bl_ui/properties_physics_field.py +++ b/release/scripts/startup/bl_ui/properties_physics_field.py @@ -128,7 +128,7 @@ class PHYSICS_PT_field(PhysicButtonsPanel, Panel): if field.type not in {'NONE', 'GUIDE'}: layout.label(text="Falloff:") - layout.prop(field, "falloff_type", expand=True) + layout.row().prop(field, "falloff_type", expand=True) basic_force_field_falloff_ui(self, context, field) diff --git a/release/scripts/startup/bl_ui/properties_physics_smoke.py b/release/scripts/startup/bl_ui/properties_physics_smoke.py index f2e6c1e22e3..4f0d3680834 100644 --- a/release/scripts/startup/bl_ui/properties_physics_smoke.py +++ b/release/scripts/startup/bl_ui/properties_physics_smoke.py @@ -52,7 +52,7 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel): md = context.smoke ob = context.object - layout.prop(md, "smoke_type", expand=True) + layout.row().prop(md, "smoke_type", expand=True) if md.smoke_type == 'DOMAIN': domain = md.domain_settings @@ -322,14 +322,14 @@ class PHYSICS_PT_smoke_cache(PhysicButtonsPanel, Panel): if cache_file_format == 'POINTCACHE': layout.label(text="Compression:") - layout.prop(domain, "point_cache_compress_type", expand=True) + layout.row().prop(domain, "point_cache_compress_type", expand=True) elif cache_file_format == 'OPENVDB': if not bpy.app.build_options.openvdb: layout.label("Built without OpenVDB support") return layout.label(text="Compression:") - layout.prop(domain, "openvdb_cache_compress_type", expand=True) + layout.row().prop(domain, "openvdb_cache_compress_type", expand=True) row = layout.row() row.label("Data Depth:") row.prop(domain, "data_depth", expand=True, text="Data Depth") diff --git a/release/scripts/startup/bl_ui/properties_physics_softbody.py b/release/scripts/startup/bl_ui/properties_physics_softbody.py index 5960428e4ae..5ce4302891d 100644 --- a/release/scripts/startup/bl_ui/properties_physics_softbody.py +++ b/release/scripts/startup/bl_ui/properties_physics_softbody.py @@ -191,7 +191,7 @@ class PHYSICS_PT_softbody_collision(PhysicButtonsPanel, Panel): layout.active = softbody.use_self_collision and softbody_panel_enabled(md) layout.label(text="Collision Ball Size Calculation:") - layout.prop(softbody, "collision_type", expand=True) + layout.row().prop(softbody, "collision_type", expand=True) col = layout.column(align=True) col.label(text="Ball:") diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py index d05527b7ef6..880684997bf 100644 --- a/release/scripts/startup/bl_ui/properties_texture.py +++ b/release/scripts/startup/bl_ui/properties_texture.py @@ -165,7 +165,7 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel, Panel): pin_id = None if not space.use_pin_id: - layout.prop(space, "texture_context", expand=True) + layout.row().prop(space, "texture_context", expand=True) pin_id = None if space.texture_context == 'OTHER': @@ -318,9 +318,9 @@ class TEXTURE_PT_clouds(TextureTypePanel, Panel): tex = context.texture - layout.prop(tex, "cloud_type", expand=True) + layout.row().prop(tex, "cloud_type", expand=True) layout.label(text="Noise:") - layout.prop(tex, "noise_type", text="Type", expand=True) + layout.row().prop(tex, "noise_type", text="Type", expand=True) layout.prop(tex, "noise_basis", text="Basis") split = layout.split() @@ -342,8 +342,8 @@ class TEXTURE_PT_wood(TextureTypePanel, Panel): tex = context.texture - layout.prop(tex, "noise_basis_2", expand=True) - layout.prop(tex, "wood_type", expand=True) + layout.row().prop(tex, "noise_basis_2", expand=True) + layout.row().prop(tex, "wood_type", expand=True) col = layout.column() col.active = tex.wood_type in {'RINGNOISE', 'BANDNOISE'} @@ -371,10 +371,10 @@ class TEXTURE_PT_marble(TextureTypePanel, Panel): tex = context.texture - layout.prop(tex, "marble_type", expand=True) - layout.prop(tex, "noise_basis_2", expand=True) + layout.row().prop(tex, "marble_type", expand=True) + layout.row().prop(tex, "noise_basis_2", expand=True) layout.label(text="Noise:") - layout.prop(tex, "noise_type", text="Type", expand=True) + layout.row().prop(tex, "noise_type", text="Type", expand=True) layout.prop(tex, "noise_basis", text="Basis") split = layout.split() @@ -431,9 +431,9 @@ class TEXTURE_PT_stucci(TextureTypePanel, Panel): tex = context.texture - layout.prop(tex, "stucci_type", expand=True) + layout.row().prop(tex, "stucci_type", expand=True) layout.label(text="Noise:") - layout.prop(tex, "noise_type", text="Type", expand=True) + layout.row().prop(tex, "noise_type", text="Type", expand=True) layout.prop(tex, "noise_basis", text="Basis") row = layout.row() @@ -808,7 +808,7 @@ class TEXTURE_PT_pointdensity(TextureButtonsPanel, Panel): tex = context.texture pd = tex.point_density - layout.prop(pd, "point_source", expand=True) + layout.row().prop(pd, "point_source", expand=True) split = layout.split() diff --git a/release/scripts/startup/bl_ui/properties_world.py b/release/scripts/startup/bl_ui/properties_world.py index 6aa39580d34..107c31567b3 100644 --- a/release/scripts/startup/bl_ui/properties_world.py +++ b/release/scripts/startup/bl_ui/properties_world.py @@ -175,7 +175,7 @@ class WORLD_PT_gather(WorldButtonsPanel, Panel): layout.active = light.use_ambient_occlusion or light.use_environment_light or light.use_indirect_light - layout.prop(light, "gather_method", expand=True) + layout.row().prop(light, "gather_method", expand=True) split = layout.split() diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index 6737b8e1089..79bb10cefeb 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -338,21 +338,21 @@ class SEQUENCER_MT_add(Menu): if len(bpy.data.scenes) > 10: layout.operator_context = 'INVOKE_DEFAULT' - layout.operator("sequencer.scene_strip_add", text="Scene") + layout.operator("sequencer.scene_strip_add", text="Scene...") else: - layout.operator_menu_enum("sequencer.scene_strip_add", "scene", text="Scene...") + layout.operator_menu_enum("sequencer.scene_strip_add", "scene", text="Scene") if len(bpy.data.movieclips) > 10: layout.operator_context = 'INVOKE_DEFAULT' - layout.operator("sequencer.movieclip_strip_add", text="Clips") + layout.operator("sequencer.movieclip_strip_add", text="Clips...") else: - layout.operator_menu_enum("sequencer.movieclip_strip_add", "clip", text="Clip...") + layout.operator_menu_enum("sequencer.movieclip_strip_add", "clip", text="Clip") if len(bpy.data.masks) > 10: layout.operator_context = 'INVOKE_DEFAULT' - layout.operator("sequencer.mask_strip_add", text="Masks") + layout.operator("sequencer.mask_strip_add", text="Masks...") else: - layout.operator_menu_enum("sequencer.mask_strip_add", "mask", text="Mask...") + layout.operator_menu_enum("sequencer.mask_strip_add", "mask", text="Mask") layout.operator("sequencer.movie_strip_add", text="Movie") layout.operator("sequencer.image_strip_add", text="Image") diff --git a/release/scripts/startup/bl_ui/space_time.py b/release/scripts/startup/bl_ui/space_time.py index b9a25cd72a0..9930992e9bb 100644 --- a/release/scripts/startup/bl_ui/space_time.py +++ b/release/scripts/startup/bl_ui/space_time.py @@ -250,7 +250,7 @@ def marker_menu_generic(layout): layout.operator_context = 'INVOKE_DEFAULT' layout.operator("marker.make_links_scene", text="Duplicate Marker to Scene...", icon='OUTLINER_OB_EMPTY') else: - layout.operator_menu_enum("marker.make_links_scene", "scene", text="Duplicate Marker to Scene...") + layout.operator_menu_enum("marker.make_links_scene", "scene", text="Duplicate Marker to Scene") layout.operator("marker.delete", text="Delete Marker") diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 5ed481a215a..03a40085172 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -80,7 +80,7 @@ class USERPREF_PT_tabs(Panel): userpref = context.user_preferences - layout.prop(userpref, "active_section", expand=True) + layout.row().prop(userpref, "active_section", expand=True) class USERPREF_MT_interaction_presets(Menu): @@ -127,7 +127,7 @@ class USERPREF_MT_app_templates(Menu): text=bpy.path.display_name(d), ) props.use_splash = True - props.app_template = d; + props.app_template = d if use_install: layout.separator() @@ -560,7 +560,7 @@ class USERPREF_PT_system(Panel): # 3. Column column = split.column() - column.label(text="Solid OpenGL lights:") + column.label(text="Solid OpenGL Lights:") split = column.split(percentage=0.1) split.label() diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 9245def7473..02c0f69ac82 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -1255,14 +1255,14 @@ class INFO_MT_add(Menu): layout.menu("INFO_MT_lamp_add", icon='OUTLINER_OB_LAMP') layout.separator() - layout.operator_menu_enum("object.effector_add", "type", text="Force Field", icon='OUTLINER_OB_EMPTY') + layout.operator_menu_enum("object.effector_add", "type", text="Force Field", icon='OUTLINER_OB_FORCE_FIELD') layout.separator() if len(bpy.data.groups) > 10: layout.operator_context = 'INVOKE_REGION_WIN' - layout.operator("object.group_instance_add", text="Group Instance...", icon='OUTLINER_OB_EMPTY') + layout.operator("object.group_instance_add", text="Group Instance...", icon='OUTLINER_OB_GROUP_INSTANCE') else: - layout.operator_menu_enum("object.group_instance_add", "group", text="Group Instance", icon='OUTLINER_OB_EMPTY') + layout.operator_menu_enum("object.group_instance_add", "group", text="Group Instance", icon='OUTLINER_OB_GROUP_INSTANCE') # ********** Object menu ********** @@ -1663,7 +1663,7 @@ class VIEW3D_MT_make_links(Menu): 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_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 @@ -3534,7 +3534,7 @@ class VIEW3D_PT_view3d_meshstatvis(Panel): row = layout.row(align=True) row.prop(statvis, "overhang_min", text="") row.prop(statvis, "overhang_max", text="") - layout.prop(statvis, "overhang_axis", expand=True) + layout.row().prop(statvis, "overhang_axis", expand=True) elif statvis_type == 'THICKNESS': row = layout.row(align=True) row.prop(statvis, "thickness_min", text="") diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index d58453deaef..2e291d3d471 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -967,9 +967,9 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel): col.prop(brush, "steps", slider=True) col.prop(settings, "default_key_count", slider=True) elif tool == 'LENGTH': - layout.prop(brush, "length_mode", expand=True) + layout.row().prop(brush, "length_mode", expand=True) elif tool == 'PUFF': - layout.prop(brush, "puff_mode", expand=True) + layout.row().prop(brush, "puff_mode", expand=True) layout.prop(brush, "use_puff_volume") # Sculpt Mode # diff --git a/release/scripts/startup/keyingsets_builtins.py b/release/scripts/startup/keyingsets_builtins.py index ce0b1b62d44..f62e3602bb9 100644 --- a/release/scripts/startup/keyingsets_builtins.py +++ b/release/scripts/startup/keyingsets_builtins.py @@ -643,26 +643,29 @@ class BUILTIN_KSI_DeltaScale(KeyingSetInfo): ############################### +# Note that this controls order of options in 'insert keyframe' menu. +# Better try to keep some logical order here beyond mere alphabetical one, also because of menu entries shortcut. +# See also T51867. classes = ( BUILTIN_KSI_Available, - BUILTIN_KSI_BendyBones, - BUILTIN_KSI_DeltaLocation, - BUILTIN_KSI_DeltaRotation, - BUILTIN_KSI_DeltaScale, + BUILTIN_KSI_Location, + BUILTIN_KSI_Rotation, + BUILTIN_KSI_Scaling, BUILTIN_KSI_LocRot, BUILTIN_KSI_LocRotScale, BUILTIN_KSI_LocScale, - BUILTIN_KSI_Location, BUILTIN_KSI_RotScale, - BUILTIN_KSI_Rotation, - BUILTIN_KSI_Scaling, + BUILTIN_KSI_DeltaLocation, + BUILTIN_KSI_DeltaRotation, + BUILTIN_KSI_DeltaScale, BUILTIN_KSI_VisualLoc, + BUILTIN_KSI_VisualRot, + BUILTIN_KSI_VisualScaling, BUILTIN_KSI_VisualLocRot, BUILTIN_KSI_VisualLocRotScale, BUILTIN_KSI_VisualLocScale, - BUILTIN_KSI_VisualRot, BUILTIN_KSI_VisualRotScale, - BUILTIN_KSI_VisualScaling, + BUILTIN_KSI_BendyBones, BUILTIN_KSI_WholeCharacter, BUILTIN_KSI_WholeCharacterSelected, ) diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc index 3da67ac0865..4fe65b96f36 100644 --- a/source/blender/alembic/intern/abc_exporter.cc +++ b/source/blender/alembic/intern/abc_exporter.cc @@ -131,13 +131,12 @@ static bool object_type_is_exportable(Object *ob) /** * Returns whether this object should be exported into the Alembic file. * - * @param settings export settings, used for options like 'selected only'. - * @param ob the object in question. - * @param is_duplicated normally false; true when the object is instanced - * into the scene by a dupli-object (e.g. part of a - * dupligroup). This ignores selection and layer - * visibility, and assumes that the dupli-object itself - * (e.g. the group-instantiating empty) is exported. + * \param settings: export settings, used for options like 'selected only'. + * \param ob: the object in question. + * \param is_duplicated: Normally false; true when the object is instanced + * into the scene by a dupli-object (e.g. part of a dupligroup). + * This ignores selection and layer visibility, + * and assumes that the dupli-object itself (e.g. the group-instantiating empty) is exported. */ static bool export_object(const ExportSettings * const settings, Object *ob, bool is_duplicated) @@ -428,7 +427,7 @@ AbcTransformWriter * AbcExporter::createTransformWriter(Object *ob, Object *pare /* check if we have already created a transform writer for this object */ AbcTransformWriter *my_writer = getXForm(name); - if (my_writer != NULL){ + if (my_writer != NULL) { return my_writer; } diff --git a/source/blender/alembic/intern/abc_object.h b/source/blender/alembic/intern/abc_object.h index 1462f93a422..cba79ffede5 100644 --- a/source/blender/alembic/intern/abc_object.h +++ b/source/blender/alembic/intern/abc_object.h @@ -90,7 +90,7 @@ struct ImportSettings { /* Length and frame offset of file sequences. */ int sequence_len; - int offset; + int sequence_offset; /* From MeshSeqCacheModifierData.read_flag */ int read_flag; @@ -107,7 +107,7 @@ struct ImportSettings { , is_sequence(false) , set_frame_range(false) , sequence_len(1) - , offset(0) + , sequence_offset(0) , read_flag(0) , validate_meshes(false) , cache_file(NULL) diff --git a/source/blender/alembic/intern/abc_util.cc b/source/blender/alembic/intern/abc_util.cc index 67d2d3b1eb2..26eb7620fb1 100644 --- a/source/blender/alembic/intern/abc_util.cc +++ b/source/blender/alembic/intern/abc_util.cc @@ -142,7 +142,7 @@ void create_swapped_rotation_matrix( float rz; /* Apply transformation */ - switch(mode) { + switch (mode) { case ABC_ZUP_FROM_YUP: ry = -euler[2]; rz = euler[1]; @@ -217,7 +217,7 @@ void copy_m44_axis_swap(float dst_mat[4][4], float src_mat[4][4], AbcAxisSwapMod copy_m4_m3(dst_mat, dst_rot); /* Apply translation */ - switch(mode) { + switch (mode) { case ABC_ZUP_FROM_YUP: copy_zup_from_yup(dst_mat[3], src_trans); break; diff --git a/source/blender/alembic/intern/abc_util.h b/source/blender/alembic/intern/abc_util.h index 74d0faf97d3..2526958111a 100644 --- a/source/blender/alembic/intern/abc_util.h +++ b/source/blender/alembic/intern/abc_util.h @@ -33,7 +33,7 @@ #endif /** - * @brief The CacheReader struct is only used for anonymous pointers, + * \brief The CacheReader struct is only used for anonymous pointers, * to interface between C and C++ code. This library only creates * pointers to AbcObjectReader (or subclasses thereof). */ diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc index 5ac73175e5b..83d971d00d9 100644 --- a/source/blender/alembic/intern/alembic_capi.cc +++ b/source/blender/alembic/intern/alembic_capi.cc @@ -452,7 +452,8 @@ static std::pair<bool, AbcObjectReader *> visit_object( else { if (child_claims_this_object) { claiming_child_readers.push_back(child_reader); - } else { + } + else { nonclaiming_child_readers.push_back(child_reader); } } @@ -742,7 +743,7 @@ static void import_startjob(void *user_data, short *stop, short *do_update, floa Scene *scene = data->scene; if (data->settings.is_sequence) { - SFRA = data->settings.offset; + SFRA = data->settings.sequence_offset; EFRA = SFRA + (data->settings.sequence_len - 1); CFRA = SFRA; } @@ -869,7 +870,7 @@ bool ABC_import(bContext *C, const char *filepath, float scale, bool is_sequence job->settings.is_sequence = is_sequence; job->settings.set_frame_range = set_frame_range; job->settings.sequence_len = sequence_len; - job->settings.offset = offset; + job->settings.sequence_offset = offset; job->settings.validate_meshes = validate_meshes; job->error_code = ABC_NO_ERROR; job->was_cancelled = false; diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h index 1f38d64924c..8c8aef3de57 100644 --- a/source/blender/blenfont/BLF_api.h +++ b/source/blender/blenfont/BLF_api.h @@ -38,7 +38,7 @@ struct rctf; struct ColorManagedDisplay; struct ResultBLF; -int BLF_init(int points, int dpi); +int BLF_init(void); void BLF_exit(void); void BLF_default_dpi(int dpi); void BLF_default_set(int fontid); diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c index 132a0ec3808..5bd62980b6d 100644 --- a/source/blender/blenfont/intern/blf.c +++ b/source/blender/blenfont/intern/blf.c @@ -96,15 +96,16 @@ static FontBLF *blf_get(int fontid) return NULL; } -int BLF_init(int points, int dpi) +int BLF_init(void) { int i; for (i = 0; i < BLF_MAX_FONT; i++) global_font[i] = NULL; - global_font_points = points; - global_font_dpi = dpi; + global_font_points = 11; + global_font_dpi = 72; + return blf_font_init(); } diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 789bc8df7e5..63ff1149a68 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -201,7 +201,7 @@ struct DerivedMesh { /* use for converting to BMesh which doesn't store bevel weight and edge crease by default */ char cd_flag; - char tangent_mask; /* which tangent layers are calculated */ + short tangent_mask; /* which tangent layers are calculated */ /** Calculate vert and face normals */ void (*calcNormals)(DerivedMesh *dm); @@ -791,11 +791,13 @@ void DM_calc_tangents_names_from_gpu( void DM_add_named_tangent_layer_for_uv( CustomData *uv_data, CustomData *tan_data, int numLoopData, const char *layer_name); + +#define DM_TANGENT_MASK_ORCO (1 << 9) void DM_calc_loop_tangents_step_0( const CustomData *loopData, bool calc_active_tangent, const char (*tangent_names)[MAX_NAME], int tangent_names_count, bool *rcalc_act, bool *rcalc_ren, int *ract_uv_n, int *rren_uv_n, - char *ract_uv_name, char *rren_uv_name, char *rtangent_mask); + char *ract_uv_name, char *rren_uv_name, short *rtangent_mask); void DM_calc_loop_tangents( DerivedMesh *dm, bool calc_active_tangent, const char (*tangent_names)[MAX_NAME], int tangent_names_count); diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h index 6527ba7f94f..5db0c3c9130 100644 --- a/source/blender/blenkernel/BKE_action.h +++ b/source/blender/blenkernel/BKE_action.h @@ -58,7 +58,7 @@ extern "C" { 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 Main *bmain, struct bAction *src); +struct bAction *BKE_action_copy(struct Main *bmain, const struct bAction *src); /* Deallocate all of the Action's data, but not the Action itself */ void BKE_action_free(struct bAction *act); @@ -150,7 +150,7 @@ void BKE_pose_free_data_ex(struct bPose *pose, bool do_id_user); void BKE_pose_free_data(struct bPose *pose); void BKE_pose_free(struct bPose *pose); void BKE_pose_free_ex(struct bPose *pose, bool do_id_user); -void BKE_pose_copy_data(struct bPose **dst, struct bPose *src, const bool copy_constraints); +void BKE_pose_copy_data(struct bPose **dst, const struct bPose *src, const bool copy_constraints); void BKE_pose_channel_copy_data(struct bPoseChannel *pchan, const struct bPoseChannel *pchan_from); struct bPoseChannel *BKE_pose_channel_find_name(const struct bPose *pose, const char *name); struct bPoseChannel *BKE_pose_channel_active(struct Object *ob); diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h index a67e903877a..420ae4bb12d 100644 --- a/source/blender/blenkernel/BKE_animsys.h +++ b/source/blender/blenkernel/BKE_animsys.h @@ -89,12 +89,6 @@ typedef enum eAnimData_MergeCopy_Modes { void BKE_animdata_merge_copy(struct ID *dst_id, struct ID *src_id, eAnimData_MergeCopy_Modes action_mode, bool fix_drivers); -/* Make Local */ -void BKE_animdata_make_local(struct AnimData *adt); - -/* Re-Assign ID's */ -void BKE_animdata_relink(struct AnimData *adt); - /* ************************************* */ /* KeyingSets API */ diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index 23bb526073b..6bfc8c918d6 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -77,7 +77,7 @@ int BKE_armature_bonelist_count(struct ListBase *lb); void BKE_armature_bonelist_free(struct ListBase *lb); void BKE_armature_free(struct bArmature *arm); void BKE_armature_make_local(struct Main *bmain, struct bArmature *arm, const bool lib_local); -struct bArmature *BKE_armature_copy(struct Main *bmain, struct bArmature *arm); +struct bArmature *BKE_armature_copy(struct Main *bmain, const struct bArmature *arm); /* Bounding box. */ struct BoundBox *BKE_armature_boundbox_get(struct Object *ob); diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index d55926ffb1e..ec0bfa6f5fa 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -50,7 +50,6 @@ void BKE_blender_version_string( void BKE_blender_userdef_set_data(struct UserDef *userdef); void BKE_blender_userdef_free_data(struct UserDef *userdef); -void BKE_blender_userdef_refresh(void); void BKE_blender_userdef_set_app_template(struct UserDef *userdef); diff --git a/source/blender/blenkernel/BKE_boids.h b/source/blender/blenkernel/BKE_boids.h index 582cd0cef8d..24f19951efe 100644 --- a/source/blender/blenkernel/BKE_boids.h +++ b/source/blender/blenkernel/BKE_boids.h @@ -61,6 +61,6 @@ BoidRule *boid_new_rule(int type); BoidState *boid_new_state(BoidSettings *boids); BoidState *boid_duplicate_state(BoidSettings *boids, BoidState *state); void boid_free_settings(BoidSettings *boids); -BoidSettings *boid_copy_settings(BoidSettings *boids); +BoidSettings *boid_copy_settings(const BoidSettings *boids); BoidState *boid_get_current_state(BoidSettings *boids); #endif diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h index 8bd4bdf89e1..42e4e73f2d5 100644 --- a/source/blender/blenkernel/BKE_brush.h +++ b/source/blender/blenkernel/BKE_brush.h @@ -44,7 +44,7 @@ void BKE_brush_system_exit(void); void BKE_brush_init(struct Brush *brush); struct Brush *BKE_brush_add(struct Main *bmain, const char *name, short ob_mode); struct Brush *BKE_brush_first_search(struct Main *bmain, short ob_mode); -struct Brush *BKE_brush_copy(struct Main *bmain, struct Brush *brush); +struct Brush *BKE_brush_copy(struct Main *bmain, const struct Brush *brush); void BKE_brush_make_local(struct Main *bmain, struct Brush *brush, const bool lib_local); void BKE_brush_unlink(struct Main *bmain, struct Brush *brush); void BKE_brush_free(struct Brush *brush); diff --git a/source/blender/blenkernel/BKE_cachefile.h b/source/blender/blenkernel/BKE_cachefile.h index 0d4ed2083b1..f1e643c4a19 100644 --- a/source/blender/blenkernel/BKE_cachefile.h +++ b/source/blender/blenkernel/BKE_cachefile.h @@ -47,7 +47,7 @@ void BKE_cachefile_init(struct CacheFile *cache_file); void BKE_cachefile_free(struct CacheFile *cache_file); -struct CacheFile *BKE_cachefile_copy(struct Main *bmain, struct CacheFile *cache_file); +struct CacheFile *BKE_cachefile_copy(struct Main *bmain, const struct CacheFile *cache_file); void BKE_cachefile_make_local(struct Main *bmain, struct CacheFile *cache_file, const bool lib_local); diff --git a/source/blender/blenkernel/BKE_camera.h b/source/blender/blenkernel/BKE_camera.h index 31a732cf7e5..b2f22aacb28 100644 --- a/source/blender/blenkernel/BKE_camera.h +++ b/source/blender/blenkernel/BKE_camera.h @@ -52,7 +52,7 @@ struct GPUFXSettings; void BKE_camera_init(struct Camera *cam); void *BKE_camera_add(struct Main *bmain, const char *name); -struct Camera *BKE_camera_copy(struct Main *bmain, struct Camera *cam); +struct Camera *BKE_camera_copy(struct Main *bmain, const struct Camera *cam); void BKE_camera_make_local(struct Main *bmain, struct Camera *cam, const bool lib_local); void BKE_camera_free(struct Camera *ca); diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h index 5b4f5910821..f68c4a2757b 100644 --- a/source/blender/blenkernel/BKE_colortools.h +++ b/source/blender/blenkernel/BKE_colortools.h @@ -46,8 +46,8 @@ void curvemapping_set_defaults(struct CurveMapping *cumap, int to struct CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, float maxy); void curvemapping_free_data(struct CurveMapping *cumap); void curvemapping_free(struct CurveMapping *cumap); -void curvemapping_copy_data(struct CurveMapping *target, struct CurveMapping *cumap); -struct CurveMapping *curvemapping_copy(struct CurveMapping *cumap); +void curvemapping_copy_data(struct CurveMapping *target, const struct CurveMapping *cumap); +struct CurveMapping *curvemapping_copy(const struct CurveMapping *cumap); void curvemapping_set_black_white_ex(const float black[3], const float white[3], float r_bwmul[3]); void curvemapping_set_black_white(struct CurveMapping *cumap, const float black[3], const float white[3]); diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index e111bd0e16b..0d382c8a49c 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -78,7 +78,7 @@ void BKE_curve_free(struct Curve *cu); void BKE_curve_editfont_free(struct Curve *cu); void BKE_curve_init(struct Curve *cu); struct Curve *BKE_curve_add(struct Main *bmain, const char *name, int type); -struct Curve *BKE_curve_copy(struct Main *bmain, struct Curve *cu); +struct Curve *BKE_curve_copy(struct Main *bmain, const struct Curve *cu); void BKE_curve_make_local(struct Main *bmain, struct Curve *cu, const bool lib_local); short BKE_curve_type_get(struct Curve *cu); void BKE_curve_type_test(struct Object *ob); @@ -142,7 +142,7 @@ int BKE_nurbList_verts_count(struct ListBase *nurb); int BKE_nurbList_verts_count_without_handles(struct ListBase *nurb); void BKE_nurbList_free(struct ListBase *lb); -void BKE_nurbList_duplicate(struct ListBase *lb1, struct ListBase *lb2); +void BKE_nurbList_duplicate(struct ListBase *lb1, const struct ListBase *lb2); void BKE_nurbList_handles_set(struct ListBase *editnurb, const char code); void BKE_nurbList_handles_recalculate(struct ListBase *editnurb, const bool calc_length, const char flag); @@ -150,7 +150,7 @@ void BKE_nurbList_handles_autocalc(ListBase *editnurb, int flag); void BKE_nurbList_flag_set(ListBase *editnurb, short flag); void BKE_nurb_free(struct Nurb *nu); -struct Nurb *BKE_nurb_duplicate(struct Nurb *nu); +struct Nurb *BKE_nurb_duplicate(const struct Nurb *nu); struct Nurb *BKE_nurb_copy(struct Nurb *src, int pntsu, int pntsv); void BKE_nurb_test2D(struct Nurb *nu); diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h index 3ce08a14177..a20c5a4240c 100644 --- a/source/blender/blenkernel/BKE_deform.h +++ b/source/blender/blenkernel/BKE_deform.h @@ -44,8 +44,8 @@ struct MLoop; struct MPoly; struct bDeformGroup *BKE_defgroup_new(struct Object *ob, const char *name); -void defgroup_copy_list(struct ListBase *lb1, struct ListBase *lb2); -struct bDeformGroup *defgroup_duplicate(struct bDeformGroup *ingroup); +void defgroup_copy_list(struct ListBase *lb1, const struct ListBase *lb2); +struct bDeformGroup *defgroup_duplicate(const struct bDeformGroup *ingroup); struct bDeformGroup *defgroup_find_name(struct Object *ob, const char *name); int *defgroup_flip_map(struct Object *ob, int *flip_map_len, const bool use_default); int *defgroup_flip_map_single(struct Object *ob, int *flip_map_len, const bool use_default, int defgroup); diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h index 3a45097efc5..b38f1299763 100644 --- a/source/blender/blenkernel/BKE_fcurve.h +++ b/source/blender/blenkernel/BKE_fcurve.h @@ -92,7 +92,7 @@ void bezt_add_to_cfra_elem(ListBase *lb, struct BezTriple *bezt); /* ---------------------- */ void fcurve_free_driver(struct FCurve *fcu); -struct ChannelDriver *fcurve_copy_driver(struct ChannelDriver *driver); +struct ChannelDriver *fcurve_copy_driver(const struct ChannelDriver *driver); void driver_variables_copy(struct ListBase *dst_list, const struct ListBase *src_list); @@ -138,7 +138,7 @@ typedef struct FModifierTypeInfo { /* free any data that is allocated separately (optional) */ void (*free_data)(struct FModifier *fcm); /* copy any special data that is allocated separately (optional) */ - void (*copy_data)(struct FModifier *fcm, struct FModifier *src); + void (*copy_data)(struct FModifier *fcm, const struct FModifier *src); /* set settings for data that will be used for FCuModifier.data (memory already allocated using MEM_callocN) */ void (*new_data)(void *mdata); /* verifies that the modifier settings are valid */ @@ -183,14 +183,14 @@ typedef enum eFMI_Requirement_Flags { } eFMI_Requirement_Flags; /* Function Prototypes for FModifierTypeInfo's */ -const FModifierTypeInfo *fmodifier_get_typeinfo(struct FModifier *fcm); -const FModifierTypeInfo *get_fmodifier_typeinfo(int type); +const FModifierTypeInfo *fmodifier_get_typeinfo(const struct FModifier *fcm); +const FModifierTypeInfo *get_fmodifier_typeinfo(const int type); /* ---------------------- */ struct FModifier *add_fmodifier(ListBase *modifiers, int type); -struct FModifier *copy_fmodifier(struct FModifier *src); -void copy_fmodifiers(ListBase *dst, ListBase *src); +struct FModifier *copy_fmodifier(const struct FModifier *src); +void copy_fmodifiers(ListBase *dst, const ListBase *src); bool remove_fmodifier(ListBase *modifiers, struct FModifier *fcm); void free_fmodifiers(ListBase *modifiers); @@ -216,7 +216,7 @@ int BKE_fcm_envelope_find_index(struct FCM_EnvelopeData *array, float frame, int /* -------- Data Management -------- */ void free_fcurve(struct FCurve *fcu); -struct FCurve *copy_fcurve(struct FCurve *fcu); +struct FCurve *copy_fcurve(const struct FCurve *fcu); void free_fcurves(ListBase *list); void copy_fcurves(ListBase *dst, ListBase *src); diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h index 3378f4acc60..bdd28baf137 100644 --- a/source/blender/blenkernel/BKE_gpencil.h +++ b/source/blender/blenkernel/BKE_gpencil.h @@ -60,7 +60,7 @@ struct bGPdata *BKE_gpencil_data_addnew(const char name[]); struct bGPDframe *BKE_gpencil_frame_duplicate(const struct bGPDframe *gpf_src); struct bGPDlayer *BKE_gpencil_layer_duplicate(const struct bGPDlayer *gpl_src); -struct bGPdata *BKE_gpencil_data_duplicate(struct Main *bmain, struct bGPdata *gpd, bool internal_copy); +struct bGPdata *BKE_gpencil_data_duplicate(struct Main *bmain, const struct bGPdata *gpd, bool internal_copy); void BKE_gpencil_make_local(struct Main *bmain, struct bGPdata *gpd, const bool lib_local); diff --git a/source/blender/blenkernel/BKE_group.h b/source/blender/blenkernel/BKE_group.h index 09a069ee36f..684251c9561 100644 --- a/source/blender/blenkernel/BKE_group.h +++ b/source/blender/blenkernel/BKE_group.h @@ -42,7 +42,7 @@ struct Scene; void BKE_group_free(struct Group *group); struct Group *BKE_group_add(struct Main *bmain, const char *name); -struct Group *BKE_group_copy(struct Main *bmain, struct Group *group); +struct Group *BKE_group_copy(struct Main *bmain, const struct Group *group); void BKE_group_make_local(struct Main *bmain, struct Group *group, const bool lib_local); bool BKE_group_object_add(struct Group *group, struct Object *ob, struct Scene *scene, struct Base *base); bool BKE_group_object_unlink(struct Group *group, struct Object *ob, struct Scene *scene, struct Base *base); diff --git a/source/blender/blenkernel/BKE_icons.h b/source/blender/blenkernel/BKE_icons.h index 6944c5ccd28..39e6b145755 100644 --- a/source/blender/blenkernel/BKE_icons.h +++ b/source/blender/blenkernel/BKE_icons.h @@ -88,7 +88,7 @@ void BKE_previewimg_clear(struct PreviewImage *prv); void BKE_previewimg_clear_single(struct PreviewImage *prv, enum eIconSizes size); /* get the preview from any pointer */ -struct PreviewImage **BKE_previewimg_id_get_p(struct ID *id); +struct PreviewImage **BKE_previewimg_id_get_p(const struct ID *id); /* free the preview image belonging to the id */ void BKE_previewimg_id_free(struct ID *id); @@ -97,9 +97,9 @@ void BKE_previewimg_id_free(struct ID *id); struct PreviewImage *BKE_previewimg_create(void); /* create a copy of the preview image */ -struct PreviewImage *BKE_previewimg_copy(struct PreviewImage *prv); +struct PreviewImage *BKE_previewimg_copy(const struct PreviewImage *prv); -void BKE_previewimg_id_copy(struct ID *new_id, struct ID *old_id); +void BKE_previewimg_id_copy(struct ID *new_id, const struct ID *old_id); /* retrieve existing or create new preview image */ struct PreviewImage *BKE_previewimg_id_ensure(struct ID *id); diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index 132c73209d1..e155b0719cc 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -250,7 +250,7 @@ void BKE_image_packfiles_from_mem(struct ReportList *reports, struct Image *ima, void BKE_image_print_memlist(void); /* empty image block, of similar type and filename */ -struct Image *BKE_image_copy(struct Main *bmain, struct Image *ima); +struct Image *BKE_image_copy(struct Main *bmain, const struct Image *ima); /* merge source into dest, and free source */ void BKE_image_merge(struct Image *dest, struct Image *source); diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h index e590ff148d7..94e8a24fbc5 100644 --- a/source/blender/blenkernel/BKE_key.h +++ b/source/blender/blenkernel/BKE_key.h @@ -51,7 +51,7 @@ extern "C" { void BKE_key_free(struct Key *sc); void BKE_key_free_nolib(struct Key *key); struct Key *BKE_key_add(struct ID *id); -struct Key *BKE_key_copy(struct Main *bmain, struct Key *key); +struct Key *BKE_key_copy(struct Main *bmain, const struct Key *key); struct Key *BKE_key_copy_nolib(struct Key *key); void BKE_key_sort(struct Key *key); diff --git a/source/blender/blenkernel/BKE_lamp.h b/source/blender/blenkernel/BKE_lamp.h index 4d53850c572..713ca80fb1a 100644 --- a/source/blender/blenkernel/BKE_lamp.h +++ b/source/blender/blenkernel/BKE_lamp.h @@ -44,7 +44,7 @@ struct Scene; void BKE_lamp_init(struct Lamp *la); struct Lamp *BKE_lamp_add(struct Main *bmain, const char *name) ATTR_WARN_UNUSED_RESULT; -struct Lamp *BKE_lamp_copy(struct Main *bmain, struct Lamp *la) ATTR_WARN_UNUSED_RESULT; +struct Lamp *BKE_lamp_copy(struct Main *bmain, const struct Lamp *la) ATTR_WARN_UNUSED_RESULT; struct Lamp *localize_lamp(struct Lamp *la) ATTR_WARN_UNUSED_RESULT; void BKE_lamp_make_local(struct Main *bmain, struct Lamp *la, const bool lib_local); void BKE_lamp_free(struct Lamp *la); diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h index 226c82da295..ec1cf79832d 100644 --- a/source/blender/blenkernel/BKE_lattice.h +++ b/source/blender/blenkernel/BKE_lattice.h @@ -47,7 +47,7 @@ struct MDeformVert; void BKE_lattice_resize(struct Lattice *lt, int u, int v, int w, struct Object *ltOb); void BKE_lattice_init(struct Lattice *lt); struct Lattice *BKE_lattice_add(struct Main *bmain, const char *name); -struct Lattice *BKE_lattice_copy(struct Main *bmain, struct Lattice *lt); +struct Lattice *BKE_lattice_copy(struct Main *bmain, const struct Lattice *lt); void BKE_lattice_free(struct Lattice *lt); void BKE_lattice_make_local(struct Main *bmain, struct Lattice *lt, const bool lib_local); void calc_lat_fudu(int flag, int res, float *r_fu, float *r_du); diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index 6649cfbb585..258dcc84449 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -50,11 +50,12 @@ struct bContext; struct PointerRNA; struct PropertyRNA; +size_t BKE_libblock_get_alloc_info(short type, const char **name); void *BKE_libblock_alloc_notest(short type); void *BKE_libblock_alloc(struct Main *bmain, short type, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); void BKE_libblock_init_empty(struct ID *id); -void *BKE_libblock_copy(struct Main *bmain, struct ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); -void *BKE_libblock_copy_nolib(struct ID *id, const bool do_action) ATTR_NONNULL(); +void *BKE_libblock_copy(struct Main *bmain, const struct ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +void *BKE_libblock_copy_nolib(const struct ID *id, const bool do_action) ATTR_NONNULL(); void BKE_libblock_copy_data(struct ID *id, const struct ID *id_from, const bool do_action); void BKE_libblock_rename(struct Main *bmain, struct ID *id, const char *name) ATTR_NONNULL(); void BLI_libblock_ensure_unique_name(struct Main *bmain, const char *name) ATTR_NONNULL(); @@ -64,9 +65,10 @@ struct ID *BKE_libblock_find_name(const short type, const char *name) ATTR_WARN_ /* library_remap.c (keep here since they're general functions) */ void BKE_libblock_free(struct Main *bmain, void *idv) ATTR_NONNULL(); +void BKE_libblock_free_datablock(struct ID *id) ATTR_NONNULL(); void BKE_libblock_free_ex(struct Main *bmain, void *idv, const bool do_id_user, const bool do_ui_user) ATTR_NONNULL(); void BKE_libblock_free_us(struct Main *bmain, void *idv) ATTR_NONNULL(); -void BKE_libblock_free_data(struct Main *bmain, struct ID *id, const bool do_id_user) ATTR_NONNULL(); +void BKE_libblock_free_data(struct ID *id, const bool do_id_user) ATTR_NONNULL(); void BKE_libblock_delete(struct Main *bmain, void *idv) ATTR_NONNULL(); void BKE_id_lib_local_paths(struct Main *bmain, struct Library *lib, struct ID *id); @@ -84,10 +86,10 @@ void BKE_id_clear_newpoin(struct ID *id); void BKE_id_make_local_generic(struct Main *bmain, struct ID *id, const bool id_in_mainlist, const bool lib_local); bool id_make_local(struct Main *bmain, struct ID *id, const bool test, const bool force_local); bool id_single_user(struct bContext *C, struct ID *id, struct PointerRNA *ptr, struct PropertyRNA *prop); -bool id_copy(struct Main *bmain, struct ID *id, struct ID **newid, bool test); +bool id_copy(struct Main *bmain, const struct ID *id, struct ID **newid, bool test); void id_sort_by_name(struct ListBase *lb, struct ID *id); void BKE_id_expand_local(struct Main *bmain, struct ID *id); -void BKE_id_copy_ensure_local(struct Main *bmain, struct ID *old_id, struct ID *new_id); +void BKE_id_copy_ensure_local(struct Main *bmain, const struct ID *old_id, struct ID *new_id); bool new_id(struct ListBase *lb, struct ID *id, const char *name); void id_clear_lib_data(struct Main *bmain, struct ID *id); diff --git a/source/blender/blenkernel/BKE_library_query.h b/source/blender/blenkernel/BKE_library_query.h index 6cf18e28e17..d6e7d98f371 100644 --- a/source/blender/blenkernel/BKE_library_query.h +++ b/source/blender/blenkernel/BKE_library_query.h @@ -83,6 +83,8 @@ enum { IDWALK_NOP = 0, IDWALK_READONLY = (1 << 0), IDWALK_RECURSE = (1 << 1), /* Also implies IDWALK_READONLY. */ + + IDWALK_NO_INDIRECT_PROXY_DATA_USAGE = (1 << 8), /* Ugly special case :(((( */ }; /* Loop over all of the ID's this datablock links to. */ diff --git a/source/blender/blenkernel/BKE_library_remap.h b/source/blender/blenkernel/BKE_library_remap.h index 53d438a0fdd..fd37fd762f4 100644 --- a/source/blender/blenkernel/BKE_library_remap.h +++ b/source/blender/blenkernel/BKE_library_remap.h @@ -46,6 +46,11 @@ enum { /* This tells the callback func to force setting IDs using target one with a 'never NULL' pointer to NULL. * WARNING! Use with extreme care, this will leave database in broken state and can cause crashes very easily! */ ID_REMAP_FORCE_NEVER_NULL_USAGE = 1 << 3, + /* Do not consider proxy/_group pointers of local objects as indirect usages... + * Our oh-so-beloved proxies again... Do not consider data used by local proxy object as indirect usage. + * This is needed e.g. in reload scenario, since we have to ensure remapping of Armature data of local proxy + * is also performed. Usual nightmare... */ + ID_REMAP_NO_INDIRECT_PROXY_DATA_USAGE = 1 << 4, }; /* Note: Requiring new_id to be non-null, this *may* not be the case ultimately, but makes things simpler for now. */ diff --git a/source/blender/blenkernel/BKE_linestyle.h b/source/blender/blenkernel/BKE_linestyle.h index af9bf58ce77..c7b323d0f6e 100644 --- a/source/blender/blenkernel/BKE_linestyle.h +++ b/source/blender/blenkernel/BKE_linestyle.h @@ -52,7 +52,7 @@ struct bContext; void BKE_linestyle_init(struct FreestyleLineStyle *linestyle); FreestyleLineStyle *BKE_linestyle_new(struct Main *bmain, const char *name); void BKE_linestyle_free(FreestyleLineStyle *linestyle); -FreestyleLineStyle *BKE_linestyle_copy(struct Main *bmain, FreestyleLineStyle *linestyle); +FreestyleLineStyle *BKE_linestyle_copy(struct Main *bmain, const FreestyleLineStyle *linestyle); void BKE_linestyle_make_local(struct Main *bmain, struct FreestyleLineStyle *linestyle, const bool lib_local); @@ -63,10 +63,10 @@ LineStyleModifier *BKE_linestyle_alpha_modifier_add(FreestyleLineStyle *linestyl LineStyleModifier *BKE_linestyle_thickness_modifier_add(FreestyleLineStyle *linestyle, const char *name, int type); LineStyleModifier *BKE_linestyle_geometry_modifier_add(FreestyleLineStyle *linestyle, const char *name, int type); -LineStyleModifier *BKE_linestyle_color_modifier_copy(FreestyleLineStyle *linestyle, LineStyleModifier *m); -LineStyleModifier *BKE_linestyle_alpha_modifier_copy(FreestyleLineStyle *linestyle, LineStyleModifier *m); -LineStyleModifier *BKE_linestyle_thickness_modifier_copy(FreestyleLineStyle *linestyle, LineStyleModifier *m); -LineStyleModifier *BKE_linestyle_geometry_modifier_copy(FreestyleLineStyle *linestyle, LineStyleModifier *m); +LineStyleModifier *BKE_linestyle_color_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m); +LineStyleModifier *BKE_linestyle_alpha_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m); +LineStyleModifier *BKE_linestyle_thickness_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m); +LineStyleModifier *BKE_linestyle_geometry_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m); int BKE_linestyle_color_modifier_remove(FreestyleLineStyle *linestyle, LineStyleModifier *modifier); int BKE_linestyle_alpha_modifier_remove(FreestyleLineStyle *linestyle, LineStyleModifier *modifier); diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 3349bffac85..0735d2d97a1 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -77,14 +77,14 @@ void BKE_mask_layer_free(struct MaskLayer *masklay); void BKE_mask_layer_free_list(struct ListBase *masklayers); void BKE_mask_spline_free(struct MaskSpline *spline); void BKE_mask_spline_free_list(struct ListBase *splines); -struct MaskSpline *BKE_mask_spline_copy(struct MaskSpline *spline); +struct MaskSpline *BKE_mask_spline_copy(const struct MaskSpline *spline); void BKE_mask_point_free(struct MaskSplinePoint *point); void BKE_mask_layer_unique_name(struct Mask *mask, struct MaskLayer *masklay); void BKE_mask_layer_rename(struct Mask *mask, struct MaskLayer *masklay, char *oldname, char *newname); -struct MaskLayer *BKE_mask_layer_copy(struct MaskLayer *layer); -void BKE_mask_layer_copy_list(struct ListBase *masklayers_new, struct ListBase *masklayers); +struct MaskLayer *BKE_mask_layer_copy(const struct MaskLayer *layer); +void BKE_mask_layer_copy_list(struct ListBase *masklayers_new, const struct ListBase *masklayers); /* splines */ struct MaskSpline *BKE_mask_spline_add(struct MaskLayer *masklay); @@ -123,7 +123,7 @@ void BKE_mask_point_select_set_handle(struct MaskSplinePoint *point, const eMask /* general */ 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 Main *bmain, struct Mask *mask); +struct Mask *BKE_mask_copy(struct Main *bmain, const struct Mask *mask); void BKE_mask_make_local(struct Main *bmain, struct Mask *mask, const bool lib_local); diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h index 8ae5c2b3c45..7da962dd6d6 100644 --- a/source/blender/blenkernel/BKE_material.h +++ b/source/blender/blenkernel/BKE_material.h @@ -54,7 +54,7 @@ void BKE_material_init(struct Material *ma); void BKE_material_remap_object(struct Object *ob, const unsigned int *remap); void BKE_material_remap_object_calc(struct Object *ob_dst, struct Object *ob_src, short *remap_src_to_dst); struct Material *BKE_material_add(struct Main *bmain, const char *name); -struct Material *BKE_material_copy(struct Main *bmain, struct Material *ma); +struct Material *BKE_material_copy(struct Main *bmain, const struct Material *ma); struct Material *localize_material(struct Material *ma); struct Material *give_node_material(struct Material *ma); /* returns node material or self */ void BKE_material_make_local(struct Main *bmain, struct Material *ma, const bool lib_local); diff --git a/source/blender/blenkernel/BKE_mball.h b/source/blender/blenkernel/BKE_mball.h index 64320a20281..c00a0743ebb 100644 --- a/source/blender/blenkernel/BKE_mball.h +++ b/source/blender/blenkernel/BKE_mball.h @@ -41,7 +41,7 @@ struct MetaElem; void BKE_mball_free(struct MetaBall *mb); void BKE_mball_init(struct MetaBall *mb); struct MetaBall *BKE_mball_add(struct Main *bmain, const char *name); -struct MetaBall *BKE_mball_copy(struct Main *bmain, struct MetaBall *mb); +struct MetaBall *BKE_mball_copy(struct Main *bmain, const struct MetaBall *mb); void BKE_mball_make_local(struct Main *bmain, struct MetaBall *mb, const bool lib_local); diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index b83bec5a302..b55b8b2dd3c 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -87,7 +87,7 @@ int BKE_mesh_edge_other_vert(const struct MEdge *e, int v); void BKE_mesh_free(struct Mesh *me); void BKE_mesh_init(struct Mesh *me); struct Mesh *BKE_mesh_add(struct Main *bmain, const char *name); -struct Mesh *BKE_mesh_copy(struct Main *bmain, struct Mesh *me); +struct Mesh *BKE_mesh_copy(struct Main *bmain, const struct Mesh *me); void BKE_mesh_update_customdata_pointers(struct Mesh *me, const bool do_ensure_tess_cd); void BKE_mesh_ensure_skin_customdata(struct Mesh *me); @@ -110,7 +110,8 @@ int BKE_mesh_nurbs_displist_to_mdata( struct MEdge **r_alledge, int *r_totedge, struct MLoop **r_allloop, struct MPoly **r_allpoly, struct MLoopUV **r_alluv, int *r_totloop, int *r_totpoly); -void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase, const bool use_orco_uv); +void BKE_mesh_from_nurbs_displist( + struct Object *ob, struct ListBase *dispbase, const bool use_orco_uv, const char *obdata_name); void BKE_mesh_from_nurbs(struct Object *ob); void BKE_mesh_to_curve_nurblist(struct DerivedMesh *dm, struct ListBase *nurblist, const int edge_users_test); void BKE_mesh_to_curve(struct Scene *scene, struct Object *ob); diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h index 3237c146bc5..69fdad5ef7b 100644 --- a/source/blender/blenkernel/BKE_movieclip.h +++ b/source/blender/blenkernel/BKE_movieclip.h @@ -41,7 +41,7 @@ struct MovieDistortion; void BKE_movieclip_free(struct MovieClip *clip); -struct MovieClip *BKE_movieclip_copy(struct Main *bmain, struct MovieClip *clip); +struct MovieClip *BKE_movieclip_copy(struct Main *bmain, const struct MovieClip *clip); void BKE_movieclip_make_local(struct Main *bmain, struct MovieClip *clip, const bool lib_local); struct MovieClip *BKE_movieclip_file_add(struct Main *bmain, const char *name); diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 41028c73014..d5279c5b0ce 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -335,8 +335,8 @@ struct bNodeTree *ntreeAddTree(struct Main *bmain, const char *name, const char /* copy/free funcs, need to manage ID users */ void ntreeFreeTree(struct bNodeTree *ntree); -struct bNodeTree *ntreeCopyTree_ex(struct bNodeTree *ntree, struct Main *bmain, const bool do_id_user); -struct bNodeTree *ntreeCopyTree(struct Main *bmain, struct bNodeTree *ntree); +struct bNodeTree *ntreeCopyTree_ex(const struct bNodeTree *ntree, struct Main *bmain, const bool do_id_user); +struct bNodeTree *ntreeCopyTree(struct Main *bmain, const struct bNodeTree *ntree); /* node->id user count */ void ntreeUserIncrefID(struct bNodeTree *ntree); void ntreeUserDecrefID(struct bNodeTree *ntree); diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index b6633ea6198..0a5035f9a9b 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -54,7 +54,7 @@ void BKE_object_workob_calc_parent(struct Scene *scene, struct Object *ob, struc void BKE_object_transform_copy(struct Object *ob_tar, const struct Object *ob_src); struct SoftBody *copy_softbody(const struct SoftBody *sb, bool copy_caches); -struct BulletSoftBody *copy_bulletsoftbody(struct BulletSoftBody *sb); +struct BulletSoftBody *copy_bulletsoftbody(const struct BulletSoftBody *sb); struct ParticleSystem *BKE_object_copy_particlesystem(struct ParticleSystem *psys); void BKE_object_copy_particlesystems(struct Object *ob_dst, const struct Object *ob_src); void BKE_object_copy_softbody(struct Object *ob_dst, const struct Object *ob_src); @@ -105,8 +105,8 @@ bool BKE_object_lod_is_usable(struct Object *ob, struct Scene *scene); struct Object *BKE_object_lod_meshob_get(struct Object *ob, struct Scene *scene); struct Object *BKE_object_lod_matob_get(struct Object *ob, struct Scene *scene); -struct Object *BKE_object_copy_ex(struct Main *bmain, struct Object *ob, bool copy_caches); -struct Object *BKE_object_copy(struct Main *bmain, struct Object *ob); +struct Object *BKE_object_copy_ex(struct Main *bmain, const struct Object *ob, bool copy_caches); +struct Object *BKE_object_copy(struct Main *bmain, const struct Object *ob); void BKE_object_make_local(struct Main *bmain, struct Object *ob, const bool lib_local); void BKE_object_make_local_ex(struct Main *bmain, struct Object *ob, const bool lib_local, const bool clear_proxy); bool BKE_object_is_libdata(struct Object *ob); @@ -189,10 +189,6 @@ void BKE_object_eval_constraints(struct EvaluationContext *eval_ctx, struct Object *ob); void BKE_object_eval_done(struct EvaluationContext *eval_ctx, struct Object *ob); -void BKE_object_eval_modifier(struct EvaluationContext *eval_ctx, - struct Scene *scene, - struct Object *ob, - struct ModifierData *md); void BKE_object_eval_uber_transform(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob); diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index b8faece6929..a70d2a99c41 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -99,7 +99,7 @@ void BKE_paint_set_overlay_override(enum OverlayFlags flag); /* palettes */ void BKE_palette_free(struct Palette *palette); struct Palette *BKE_palette_add(struct Main *bmain, const char *name); -struct Palette *BKE_palette_copy(struct Main *bmain, struct Palette *palette); +struct Palette *BKE_palette_copy(struct Main *bmain, const struct Palette *palette); void BKE_palette_make_local(struct Main *bmain, struct Palette *palette, const bool lib_local); struct PaletteColor *BKE_palette_color_add(struct Palette *palette); bool BKE_palette_is_empty(const struct Palette *palette); @@ -109,7 +109,7 @@ void BKE_palette_clear(struct Palette *palette); /* paint curves */ struct PaintCurve *BKE_paint_curve_add(struct Main *bmain, const char *name); void BKE_paint_curve_free(struct PaintCurve *pc); -struct PaintCurve *BKE_paint_curve_copy(struct Main *bmain, struct PaintCurve *pc); +struct PaintCurve *BKE_paint_curve_copy(struct Main *bmain, const struct PaintCurve *pc); void BKE_paint_curve_make_local(struct Main *bmain, struct PaintCurve *pc, const bool lib_local); void BKE_paint_init(struct Scene *sce, PaintMode mode, const char col[3]); diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index 2b6a84a2f87..f9948ba500a 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -324,7 +324,7 @@ struct ParticleSystemModifierData *psys_get_modifier(struct Object *ob, struct P struct ModifierData *object_add_particle_system(struct Scene *scene, struct Object *ob, const char *name); void object_remove_particle_system(struct Scene *scene, struct Object *ob); struct ParticleSettings *psys_new_settings(const char *name, struct Main *main); -struct ParticleSettings *BKE_particlesettings_copy(struct Main *bmain, struct ParticleSettings *part); +struct ParticleSettings *BKE_particlesettings_copy(struct Main *bmain, const struct ParticleSettings *part); void BKE_particlesettings_make_local(struct Main *bmain, struct ParticleSettings *part, const bool lib_local); void psys_reset(struct ParticleSystem *psys, int mode); diff --git a/source/blender/blenkernel/BKE_property.h b/source/blender/blenkernel/BKE_property.h index 99e60757f15..c787e8e8ed1 100644 --- a/source/blender/blenkernel/BKE_property.h +++ b/source/blender/blenkernel/BKE_property.h @@ -37,8 +37,8 @@ struct Object; void BKE_bproperty_free(struct bProperty *prop); void BKE_bproperty_free_list(struct ListBase *lb); -struct bProperty *BKE_bproperty_copy(struct bProperty *prop); -void BKE_bproperty_copy_list(struct ListBase *lbn, struct ListBase *lbo); +struct bProperty *BKE_bproperty_copy(const struct bProperty *prop); +void BKE_bproperty_copy_list(struct ListBase *lbn, const struct ListBase *lbo); void BKE_bproperty_init(struct bProperty *prop); struct bProperty *BKE_bproperty_new(int type); void BKE_bproperty_unique(struct bProperty *first, struct bProperty *prop, int force); diff --git a/source/blender/blenkernel/BKE_rigidbody.h b/source/blender/blenkernel/BKE_rigidbody.h index 443c3b2b5b2..c72f067a111 100644 --- a/source/blender/blenkernel/BKE_rigidbody.h +++ b/source/blender/blenkernel/BKE_rigidbody.h @@ -49,8 +49,8 @@ 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); +struct RigidBodyOb *BKE_rigidbody_copy_object(const struct Object *ob); +struct RigidBodyCon *BKE_rigidbody_copy_constraint(const struct Object *ob); /* Callback format for performing operations on ID-pointers for rigidbody world. */ typedef void (*RigidbodyWorldIDFunc)(struct RigidBodyWorld *rbw, struct ID **idpoin, void *userdata, int cb_flag); diff --git a/source/blender/blenkernel/BKE_sca.h b/source/blender/blenkernel/BKE_sca.h index 1579a0c7bb3..10cddd7b454 100644 --- a/source/blender/blenkernel/BKE_sca.h +++ b/source/blender/blenkernel/BKE_sca.h @@ -53,15 +53,15 @@ void free_actuators(struct ListBase *lb); void free_sensor(struct bSensor *sens); void free_sensors(struct ListBase *lb); struct bSensor *copy_sensor(struct bSensor *sens); -void copy_sensors(struct ListBase *lbn, struct ListBase *lbo); +void copy_sensors(struct ListBase *lbn, const struct ListBase *lbo); void init_sensor(struct bSensor *sens); struct bSensor *new_sensor(int type); struct bController *copy_controller(struct bController *cont); -void copy_controllers(struct ListBase *lbn, struct ListBase *lbo); +void copy_controllers(struct ListBase *lbn, const struct ListBase *lbo); void init_controller(struct bController *cont); struct bController *new_controller(int type); struct bActuator *copy_actuator(struct bActuator *act); -void copy_actuators(struct ListBase *lbn, struct ListBase *lbo); +void copy_actuators(struct ListBase *lbn, const struct ListBase *lbo); void init_actuator(struct bActuator *act); struct bActuator *new_actuator(int type); void clear_sca_new_poins_ob(struct Object *ob); @@ -70,7 +70,7 @@ void set_sca_new_poins_ob(struct Object *ob); void set_sca_new_poins(void); void BKE_sca_logic_links_remap(struct Main *bmain, struct Object *ob_old, struct Object *ob_new); -void BKE_sca_logic_copy(struct Object *ob_new, struct Object *ob); +void BKE_sca_logic_copy(struct Object *ob_new, const struct Object *ob); void sca_move_sensor(struct bSensor *sens_to_move, struct Object *ob, int move_up); void sca_move_controller(struct bController *cont_to_move, struct Object *ob, int move_up); diff --git a/source/blender/blenkernel/BKE_speaker.h b/source/blender/blenkernel/BKE_speaker.h index b91b64c4b74..907558f9203 100644 --- a/source/blender/blenkernel/BKE_speaker.h +++ b/source/blender/blenkernel/BKE_speaker.h @@ -33,7 +33,7 @@ struct Speaker; void BKE_speaker_init(struct Speaker *spk); void *BKE_speaker_add(struct Main *bmain, const char *name); -struct Speaker *BKE_speaker_copy(struct Main *bmain, struct Speaker *spk); +struct Speaker *BKE_speaker_copy(struct Main *bmain, const struct Speaker *spk); void BKE_speaker_make_local(struct Main *bmain, struct Speaker *spk, const bool lib_local); void BKE_speaker_free(struct Speaker *spk); diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h index 081b7589af6..c8fb483cdf2 100644 --- a/source/blender/blenkernel/BKE_text.h +++ b/source/blender/blenkernel/BKE_text.h @@ -52,7 +52,7 @@ bool BKE_text_reload(struct Text *text); struct Text *BKE_text_load_ex(struct Main *bmain, const char *file, const char *relpath, const bool is_internal); struct Text *BKE_text_load (struct Main *bmain, const char *file, const char *relpath); -struct Text *BKE_text_copy (struct Main *bmain, struct Text *ta); +struct Text *BKE_text_copy (struct Main *bmain, const struct Text *ta); void BKE_text_make_local (struct Main *bmain, struct Text *text, const bool lib_local); void BKE_text_clear (struct Text *text); void BKE_text_write (struct Text *text, const char *str); diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h index e353d032ee4..190fdeafaec 100644 --- a/source/blender/blenkernel/BKE_texture.h +++ b/source/blender/blenkernel/BKE_texture.h @@ -70,7 +70,7 @@ void colorband_update_sort(struct ColorBand *coba); void BKE_texture_free(struct Tex *tex); void BKE_texture_default(struct Tex *tex); -struct Tex *BKE_texture_copy(struct Main *bmain, struct Tex *tex); +struct Tex *BKE_texture_copy(struct Main *bmain, const struct Tex *tex); struct Tex *BKE_texture_add(struct Main *bmain, const char *name); struct Tex *BKE_texture_localize(struct Tex *tex); void BKE_texture_make_local(struct Main *bmain, struct Tex *tex, const bool lib_local); @@ -114,13 +114,13 @@ void BKE_texture_colormapping_default(struct ColorMapping *color void BKE_texture_envmap_free_data(struct EnvMap *env); void BKE_texture_envmap_free(struct EnvMap *env); struct EnvMap *BKE_texture_envmap_add(void); -struct EnvMap *BKE_texture_envmap_copy(struct EnvMap *env); +struct EnvMap *BKE_texture_envmap_copy(const struct EnvMap *env); void BKE_texture_pointdensity_init_data(struct PointDensity *pd); void BKE_texture_pointdensity_free_data(struct PointDensity *pd); void BKE_texture_pointdensity_free(struct PointDensity *pd); struct PointDensity *BKE_texture_pointdensity_add(void); -struct PointDensity *BKE_texture_pointdensity_copy(struct PointDensity *pd); +struct PointDensity *BKE_texture_pointdensity_copy(const struct PointDensity *pd); void BKE_texture_voxeldata_free_data(struct VoxelData *vd); void BKE_texture_voxeldata_free(struct VoxelData *vd); @@ -129,7 +129,7 @@ struct VoxelData *BKE_texture_voxeldata_copy(struct VoxelData *vd); void BKE_texture_ocean_free(struct OceanTex *ot); struct OceanTex *BKE_texture_ocean_add(void); -struct OceanTex *BKE_texture_ocean_copy(struct OceanTex *ot); +struct OceanTex *BKE_texture_ocean_copy(const struct OceanTex *ot); bool BKE_texture_dependsOnTime(const struct Tex *texture); bool BKE_texture_is_image_user(const struct Tex *tex); diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index 30873567297..b48be382073 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -52,7 +52,7 @@ struct rcti; /* **** Common functions **** */ void BKE_tracking_free(struct MovieTracking *tracking); -void BKE_tracking_copy(struct MovieTracking *tracking_dst, struct MovieTracking *tracking_src); +void BKE_tracking_copy(struct MovieTracking *tracking_dst, const struct MovieTracking *tracking_src); void BKE_tracking_settings_init(struct MovieTracking *tracking); diff --git a/source/blender/blenkernel/BKE_world.h b/source/blender/blenkernel/BKE_world.h index 23bf9ec3d22..18ae61f7653 100644 --- a/source/blender/blenkernel/BKE_world.h +++ b/source/blender/blenkernel/BKE_world.h @@ -39,7 +39,7 @@ struct World; void BKE_world_free(struct World *sc); void BKE_world_init(struct World *wrld); struct World *add_world(struct Main *bmian, const char *name); -struct World *BKE_world_copy(struct Main *bmain, struct World *wrld); +struct World *BKE_world_copy(struct Main *bmain, const struct World *wrld); struct World *localize_world(struct World *wrld); void BKE_world_make_local(struct Main *bmain, struct World *wrld, const bool lib_local); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 18e9bdf6cd1..7eea8224ba1 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -3322,7 +3322,8 @@ void DM_calc_loop_tangents_step_0( const CustomData *loopData, bool calc_active_tangent, const char (*tangent_names)[MAX_NAME], int tangent_names_count, bool *rcalc_act, bool *rcalc_ren, int *ract_uv_n, int *rren_uv_n, - char *ract_uv_name, char *rren_uv_name, char *rtangent_mask) { + char *ract_uv_name, char *rren_uv_name, short *rtangent_mask) +{ /* Active uv in viewport */ int layer_index = CustomData_get_layer_index(loopData, CD_MLOOPUV); *ract_uv_n = CustomData_get_active_layer(loopData, CD_MLOOPUV); @@ -3376,21 +3377,22 @@ void DM_calc_loop_tangents_step_0( if (add) *rtangent_mask |= 1 << n; } + + if (uv_layer_num == 0) + *rtangent_mask |= DM_TANGENT_MASK_ORCO; } void DM_calc_loop_tangents( DerivedMesh *dm, bool calc_active_tangent, const char (*tangent_names)[MAX_NAME], int tangent_names_count) { - if (CustomData_number_of_layers(&dm->loopData, CD_MLOOPUV) == 0) - return; int act_uv_n = -1; int ren_uv_n = -1; bool calc_act = false; bool calc_ren = false; char act_uv_name[MAX_NAME]; char ren_uv_name[MAX_NAME]; - char tangent_mask = 0; + short tangent_mask = 0; DM_calc_loop_tangents_step_0( &dm->loopData, calc_active_tangent, tangent_names, tangent_names_count, &calc_act, &calc_ren, &act_uv_n, &ren_uv_n, act_uv_name, ren_uv_name, &tangent_mask); @@ -3403,6 +3405,8 @@ void DM_calc_loop_tangents( for (int i = 0; i < tangent_names_count; i++) if (tangent_names[i][0]) DM_add_named_tangent_layer_for_uv(&dm->loopData, &dm->loopData, dm->numLoopData, tangent_names[i]); + if ((tangent_mask & DM_TANGENT_MASK_ORCO) && CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, "") == -1) + CustomData_add_layer_named(&dm->loopData, CD_TANGENT, CD_CALLOC, NULL, dm->numLoopData, ""); if (calc_act && act_uv_name[0]) DM_add_named_tangent_layer_for_uv(&dm->loopData, &dm->loopData, dm->numLoopData, act_uv_name); if (calc_ren && ren_uv_name[0]) @@ -3464,19 +3468,24 @@ void DM_calc_loop_tangents( mesh2tangent->orco = NULL; mesh2tangent->mloopuv = CustomData_get_layer_named(&dm->loopData, CD_MLOOPUV, dm->loopData.layers[index].name); + + /* Fill the resulting tangent_mask */ if (!mesh2tangent->mloopuv) { mesh2tangent->orco = dm->getVertDataArray(dm, CD_ORCO); if (!mesh2tangent->orco) continue; + + dm->tangent_mask |= DM_TANGENT_MASK_ORCO; + } + else { + int uv_ind = CustomData_get_named_layer_index(&dm->loopData, CD_MLOOPUV, dm->loopData.layers[index].name); + int uv_start = CustomData_get_layer_index(&dm->loopData, CD_MLOOPUV); + BLI_assert(uv_ind != -1 && uv_start != -1); + BLI_assert(uv_ind - uv_start < MAX_MTFACE); + dm->tangent_mask |= 1 << (uv_ind - uv_start); } - mesh2tangent->tangent = dm->loopData.layers[index].data; - /* Fill the resulting tangent_mask */ - int uv_ind = CustomData_get_named_layer_index(&dm->loopData, CD_MLOOPUV, dm->loopData.layers[index].name); - int uv_start = CustomData_get_layer_index(&dm->loopData, CD_MLOOPUV); - BLI_assert(uv_ind != -1 && uv_start != -1); - BLI_assert(uv_ind - uv_start < MAX_MTFACE); - dm->tangent_mask |= 1 << (uv_ind - uv_start); + mesh2tangent->tangent = dm->loopData.layers[index].data; BLI_task_pool_push(task_pool, DM_calc_loop_tangents_thread, mesh2tangent, false, TASK_PRIORITY_LOW); } @@ -3492,21 +3501,19 @@ void DM_calc_loop_tangents( #endif - int uv_index, tan_index; - /* Update active layer index */ - uv_index = CustomData_get_layer_index_n(&dm->loopData, CD_MLOOPUV, act_uv_n); - if (uv_index != -1) { - tan_index = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, dm->loopData.layers[uv_index].name); + int act_uv_index = CustomData_get_layer_index_n(&dm->loopData, CD_MLOOPUV, act_uv_n); + if (act_uv_index != -1) { + int tan_index = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, dm->loopData.layers[act_uv_index].name); CustomData_set_layer_active_index(&dm->loopData, CD_TANGENT, tan_index); - } + } /* else tangent has been built from orco */ /* Update render layer index */ - uv_index = CustomData_get_layer_index_n(&dm->loopData, CD_MLOOPUV, ren_uv_n); - if (uv_index != -1) { - tan_index = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, dm->loopData.layers[uv_index].name); + int ren_uv_index = CustomData_get_layer_index_n(&dm->loopData, CD_MLOOPUV, ren_uv_n); + if (ren_uv_index != -1) { + int tan_index = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, dm->loopData.layers[ren_uv_index].name); CustomData_set_layer_render_index(&dm->loopData, CD_TANGENT, tan_index); - } + } /* else tangent has been built from orco */ } } diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 1e33fe4ab46..885ea36d404 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -120,7 +120,7 @@ void BKE_action_free(bAction *act) /* .................................. */ -bAction *BKE_action_copy(Main *bmain, bAction *src) +bAction *BKE_action_copy(Main *bmain, const bAction *src) { bAction *dst = NULL; bActionGroup *dgrp, *sgrp; @@ -523,7 +523,7 @@ const char *BKE_pose_ikparam_get_name(bPose *pose) * * \param dst Should be freed already, makes entire duplicate. */ -void BKE_pose_copy_data(bPose **dst, bPose *src, const bool copy_constraints) +void BKE_pose_copy_data(bPose **dst, const bPose *src, const bool copy_constraints) { bPose *outPose; bPoseChannel *pchan; diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 0b637355ecf..539901a59d5 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -397,73 +397,6 @@ void BKE_animdata_merge_copy(ID *dst_id, ID *src_id, eAnimData_MergeCopy_Modes a } } -/* Make Local -------------------------------------------- */ - -static void make_local_strips(ListBase *strips) -{ - NlaStrip *strip; - - for (strip = strips->first; strip; strip = strip->next) { - if (strip->act) BKE_action_make_local(G.main, strip->act, false); - if (strip->remap && strip->remap->target) BKE_action_make_local(G.main, strip->remap->target, false); - - make_local_strips(&strip->strips); - } -} - -/* Use local copy instead of linked copy of various ID-blocks */ -void BKE_animdata_make_local(AnimData *adt) -{ - NlaTrack *nlt; - - /* Actions - Active and Temp */ - if (adt->action) BKE_action_make_local(G.main, adt->action, false); - if (adt->tmpact) BKE_action_make_local(G.main, adt->tmpact, false); - /* Remaps */ - if (adt->remap && adt->remap->target) BKE_action_make_local(G.main, adt->remap->target, false); - - /* Drivers */ - /* TODO: need to remap the ID-targets too? */ - - /* NLA Data */ - for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) - make_local_strips(&nlt->strips); -} - - -/* When duplicating data (i.e. objects), drivers referring to the original data will - * get updated to point to the duplicated data (if drivers belong to the new data) - */ -void BKE_animdata_relink(AnimData *adt) -{ - /* sanity check */ - if (adt == NULL) - return; - - /* drivers */ - if (adt->drivers.first) { - FCurve *fcu; - - /* check each driver against all the base paths to see if any should go */ - for (fcu = adt->drivers.first; fcu; fcu = fcu->next) { - ChannelDriver *driver = fcu->driver; - DriverVar *dvar; - - /* driver variables */ - for (dvar = driver->variables.first; dvar; dvar = dvar->next) { - /* only change the used targets, since the others will need fixing manually anyway */ - DRIVER_TARGETS_USED_LOOPER(dvar) - { - if (dtar->id && dtar->id->newid) { - dtar->id = dtar->id->newid; - } - } - DRIVER_TARGETS_LOOPER_END - } - } - } -} - /* Sub-ID Regrouping ------------------------------------------- */ /** @@ -1586,7 +1519,8 @@ static bool animsys_write_rna_setting(PathResolvedRNA *anim_rna, const float val } case PROP_INT: { - const int value_coerce = (int)value; + int value_coerce = (int)value; + RNA_property_int_clamp(ptr, prop, &value_coerce); if (array_index != -1) { if (RNA_property_int_get_index(ptr, prop, array_index) != value_coerce) { RNA_property_int_set_index(ptr, prop, array_index, value_coerce); @@ -1603,15 +1537,17 @@ static bool animsys_write_rna_setting(PathResolvedRNA *anim_rna, const float val } case PROP_FLOAT: { + float value_coerce = value; + RNA_property_float_clamp(ptr, prop, &value_coerce); if (array_index != -1) { - if (RNA_property_float_get_index(ptr, prop, array_index) != value) { - RNA_property_float_set_index(ptr, prop, array_index, value); + if (RNA_property_float_get_index(ptr, prop, array_index) != value_coerce) { + RNA_property_float_set_index(ptr, prop, array_index, value_coerce); written = true; } } else { - if (RNA_property_float_get(ptr, prop) != value) { - RNA_property_float_set(ptr, prop, value); + if (RNA_property_float_get(ptr, prop) != value_coerce) { + RNA_property_float_set(ptr, prop, value_coerce); written = true; } } diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index d7ea534068d..35b6fe113bd 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -150,7 +150,7 @@ void BKE_armature_make_local(Main *bmain, bArmature *arm, const bool lib_local) BKE_id_make_local_generic(bmain, &arm->id, true, lib_local); } -static void copy_bonechildren(Bone *newBone, Bone *oldBone, Bone *actBone, Bone **newActBone) +static void copy_bonechildren(Bone *newBone, const Bone *oldBone, const Bone *actBone, Bone **newActBone) { Bone *curBone, *newChildBone; @@ -172,7 +172,7 @@ static void copy_bonechildren(Bone *newBone, Bone *oldBone, Bone *actBone, Bone } } -bArmature *BKE_armature_copy(Main *bmain, bArmature *arm) +bArmature *BKE_armature_copy(Main *bmain, const bArmature *arm) { bArmature *newArm; Bone *oldBone, *newBone; diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index ceb641073e0..2624019e63a 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -226,19 +226,6 @@ void BKE_blender_userdef_free_data(UserDef *userdef) } /** - * Handle changes in settings that need refreshing. - */ -void BKE_blender_userdef_refresh(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; - -} - -/** * Write U from userdef. * This function defines which settings a template will override for the user preferences. */ diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c index a521d671ea4..05ea7983b8e 100644 --- a/source/blender/blenkernel/intern/blendfile.c +++ b/source/blender/blenkernel/intern/blendfile.c @@ -413,9 +413,9 @@ bool BKE_blendfile_read_from_memfile( if (bfd) { /* remove the unused screens and wm */ while (bfd->main->wm.first) - BKE_libblock_free_ex(bfd->main, bfd->main->wm.first, true, true); + BKE_libblock_free(bfd->main, bfd->main->wm.first); while (bfd->main->screen.first) - BKE_libblock_free_ex(bfd->main, bfd->main->screen.first, true, true); + BKE_libblock_free(bfd->main, bfd->main->screen.first); setup_app_data(C, bfd, "<memory1>", reports); } diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index b4bc83bf94c..7ca4e07076d 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -1581,7 +1581,7 @@ void boid_free_settings(BoidSettings *boids) MEM_freeN(boids); } } -BoidSettings *boid_copy_settings(BoidSettings *boids) +BoidSettings *boid_copy_settings(const BoidSettings *boids) { BoidSettings *nboids = NULL; diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 540ef789e66..31d67c7962a 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -172,7 +172,7 @@ struct Brush *BKE_brush_first_search(struct Main *bmain, short ob_mode) return NULL; } -Brush *BKE_brush_copy(Main *bmain, Brush *brush) +Brush *BKE_brush_copy(Main *bmain, const Brush *brush) { Brush *brushn; @@ -195,7 +195,7 @@ Brush *BKE_brush_copy(Main *bmain, Brush *brush) brushn->curve = curvemapping_copy(brush->curve); /* enable fake user by default */ - id_fake_user_set(&brush->id); + id_fake_user_set(&brushn->id); BKE_id_copy_ensure_local(bmain, &brush->id, &brushn->id); diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c index c0e4ef37a93..c1fad4f80c8 100644 --- a/source/blender/blenkernel/intern/bvhutils.c +++ b/source/blender/blenkernel/intern/bvhutils.c @@ -917,10 +917,10 @@ BVHTree *bvhtree_from_mesh_faces( /** * Builds a bvh tree where nodes are the given tessellated faces (note: does not copy given mfaces!). - * \param vert_allocated if true, vert freeing will be done when freeing data. - * \param face_allocated if true, face freeing will be done when freeing data. + * \param vert_allocated: if true, vert freeing will be done when freeing data. + * \param face_allocated: if true, face freeing will be done when freeing data. * \param faces_mask: if not null, true elements give which faces to add to BVH tree. - * \param numFaces_active if >= 0, number of active faces to add to BVH tree (else will be computed from mask). + * \param faces_num_active: if >= 0, number of active faces to add to BVH tree (else will be computed from mask). */ BVHTree *bvhtree_from_mesh_faces_ex( BVHTreeFromMesh *data, const MVert *vert, const bool vert_allocated, diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c index 67c66d4e40b..cf619a32783 100644 --- a/source/blender/blenkernel/intern/cachefile.c +++ b/source/blender/blenkernel/intern/cachefile.c @@ -100,12 +100,12 @@ void BKE_cachefile_free(CacheFile *cache_file) BLI_freelistN(&cache_file->object_paths); } -CacheFile *BKE_cachefile_copy(Main *bmain, CacheFile *cache_file) +CacheFile *BKE_cachefile_copy(Main *bmain, const CacheFile *cache_file) { CacheFile *new_cache_file = BKE_libblock_copy(bmain, &cache_file->id); new_cache_file->handle = NULL; - BLI_listbase_clear(&cache_file->object_paths); + BLI_listbase_clear(&new_cache_file->object_paths); BKE_id_copy_ensure_local(bmain, &cache_file->id, &new_cache_file->id); @@ -166,10 +166,12 @@ void BKE_cachefile_update_frame(Main *bmain, Scene *scene, const float ctime, co const float time = BKE_cachefile_time_offset(cache_file, ctime, fps); if (BKE_cachefile_filepath_get(bmain, cache_file, time, filename)) { + BKE_cachefile_clean(scene, cache_file); #ifdef WITH_ALEMBIC ABC_free_handle(cache_file->handle); cache_file->handle = ABC_create_handle(filename, NULL); #endif + break; } } } diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c index 9cb553aa27b..915c08674a4 100644 --- a/source/blender/blenkernel/intern/camera.c +++ b/source/blender/blenkernel/intern/camera.c @@ -93,7 +93,7 @@ void *BKE_camera_add(Main *bmain, const char *name) return cam; } -Camera *BKE_camera_copy(Main *bmain, Camera *cam) +Camera *BKE_camera_copy(Main *bmain, const Camera *cam) { Camera *camn; diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index b3a0895d063..ee0f904c3a6 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -130,7 +130,7 @@ void curvemapping_free(CurveMapping *cumap) } } -void curvemapping_copy_data(CurveMapping *target, CurveMapping *cumap) +void curvemapping_copy_data(CurveMapping *target, const CurveMapping *cumap) { int a; @@ -146,7 +146,7 @@ void curvemapping_copy_data(CurveMapping *target, CurveMapping *cumap) } } -CurveMapping *curvemapping_copy(CurveMapping *cumap) +CurveMapping *curvemapping_copy(const CurveMapping *cumap) { if (cumap) { CurveMapping *cumapn = MEM_dupallocN(cumap); diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 9bc1ce16284..07a6b304dff 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -790,7 +790,7 @@ static void default_get_tarmat(bConstraint *con, bConstraintOb *UNUSED(cob), bCo ct = ctn; \ } \ } (void)0 - + /* --------- ChildOf Constraint ------------ */ static void childof_new_data(void *cdata) diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 439abb1d593..8b32109cf2b 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -187,7 +187,7 @@ Curve *BKE_curve_add(Main *bmain, const char *name, int type) return cu; } -Curve *BKE_curve_copy(Main *bmain, Curve *cu) +Curve *BKE_curve_copy(Main *bmain, const Curve *cu) { Curve *cun; int a; @@ -468,7 +468,7 @@ void BKE_nurbList_free(ListBase *lb) BLI_listbase_clear(lb); } -Nurb *BKE_nurb_duplicate(Nurb *nu) +Nurb *BKE_nurb_duplicate(const Nurb *nu) { Nurb *newnu; int len; @@ -532,7 +532,7 @@ Nurb *BKE_nurb_copy(Nurb *src, int pntsu, int pntsv) return newnu; } -void BKE_nurbList_duplicate(ListBase *lb1, ListBase *lb2) +void BKE_nurbList_duplicate(ListBase *lb1, const ListBase *lb2) { Nurb *nu, *nun; diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index 13b1aab5e1c..69baaf5e58a 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -76,7 +76,7 @@ bDeformGroup *BKE_defgroup_new(Object *ob, const char *name) return defgroup; } -void defgroup_copy_list(ListBase *outbase, ListBase *inbase) +void defgroup_copy_list(ListBase *outbase, const ListBase *inbase) { bDeformGroup *defgroup, *defgroupn; @@ -88,7 +88,7 @@ void defgroup_copy_list(ListBase *outbase, ListBase *inbase) } } -bDeformGroup *defgroup_duplicate(bDeformGroup *ingroup) +bDeformGroup *defgroup_duplicate(const bDeformGroup *ingroup) { bDeformGroup *outgroup; diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index 5591ee2a0d4..a91983c001c 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -149,6 +149,8 @@ static void emDM_ensurePolyCenters(EditDerivedBMesh *bmdm) const float (*vertexCos)[3]; vertexCos = bmdm->vertexCos; + BM_mesh_elem_index_ensure(bm, BM_VERT); + BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) { BM_face_calc_center_mean_vcos(bm, efa, polyCos[i], vertexCos); } @@ -487,8 +489,6 @@ static void emDM_calc_loop_tangents( EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm; BMEditMesh *em = bmdm->em; BMesh *bm = bmdm->em->bm; - if (CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV) == 0) - return; int act_uv_n = -1; int ren_uv_n = -1; @@ -496,7 +496,7 @@ static void emDM_calc_loop_tangents( bool calc_ren = false; char act_uv_name[MAX_NAME]; char ren_uv_name[MAX_NAME]; - char tangent_mask = 0; + short tangent_mask = 0; DM_calc_loop_tangents_step_0( &bm->ldata, calc_active_tangent, tangent_names, tangent_names_count, @@ -506,6 +506,8 @@ static void emDM_calc_loop_tangents( for (int i = 0; i < tangent_names_count; i++) if (tangent_names[i][0]) DM_add_named_tangent_layer_for_uv(&bm->ldata, &dm->loopData, dm->numLoopData, tangent_names[i]); + if ((tangent_mask & DM_TANGENT_MASK_ORCO) && CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, "") == -1) + CustomData_add_layer_named(&dm->loopData, CD_TANGENT, CD_CALLOC, NULL, dm->numLoopData, ""); if (calc_act && act_uv_name[0]) DM_add_named_tangent_layer_for_uv(&bm->ldata, &dm->loopData, dm->numLoopData, act_uv_name); if (calc_ren && ren_uv_name[0]) @@ -572,7 +574,17 @@ static void emDM_calc_loop_tangents( continue; /* needed for orco lookups */ htype_index |= BM_VERT; + dm->tangent_mask |= DM_TANGENT_MASK_ORCO; + } + else { + /* Fill the resulting tangent_mask */ + int uv_ind = CustomData_get_named_layer_index(&bm->ldata, CD_MLOOPUV, dm->loopData.layers[index].name); + int uv_start = CustomData_get_layer_index(&bm->ldata, CD_MLOOPUV); + BLI_assert(uv_ind != -1 && uv_start != -1); + BLI_assert(uv_ind - uv_start < MAX_MTFACE); + dm->tangent_mask |= 1 << (uv_ind - uv_start); } + if (mesh2tangent->precomputedFaceNormals) { /* needed for face normal lookups */ htype_index |= BM_FACE; @@ -582,12 +594,6 @@ static void emDM_calc_loop_tangents( mesh2tangent->looptris = (const BMLoop *(*)[3])em->looptris; mesh2tangent->tangent = dm->loopData.layers[index].data; - /* Fill the resulting tangent_mask */ - int uv_ind = CustomData_get_named_layer_index(&bm->ldata, CD_MLOOPUV, dm->loopData.layers[index].name); - int uv_start = CustomData_get_layer_index(&bm->ldata, CD_MLOOPUV); - BLI_assert(uv_ind != -1 && uv_start != -1); - BLI_assert(uv_ind - uv_start < MAX_MTFACE); - dm->tangent_mask |= 1 << (uv_ind - uv_start); BLI_task_pool_push(task_pool, emDM_calc_loop_tangents_thread, mesh2tangent, false, TASK_PRIORITY_LOW); } @@ -602,15 +608,20 @@ static void emDM_calc_loop_tangents( #undef USE_LOOPTRI_DETECT_QUADS #endif } + /* Update active layer index */ - int uv_index = CustomData_get_layer_index_n(&bm->ldata, CD_MLOOPUV, act_uv_n); - int tan_index = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, bm->ldata.layers[uv_index].name); - CustomData_set_layer_active_index(&dm->loopData, CD_TANGENT, tan_index); + int act_uv_index = CustomData_get_layer_index_n(&bm->ldata, CD_MLOOPUV, act_uv_n); + if (act_uv_index >= 0) { + int tan_index = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, bm->ldata.layers[act_uv_index].name); + CustomData_set_layer_active_index(&dm->loopData, CD_TANGENT, tan_index); + } /* else tangent has been built from orco */ /* Update render layer index */ - uv_index = CustomData_get_layer_index_n(&bm->ldata, CD_MLOOPUV, ren_uv_n); - tan_index = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, bm->ldata.layers[uv_index].name); - CustomData_set_layer_render_index(&dm->loopData, CD_TANGENT, tan_index); + int ren_uv_index = CustomData_get_layer_index_n(&bm->ldata, CD_MLOOPUV, ren_uv_n); + if (ren_uv_index >= 0) { + int tan_index = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, bm->ldata.layers[ren_uv_index].name); + CustomData_set_layer_render_index(&dm->loopData, CD_TANGENT, tan_index); + } /* else tangent has been built from orco */ } /** \} */ diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 4eee24b378f..38f5c00941c 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -986,19 +986,19 @@ static void do_physical_effector(EffectorCache *eff, EffectorData *efd, Effected */ void pdDoEffectors(ListBase *effectors, ListBase *colliders, EffectorWeights *weights, EffectedPoint *point, float *force, float *impulse) { -/* - * Modifies the force on a particle according to its - * relation with the effector object - * Different kind of effectors include: - * Forcefields: Gravity-like attractor - * (force power is related to the inverse of distance to the power of a falloff value) - * Vortex fields: swirling effectors - * (particles rotate around Z-axis of the object. otherwise, same relation as) - * (Forcefields, but this is not done through a force/acceleration) - * Guide: particles on a path - * (particles are guided along a curve bezier or old nurbs) - * (is independent of other effectors) - */ + /* + * Modifies the force on a particle according to its + * relation with the effector object + * Different kind of effectors include: + * Forcefields: Gravity-like attractor + * (force power is related to the inverse of distance to the power of a falloff value) + * Vortex fields: swirling effectors + * (particles rotate around Z-axis of the object. otherwise, same relation as) + * (Forcefields, but this is not done through a force/acceleration) + * Guide: particles on a path + * (particles are guided along a curve bezier or old nurbs) + * (is independent of other effectors) + */ EffectorCache *eff; EffectorData efd; int p=0, tot = 1, step = 1; diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 7dbc43e0a32..db6c533ab57 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -126,7 +126,7 @@ void free_fcurves(ListBase *list) /* ---------------------- Copy --------------------------- */ /* duplicate an F-Curve */ -FCurve *copy_fcurve(FCurve *fcu) +FCurve *copy_fcurve(const FCurve *fcu) { FCurve *fcu_d; @@ -1805,7 +1805,7 @@ void fcurve_free_driver(FCurve *fcu) } /* This makes a copy of the given driver */ -ChannelDriver *fcurve_copy_driver(ChannelDriver *driver) +ChannelDriver *fcurve_copy_driver(const ChannelDriver *driver) { ChannelDriver *ndriver; @@ -1945,7 +1945,7 @@ float evaluate_driver(PathResolvedRNA *anim_rna, ChannelDriver *driver, const fl BLI_mutex_unlock(&python_driver_lock); } #else /* WITH_PYTHON*/ - (void)evaltime; + UNUSED_VARS(anim_rna, evaltime); #endif /* WITH_PYTHON*/ break; } diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c index 2c301c04100..f1732ee7a9a 100644 --- a/source/blender/blenkernel/intern/fmodifier.c +++ b/source/blender/blenkernel/intern/fmodifier.c @@ -116,7 +116,7 @@ static void fcm_generator_free(FModifier *fcm) MEM_freeN(data->coefficients); } -static void fcm_generator_copy(FModifier *fcm, FModifier *src) +static void fcm_generator_copy(FModifier *fcm, const FModifier *src) { FMod_Generator *gen = (FMod_Generator *)fcm->data; FMod_Generator *ogen = (FMod_Generator *)src->data; @@ -386,7 +386,7 @@ static void fcm_envelope_free(FModifier *fcm) MEM_freeN(env->data); } -static void fcm_envelope_copy(FModifier *fcm, FModifier *src) +static void fcm_envelope_copy(FModifier *fcm, const FModifier *src) { FMod_Envelope *env = (FMod_Envelope *)fcm->data; FMod_Envelope *oenv = (FMod_Envelope *)src->data; @@ -877,7 +877,7 @@ static void fcm_python_new_data(void *mdata) data->prop->type = IDP_GROUP; } -static void fcm_python_copy(FModifier *fcm, FModifier *src) +static void fcm_python_copy(FModifier *fcm, const FModifier *src) { FMod_Python *pymod = (FMod_Python *)fcm->data; FMod_Python *opymod = (FMod_Python *)src->data; @@ -1040,7 +1040,7 @@ static void fmods_init_typeinfo(void) /* This function should be used for getting the appropriate type-info when only * a F-Curve modifier type is known */ -const FModifierTypeInfo *get_fmodifier_typeinfo(int type) +const FModifierTypeInfo *get_fmodifier_typeinfo(const int type) { /* initialize the type-info list? */ if (FMI_INIT) { @@ -1065,7 +1065,7 @@ const FModifierTypeInfo *get_fmodifier_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. */ -const FModifierTypeInfo *fmodifier_get_typeinfo(FModifier *fcm) +const FModifierTypeInfo *fmodifier_get_typeinfo(const FModifier *fcm) { /* only return typeinfo for valid modifiers */ if (fcm) @@ -1117,7 +1117,7 @@ FModifier *add_fmodifier(ListBase *modifiers, int type) } /* Make a copy of the specified F-Modifier */ -FModifier *copy_fmodifier(FModifier *src) +FModifier *copy_fmodifier(const FModifier *src) { const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(src); FModifier *dst; @@ -1142,7 +1142,7 @@ FModifier *copy_fmodifier(FModifier *src) } /* Duplicate all of the F-Modifiers in the Modifier stacks */ -void copy_fmodifiers(ListBase *dst, ListBase *src) +void copy_fmodifiers(ListBase *dst, const ListBase *src) { FModifier *fcm, *srcfcm; diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index 30fc8915d46..758438bb051 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -754,7 +754,7 @@ bGPDlayer *BKE_gpencil_layer_duplicate(const bGPDlayer *gpl_src) } /* make a copy of a given gpencil datablock */ -bGPdata *BKE_gpencil_data_duplicate(Main *bmain, bGPdata *gpd_src, bool internal_copy) +bGPdata *BKE_gpencil_data_duplicate(Main *bmain, const bGPdata *gpd_src, bool internal_copy) { const bGPDlayer *gpl_src; bGPDlayer *gpl_dst; diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c index 9b011dbb003..932f41ac4ba 100644 --- a/source/blender/blenkernel/intern/group.c +++ b/source/blender/blenkernel/intern/group.c @@ -80,6 +80,8 @@ Group *BKE_group_add(Main *bmain, const char *name) Group *group; group = BKE_libblock_alloc(bmain, ID_GR, name); + id_us_min(&group->id); + id_us_ensure_real(&group->id); group->layer = (1 << 20) - 1; group->preview = NULL; @@ -87,7 +89,7 @@ Group *BKE_group_add(Main *bmain, const char *name) return group; } -Group *BKE_group_copy(Main *bmain, Group *group) +Group *BKE_group_copy(Main *bmain, const Group *group) { Group *groupn; diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c index 7669c4ba112..bccf9307912 100644 --- a/source/blender/blenkernel/intern/icons.c +++ b/source/blender/blenkernel/intern/icons.c @@ -204,7 +204,7 @@ void BKE_previewimg_clear(struct PreviewImage *prv) } } -PreviewImage *BKE_previewimg_copy(PreviewImage *prv) +PreviewImage *BKE_previewimg_copy(const PreviewImage *prv) { PreviewImage *prv_img = NULL; int i; @@ -222,7 +222,7 @@ PreviewImage *BKE_previewimg_copy(PreviewImage *prv) } /** Duplicate preview image from \a id and clear icon_id, to be used by datablock copy functions. */ -void BKE_previewimg_id_copy(ID *new_id, ID *old_id) +void BKE_previewimg_id_copy(ID *new_id, const ID *old_id) { PreviewImage **old_prv_p = BKE_previewimg_id_get_p(old_id); PreviewImage **new_prv_p = BKE_previewimg_id_get_p(new_id); @@ -239,7 +239,7 @@ void BKE_previewimg_id_copy(ID *new_id, ID *old_id) } } -PreviewImage **BKE_previewimg_id_get_p(ID *id) +PreviewImage **BKE_previewimg_id_get_p(const ID *id) { switch (GS(id->name)) { #define ID_PRV_CASE(id_code, id_struct) case id_code: { return &((id_struct *)id)->preview; } ((void)0) diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 9b28d9732e5..abe08def197 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -434,7 +434,7 @@ static void copy_image_packedfiles(ListBase *lb_dst, const ListBase *lb_src) } /* empty image block, of similar type and filename */ -Image *BKE_image_copy(Main *bmain, Image *ima) +Image *BKE_image_copy(Main *bmain, const Image *ima) { Image *nima = image_alloc(bmain, ima->id.name + 2, ima->source, ima->type); @@ -2863,7 +2863,7 @@ bool BKE_image_is_stereo(Image *ima) { return BKE_image_is_multiview(ima) && (BLI_findstring(&ima->views, STEREO_LEFT_NAME, offsetof(ImageView, name)) && - BLI_findstring(&ima->views, STEREO_RIGHT_NAME, offsetof(ImageView, name))); + BLI_findstring(&ima->views, STEREO_RIGHT_NAME, offsetof(ImageView, name))); } static void image_init_multilayer_multiview(Image *ima, RenderResult *rr) diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 8a7c1dd2833..98b251294ae 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -151,7 +151,7 @@ Key *BKE_key_add(ID *id) /* common function */ return key; } -Key *BKE_key_copy(Main *bmain, Key *key) +Key *BKE_key_copy(Main *bmain, const Key *key) { Key *keyn; KeyBlock *kbn, *kb; diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c index 69a2067f4e6..2242ba379fb 100644 --- a/source/blender/blenkernel/intern/lamp.c +++ b/source/blender/blenkernel/intern/lamp.c @@ -116,7 +116,7 @@ Lamp *BKE_lamp_add(Main *bmain, const char *name) return la; } -Lamp *BKE_lamp_copy(Main *bmain, Lamp *la) +Lamp *BKE_lamp_copy(Main *bmain, const Lamp *la) { Lamp *lan; int a; diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 54cfae620a1..c9d7dddf25a 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -277,7 +277,7 @@ Lattice *BKE_lattice_add(Main *bmain, const char *name) return lt; } -Lattice *BKE_lattice_copy(Main *bmain, Lattice *lt) +Lattice *BKE_lattice_copy(Main *bmain, const Lattice *lt) { Lattice *ltn; diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index c249577686e..2ea7342ff34 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -307,7 +307,7 @@ void BKE_id_expand_local(Main *bmain, ID *id) /** * Ensure new (copied) ID is fully made local. */ -void BKE_id_copy_ensure_local(Main *bmain, ID *old_id, ID *new_id) +void BKE_id_copy_ensure_local(Main *bmain, const ID *old_id, ID *new_id) { if (ID_IS_LINKED_DATABLOCK(old_id)) { BKE_id_expand_local(bmain, new_id); @@ -488,7 +488,7 @@ bool id_make_local(Main *bmain, ID *id, const bool test, const bool lib_local) * Invokes the appropriate copy method for the block and returns the result in * newid, unless test. Returns true if the block can be copied. */ -bool id_copy(Main *bmain, ID *id, ID **newid, bool test) +bool id_copy(Main *bmain, const ID *id, ID **newid, bool test) { if (!test) { *newid = NULL; @@ -858,118 +858,72 @@ int set_listbasepointers(Main *main, ListBase **lb) * **************************** */ /** + * Get allocation size fo a given datablock type and optionally allocation name. + */ +size_t BKE_libblock_get_alloc_info(short type, const char **name) +{ +#define CASE_RETURN(id_code, type) \ + case id_code: \ + do { \ + if (name != NULL) { \ + *name = #type; \ + } \ + return sizeof(type); \ + } while(0) + + switch ((ID_Type)type) { + CASE_RETURN(ID_SCE, Scene); + CASE_RETURN(ID_LI, Library); + CASE_RETURN(ID_OB, Object); + CASE_RETURN(ID_ME, Mesh); + CASE_RETURN(ID_CU, Curve); + CASE_RETURN(ID_MB, MetaBall); + CASE_RETURN(ID_MA, Material); + CASE_RETURN(ID_TE, Tex); + CASE_RETURN(ID_IM, Image); + CASE_RETURN(ID_LT, Lattice); + CASE_RETURN(ID_LA, Lamp); + CASE_RETURN(ID_CA, Camera); + CASE_RETURN(ID_IP, Ipo); + CASE_RETURN(ID_KE, Key); + CASE_RETURN(ID_WO, World); + CASE_RETURN(ID_SCR, bScreen); + CASE_RETURN(ID_VF, VFont); + CASE_RETURN(ID_TXT, Text); + CASE_RETURN(ID_SPK, Speaker); + CASE_RETURN(ID_SO, bSound); + CASE_RETURN(ID_GR, Group); + CASE_RETURN(ID_AR, bArmature); + CASE_RETURN(ID_AC, bAction); + CASE_RETURN(ID_NT, bNodeTree); + CASE_RETURN(ID_BR, Brush); + CASE_RETURN(ID_PA, ParticleSettings); + CASE_RETURN(ID_WM, wmWindowManager); + CASE_RETURN(ID_GD, bGPdata); + CASE_RETURN(ID_MC, MovieClip); + CASE_RETURN(ID_MSK, Mask); + CASE_RETURN(ID_LS, FreestyleLineStyle); + CASE_RETURN(ID_PAL, Palette); + CASE_RETURN(ID_PC, PaintCurve); + CASE_RETURN(ID_CF, CacheFile); + } + return 0; +#undef CASE_RETURN +} + +/** * Allocates and returns memory of the right size for the specified block type, * initialized to zero. */ void *BKE_libblock_alloc_notest(short type) { - ID *id = NULL; - - switch ((ID_Type)type) { - case ID_SCE: - id = MEM_callocN(sizeof(Scene), "scene"); - break; - case ID_LI: - id = MEM_callocN(sizeof(Library), "library"); - break; - case ID_OB: - id = MEM_callocN(sizeof(Object), "object"); - break; - case ID_ME: - id = MEM_callocN(sizeof(Mesh), "mesh"); - break; - case ID_CU: - id = MEM_callocN(sizeof(Curve), "curve"); - break; - case ID_MB: - id = MEM_callocN(sizeof(MetaBall), "mball"); - break; - case ID_MA: - id = MEM_callocN(sizeof(Material), "mat"); - break; - case ID_TE: - id = MEM_callocN(sizeof(Tex), "tex"); - break; - case ID_IM: - id = MEM_callocN(sizeof(Image), "image"); - break; - case ID_LT: - id = MEM_callocN(sizeof(Lattice), "latt"); - break; - case ID_LA: - id = MEM_callocN(sizeof(Lamp), "lamp"); - break; - case ID_CA: - id = MEM_callocN(sizeof(Camera), "camera"); - break; - case ID_IP: - id = MEM_callocN(sizeof(Ipo), "ipo"); - break; - case ID_KE: - id = MEM_callocN(sizeof(Key), "key"); - break; - case ID_WO: - id = MEM_callocN(sizeof(World), "world"); - break; - case ID_SCR: - id = MEM_callocN(sizeof(bScreen), "screen"); - break; - case ID_VF: - id = MEM_callocN(sizeof(VFont), "vfont"); - break; - case ID_TXT: - id = MEM_callocN(sizeof(Text), "text"); - break; - case ID_SPK: - id = MEM_callocN(sizeof(Speaker), "speaker"); - break; - case ID_SO: - id = MEM_callocN(sizeof(bSound), "sound"); - break; - case ID_GR: - id = MEM_callocN(sizeof(Group), "group"); - break; - case ID_AR: - id = MEM_callocN(sizeof(bArmature), "armature"); - break; - case ID_AC: - id = MEM_callocN(sizeof(bAction), "action"); - break; - case ID_NT: - id = MEM_callocN(sizeof(bNodeTree), "nodetree"); - break; - case ID_BR: - id = MEM_callocN(sizeof(Brush), "brush"); - break; - case ID_PA: - id = MEM_callocN(sizeof(ParticleSettings), "ParticleSettings"); - break; - case ID_WM: - id = MEM_callocN(sizeof(wmWindowManager), "Window manager"); - break; - case ID_GD: - id = MEM_callocN(sizeof(bGPdata), "Grease Pencil"); - break; - case ID_MC: - id = MEM_callocN(sizeof(MovieClip), "Movie Clip"); - break; - case ID_MSK: - id = MEM_callocN(sizeof(Mask), "Mask"); - break; - case ID_LS: - id = MEM_callocN(sizeof(FreestyleLineStyle), "Freestyle Line Style"); - break; - case ID_PAL: - id = MEM_callocN(sizeof(Palette), "Palette"); - break; - case ID_PC: - id = MEM_callocN(sizeof(PaintCurve), "Paint Curve"); - break; - case ID_CF: - id = MEM_callocN(sizeof(CacheFile), "Cache File"); - break; + const char *name; + size_t size = BKE_libblock_get_alloc_info(type, &name); + if (size != 0) { + return MEM_callocN(size, name); } - return id; + BLI_assert(!"Request to allocate unknown data type"); + return NULL; } /** @@ -1138,7 +1092,7 @@ void BKE_libblock_copy_data(ID *id, const ID *id_from, const bool do_action) } /* used everywhere in blenkernel */ -void *BKE_libblock_copy(Main *bmain, ID *id) +void *BKE_libblock_copy(Main *bmain, const ID *id) { ID *idn; size_t idn_len; @@ -1160,7 +1114,7 @@ void *BKE_libblock_copy(Main *bmain, ID *id) return idn; } -void *BKE_libblock_copy_nolib(ID *id, const bool do_action) +void *BKE_libblock_copy_nolib(const ID *id, const bool do_action) { ID *idn; size_t idn_len; diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c index 931002e6bbc..d1f0c87183d 100644 --- a/source/blender/blenkernel/intern/library_query.c +++ b/source/blender/blenkernel/intern/library_query.c @@ -512,7 +512,8 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call /* Object is special, proxies make things hard... */ const int data_cb_flag = data.cb_flag; - const int proxy_cb_flag = (object->proxy || object->proxy_group) ? IDWALK_CB_INDIRECT_USAGE : 0; + const int proxy_cb_flag = ((data.flag & IDWALK_NO_INDIRECT_PROXY_DATA_USAGE) == 0 && (object->proxy || object->proxy_group)) ? + IDWALK_CB_INDIRECT_USAGE : 0; /* object data special case */ data.cb_flag |= proxy_cb_flag; diff --git a/source/blender/blenkernel/intern/library_remap.c b/source/blender/blenkernel/intern/library_remap.c index 24626c6ead7..5e5ba44f039 100644 --- a/source/blender/blenkernel/intern/library_remap.c +++ b/source/blender/blenkernel/intern/library_remap.c @@ -419,6 +419,7 @@ ATTR_NONNULL(1) static void libblock_remap_data( IDRemap id_remap_data; ListBase *lb_array[MAX_LIBARRAY]; int i; + const int foreach_id_flags = (remap_flags & ID_REMAP_NO_INDIRECT_PROXY_DATA_USAGE) != 0 ? IDWALK_NO_INDIRECT_PROXY_DATA_USAGE : IDWALK_NOP; if (r_id_remap_data == NULL) { r_id_remap_data = &id_remap_data; @@ -439,7 +440,7 @@ ATTR_NONNULL(1) static void libblock_remap_data( #endif r_id_remap_data->id = id; libblock_remap_data_preprocess(r_id_remap_data); - BKE_library_foreach_ID_link(NULL, id, foreach_libblock_remap_callback, (void *)r_id_remap_data, IDWALK_NOP); + BKE_library_foreach_ID_link(NULL, id, foreach_libblock_remap_callback, (void *)r_id_remap_data, foreach_id_flags); } else { i = set_listbasepointers(bmain, lb_array); @@ -456,7 +457,7 @@ ATTR_NONNULL(1) static void libblock_remap_data( r_id_remap_data->id = id_curr; libblock_remap_data_preprocess(r_id_remap_data); BKE_library_foreach_ID_link( - NULL, id_curr, foreach_libblock_remap_callback, (void *)r_id_remap_data, IDWALK_NOP); + NULL, id_curr, foreach_libblock_remap_callback, (void *)r_id_remap_data, foreach_id_flags); } } } @@ -723,7 +724,7 @@ void BKE_libblock_relink_to_newid(ID *id) BKE_library_foreach_ID_link(NULL, id, id_relink_to_newid_looper, NULL, 0); } -void BKE_libblock_free_data(Main *UNUSED(bmain), ID *id, const bool do_id_user) +void BKE_libblock_free_data(ID *id, const bool do_id_user) { if (id->properties) { IDP_FreeProperty_ex(id->properties, do_id_user); @@ -731,30 +732,9 @@ void BKE_libblock_free_data(Main *UNUSED(bmain), ID *id, const bool do_id_user) } } -/** - * used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c - * - * \param do_id_user: if \a true, try to release other ID's 'references' hold by \a idv. - * (only applies to main database) - * \param do_ui_user: similar to do_id_user but makes sure UI does not hold references to - * \a id. - */ -void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user, const bool do_ui_user) +void BKE_libblock_free_datablock(ID *id) { - ID *id = idv; - short type = GS(id->name); - ListBase *lb = which_libbase(bmain, type); - - DAG_id_type_tag(bmain, type); - -#ifdef WITH_PYTHON - BPY_id_release(id); -#endif - - if (do_id_user) { - BKE_libblock_relink_ex(bmain, id, NULL, NULL, true); - } - + const short type = GS(id->name); switch (type) { case ID_SCE: BKE_scene_free((Scene *)id); @@ -860,6 +840,33 @@ void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user, const b BKE_cachefile_free((CacheFile *)id); break; } +} + +/** + * used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c + * + * \param do_id_user: if \a true, try to release other ID's 'references' hold by \a idv. + * (only applies to main database) + * \param do_ui_user: similar to do_id_user but makes sure UI does not hold references to + * \a id. + */ +void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user, const bool do_ui_user) +{ + ID *id = idv; + short type = GS(id->name); + ListBase *lb = which_libbase(bmain, type); + + DAG_id_type_tag(bmain, type); + +#ifdef WITH_PYTHON + BPY_id_release(id); +#endif + + if (do_id_user) { + BKE_libblock_relink_ex(bmain, id, NULL, NULL, true); + } + + BKE_libblock_free_datablock(id); /* avoid notifying on removed data */ BKE_main_lock(bmain); @@ -876,7 +883,7 @@ void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user, const b BLI_remlink(lb, id); - BKE_libblock_free_data(bmain, id, do_id_user); + BKE_libblock_free_data(id, do_id_user); BKE_main_unlock(bmain); MEM_freeN(id); diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c index 1eb909bd9f9..771e81ddc4f 100644 --- a/source/blender/blenkernel/intern/linestyle.c +++ b/source/blender/blenkernel/intern/linestyle.c @@ -155,7 +155,7 @@ void BKE_linestyle_free(FreestyleLineStyle *linestyle) BKE_linestyle_geometry_modifier_remove(linestyle, m); } -FreestyleLineStyle *BKE_linestyle_copy(struct Main *bmain, FreestyleLineStyle *linestyle) +FreestyleLineStyle *BKE_linestyle_copy(struct Main *bmain, const FreestyleLineStyle *linestyle) { FreestyleLineStyle *new_linestyle; LineStyleModifier *m; @@ -355,7 +355,7 @@ LineStyleModifier *BKE_linestyle_color_modifier_add(FreestyleLineStyle *linestyl return m; } -LineStyleModifier *BKE_linestyle_color_modifier_copy(FreestyleLineStyle *linestyle, LineStyleModifier *m) +LineStyleModifier *BKE_linestyle_color_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m) { LineStyleModifier *new_m; @@ -594,7 +594,7 @@ LineStyleModifier *BKE_linestyle_alpha_modifier_add(FreestyleLineStyle *linestyl return m; } -LineStyleModifier *BKE_linestyle_alpha_modifier_copy(FreestyleLineStyle *linestyle, LineStyleModifier *m) +LineStyleModifier *BKE_linestyle_alpha_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m) { LineStyleModifier *new_m; @@ -863,7 +863,7 @@ LineStyleModifier *BKE_linestyle_thickness_modifier_add(FreestyleLineStyle *line return m; } -LineStyleModifier *BKE_linestyle_thickness_modifier_copy(FreestyleLineStyle *linestyle, LineStyleModifier *m) +LineStyleModifier *BKE_linestyle_thickness_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m) { LineStyleModifier *new_m; @@ -1195,7 +1195,7 @@ LineStyleModifier *BKE_linestyle_geometry_modifier_add(FreestyleLineStyle *lines return m; } -LineStyleModifier *BKE_linestyle_geometry_modifier_copy(FreestyleLineStyle *linestyle, LineStyleModifier *m) +LineStyleModifier *BKE_linestyle_geometry_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m) { LineStyleModifier *new_m; diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 6f23b82c6df..ae27e9bcd34 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -192,7 +192,7 @@ void BKE_mask_layer_rename(Mask *mask, MaskLayer *masklay, char *oldname, char * BKE_animdata_fix_paths_rename_all(&mask->id, "layers", oldname, masklay->name); } -MaskLayer *BKE_mask_layer_copy(MaskLayer *masklay) +MaskLayer *BKE_mask_layer_copy(const MaskLayer *masklay) { MaskLayer *masklay_new; MaskSpline *spline; @@ -236,7 +236,7 @@ MaskLayer *BKE_mask_layer_copy(MaskLayer *masklay) return masklay_new; } -void BKE_mask_layer_copy_list(ListBase *masklayers_new, ListBase *masklayers) +void BKE_mask_layer_copy_list(ListBase *masklayers_new, const ListBase *masklayers) { MaskLayer *layer; @@ -840,7 +840,7 @@ Mask *BKE_mask_copy_nolib(Mask *mask) return mask_new; } -Mask *BKE_mask_copy(Main *bmain, Mask *mask) +Mask *BKE_mask_copy(Main *bmain, const Mask *mask) { Mask *mask_new; @@ -851,7 +851,7 @@ Mask *BKE_mask_copy(Main *bmain, Mask *mask) BKE_mask_layer_copy_list(&mask_new->masklayers, &mask->masklayers); /* enable fake user by default */ - id_fake_user_set(&mask->id); + id_fake_user_set(&mask_new->id); BKE_id_copy_ensure_local(bmain, &mask->id, &mask_new->id); @@ -906,7 +906,7 @@ void BKE_mask_spline_free_list(ListBase *splines) } } -static MaskSplinePoint *mask_spline_points_copy(MaskSplinePoint *points, int tot_point) +static MaskSplinePoint *mask_spline_points_copy(const MaskSplinePoint *points, int tot_point) { MaskSplinePoint *npoints; int i; @@ -923,7 +923,7 @@ static MaskSplinePoint *mask_spline_points_copy(MaskSplinePoint *points, int tot return npoints; } -MaskSpline *BKE_mask_spline_copy(MaskSpline *spline) +MaskSpline *BKE_mask_spline_copy(const MaskSpline *spline) { MaskSpline *nspline = MEM_callocN(sizeof(MaskSpline), "new spline"); diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 54945242fe4..f21efb71180 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -220,7 +220,7 @@ Material *BKE_material_add(Main *bmain, const char *name) } /* XXX keep synced with next function */ -Material *BKE_material_copy(Main *bmain, Material *ma) +Material *BKE_material_copy(Main *bmain, const Material *ma) { Material *man; int a; diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index 97033a9555d..b80579014d6 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -103,7 +103,7 @@ MetaBall *BKE_mball_add(Main *bmain, const char *name) return mb; } -MetaBall *BKE_mball_copy(Main *bmain, MetaBall *mb) +MetaBall *BKE_mball_copy(Main *bmain, const MetaBall *mb) { MetaBall *mbn; int a; diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index c12890a354e..6233caa43fa 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -501,7 +501,7 @@ Mesh *BKE_mesh_add(Main *bmain, const char *name) return me; } -Mesh *BKE_mesh_copy(Main *bmain, Mesh *me) +Mesh *BKE_mesh_copy(Main *bmain, const Mesh *me) { Mesh *men; int a; @@ -1339,7 +1339,7 @@ int BKE_mesh_nurbs_displist_to_mdata( /* this may fail replacing ob->data, be sure to check ob->type */ -void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const bool use_orco_uv) +void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const bool use_orco_uv, const char *obdata_name) { Main *bmain = G.main; Object *ob1; @@ -1366,7 +1366,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const bool use } /* make mesh */ - me = BKE_mesh_add(bmain, "Mesh"); + me = BKE_mesh_add(bmain, obdata_name); me->totvert = totvert; me->totedge = totedge; me->totloop = totloop; @@ -1386,7 +1386,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const bool use BKE_mesh_calc_normals(me); } else { - me = BKE_mesh_add(bmain, "Mesh"); + me = BKE_mesh_add(bmain, obdata_name); DM_to_mesh(dm, me, ob, CD_MASK_MESH, false); } @@ -1398,9 +1398,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const bool use cu->mat = NULL; cu->totcol = 0; - if (ob->data) { - BKE_libblock_free(bmain, ob->data); - } + /* Do not decrement ob->data usercount here, it's done at end of func with BKE_libblock_free_us() call. */ ob->data = me; ob->type = OB_MESH; @@ -1410,11 +1408,14 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const bool use if (ob1->data == cu) { ob1->type = OB_MESH; + id_us_min((ID *)ob1->data); ob1->data = ob->data; - id_us_plus((ID *)ob->data); + id_us_plus((ID *)ob1->data); } ob1 = ob1->id.next; } + + BKE_libblock_free_us(bmain, cu); } void BKE_mesh_from_nurbs(Object *ob) @@ -1427,7 +1428,7 @@ void BKE_mesh_from_nurbs(Object *ob) disp = ob->curve_cache->disp; } - BKE_mesh_from_nurbs_displist(ob, &disp, use_orco_uv); + BKE_mesh_from_nurbs_displist(ob, &disp, use_orco_uv, cu->id.name); } typedef struct EdgeLink { @@ -2486,7 +2487,7 @@ Mesh *BKE_mesh_new_from_object( /* convert object type to mesh */ uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0; - BKE_mesh_from_nurbs_displist(tmpobj, &dispbase, uv_from_orco); + BKE_mesh_from_nurbs_displist(tmpobj, &dispbase, uv_from_orco, tmpcu->id.name + 2); tmpmesh = tmpobj->data; @@ -2522,7 +2523,7 @@ Mesh *BKE_mesh_new_from_object( if (ob != basis_ob) return NULL; /* only do basis metaball */ - tmpmesh = BKE_mesh_add(bmain, "Mesh"); + tmpmesh = BKE_mesh_add(bmain, ((ID *)ob->data)->name + 2); /* BKE_mesh_add gives us a user count we don't need */ id_us_min(&tmpmesh->id); @@ -2577,7 +2578,7 @@ Mesh *BKE_mesh_new_from_object( else dm = mesh_create_derived_view(sce, ob, mask); - tmpmesh = BKE_mesh_add(bmain, "Mesh"); + tmpmesh = BKE_mesh_add(bmain, ((ID *)ob->data)->name + 2); DM_to_mesh(dm, tmpmesh, ob, mask, true); /* Copy autosmooth settings from original mesh. */ diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index 37f4477febf..5dfcef9f9bf 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -1629,8 +1629,8 @@ void BKE_mesh_normals_loop_custom_from_vertices_set( /** * Computes average per-vertex normals from given custom loop normals. * - * @param clnors The computed custom loop normals. - * @param r_vert_clnors The (already allocated) array where to store averaged per-vertex normals. + * \param clnors: The computed custom loop normals. + * \param r_vert_clnors: The (already allocated) array where to store averaged per-vertex normals. */ void BKE_mesh_normals_loop_to_vertex( const int numVerts, const MLoop *mloops, const int numLoops, diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c index 8562988b5e1..525c0c9728e 100644 --- a/source/blender/blenkernel/intern/mesh_mapping.c +++ b/source/blender/blenkernel/intern/mesh_mapping.c @@ -165,7 +165,7 @@ UvVertMap *BKE_mesh_uv_vert_map_create( vmap->vert[a] = newvlist; } - if (use_winding) { + if (use_winding) { MEM_freeN(winding); } diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 6794a8e8f93..dfa8742a295 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -1488,7 +1488,7 @@ void BKE_movieclip_free(MovieClip *clip) BKE_animdata_free((ID *) clip, false); } -MovieClip *BKE_movieclip_copy(Main *bmain, MovieClip *clip) +MovieClip *BKE_movieclip_copy(Main *bmain, const MovieClip *clip) { MovieClip *clip_new; diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 63da1b5f9e7..78323557ae2 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -921,7 +921,7 @@ static void node_socket_copy(bNodeSocket *dst, bNodeSocket *src) /* keep socket listorder identical, for copying links */ /* ntree is the target tree */ -bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node) +bNode *nodeCopyNode(bNodeTree *ntree, bNode *node) { bNode *nnode = MEM_callocN(sizeof(bNode), "dupli node"); bNodeSocket *sock, *oldsock; @@ -1200,7 +1200,9 @@ bNodeTree *ntreeAddTree(Main *bmain, const char *name, const char *idname) * copying for internal use (threads for eg), where you wont want it to modify the * scene data. */ -static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, Main *bmain, bool skip_database, bool do_id_user, bool do_make_extern, bool copy_previews) +static bNodeTree *ntreeCopyTree_internal( + const bNodeTree *ntree, Main *bmain, + bool skip_database, bool do_id_user, bool do_make_extern, bool copy_previews) { bNodeTree *newtree; bNode *node /*, *nnode */ /* UNUSED */, *last; @@ -1299,11 +1301,11 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, Main *bmain, bool ski return newtree; } -bNodeTree *ntreeCopyTree_ex(bNodeTree *ntree, Main *bmain, const bool do_id_user) +bNodeTree *ntreeCopyTree_ex(const bNodeTree *ntree, Main *bmain, const bool do_id_user) { return ntreeCopyTree_internal(ntree, bmain, false, do_id_user, true, true); } -bNodeTree *ntreeCopyTree(Main *bmain, bNodeTree *ntree) +bNodeTree *ntreeCopyTree(Main *bmain, const bNodeTree *ntree) { return ntreeCopyTree_ex(ntree, bmain, true); } @@ -1828,7 +1830,7 @@ void ntreeFreeTree(bNodeTree *ntree) if (tntree == ntree) break; if (tntree == NULL) { - BKE_libblock_free_data(G.main, &ntree->id, true); + BKE_libblock_free_data(&ntree->id, true); } } @@ -3172,12 +3174,20 @@ void nodeSynchronizeID(bNode *node, bool copy_to_id) void nodeLabel(bNodeTree *ntree, bNode *node, char *label, int maxlen) { - if (node->label[0] != '\0') + if (node->label[0] != '\0') { BLI_strncpy(label, node->label, maxlen); - else if (node->typeinfo->labelfunc) + } + else if (node->typeinfo->labelfunc) { node->typeinfo->labelfunc(ntree, node, label, maxlen); - else - BLI_strncpy(label, IFACE_(node->typeinfo->ui_name), maxlen); + } + else { + /* Kind of hacky and weak... Ideally would be better to use RNA here. :| */ + const char *tmp = CTX_IFACE_(BLT_I18NCONTEXT_ID_NODETREE, node->typeinfo->ui_name); + if (tmp == node->typeinfo->ui_name) { + tmp = IFACE_(node->typeinfo->ui_name); + } + BLI_strncpy(label, tmp, maxlen); + } } static void node_type_base_defaults(bNodeType *ntype) diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index b65cc408ae5..f3086396c3a 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -882,7 +882,7 @@ SoftBody *copy_softbody(const SoftBody *sb, bool copy_caches) return sbn; } -BulletSoftBody *copy_bulletsoftbody(BulletSoftBody *bsb) +BulletSoftBody *copy_bulletsoftbody(const BulletSoftBody *bsb) { BulletSoftBody *bsbn; @@ -1014,7 +1014,7 @@ void BKE_object_copy_softbody(Object *ob_dst, const Object *ob_src) } } -static void copy_object_pose(Object *obn, Object *ob) +static void copy_object_pose(Object *obn, const Object *ob) { bPoseChannel *chan; @@ -1047,7 +1047,7 @@ static void copy_object_pose(Object *obn, Object *ob) } } -static void copy_object_lod(Object *obn, Object *ob) +static void copy_object_lod(Object *obn, const Object *ob) { BLI_duplicatelist(&obn->lodlevels, &ob->lodlevels); @@ -1098,7 +1098,7 @@ void BKE_object_transform_copy(Object *ob_tar, const Object *ob_src) copy_v3_v3(ob_tar->size, ob_src->size); } -Object *BKE_object_copy_ex(Main *bmain, Object *ob, bool copy_caches) +Object *BKE_object_copy_ex(Main *bmain, const Object *ob, bool copy_caches) { Object *obn; ModifierData *md; @@ -1187,7 +1187,7 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, bool copy_caches) } /* copy objects, will re-initialize cached simulation data */ -Object *BKE_object_copy(Main *bmain, Object *ob) +Object *BKE_object_copy(Main *bmain, const Object *ob) { return BKE_object_copy_ex(bmain, ob, false); } diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c index e9ebd397df0..076bef71875 100644 --- a/source/blender/blenkernel/intern/object_dupli.c +++ b/source/blender/blenkernel/intern/object_dupli.c @@ -547,10 +547,15 @@ static void make_duplis_verts(const DupliContext *ctx) BMEditMesh *em = BKE_editmesh_from_object(parent); CustomDataMask dm_mask = (use_texcoords ? CD_MASK_BAREMESH | CD_MASK_ORCO : CD_MASK_BAREMESH); - if (em) + if (ctx->eval_ctx->mode == DAG_EVAL_RENDER) { + vdd.dm = mesh_create_derived_render(scene, parent, dm_mask); + } + else if (em) { vdd.dm = editbmesh_get_derived_cage(scene, parent, em, dm_mask); - else + } + else { vdd.dm = mesh_get_derived_final(scene, parent, dm_mask); + } vdd.edit_btmesh = me->edit_btmesh; if (use_texcoords) @@ -810,10 +815,15 @@ static void make_duplis_faces(const DupliContext *ctx) BMEditMesh *em = BKE_editmesh_from_object(parent); CustomDataMask dm_mask = (use_texcoords ? CD_MASK_BAREMESH | CD_MASK_ORCO | CD_MASK_MLOOPUV : CD_MASK_BAREMESH); - if (em) + if (ctx->eval_ctx->mode == DAG_EVAL_RENDER) { + fdd.dm = mesh_create_derived_render(scene, parent, dm_mask); + } + else if (em) { fdd.dm = editbmesh_get_derived_cage(scene, parent, em, dm_mask); - else + } + else { fdd.dm = mesh_get_derived_final(scene, parent, dm_mask); + } if (use_texcoords) { CustomData *ml_data = fdd.dm->getLoopDataLayout(fdd.dm); diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c index a531466294e..e03af585cf2 100644 --- a/source/blender/blenkernel/intern/object_update.c +++ b/source/blender/blenkernel/intern/object_update.c @@ -145,18 +145,6 @@ void BKE_object_eval_done(EvaluationContext *UNUSED(eval_ctx), Object *ob) else ob->transflag &= ~OB_NEG_SCALE; } -void BKE_object_eval_modifier(struct EvaluationContext *eval_ctx, - struct Scene *scene, - struct Object *ob, - struct ModifierData *md) -{ - DEBUG_PRINT("%s on %s\n", __func__, ob->id.name); - (void) eval_ctx; /* Ignored. */ - (void) scene; /* Ignored. */ - (void) ob; /* Ignored. */ - (void) md; /* Ignored. */ -} - void BKE_object_handle_data_update(EvaluationContext *eval_ctx, Scene *scene, Object *ob) diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c index 621ac9c2480..537c8926a5b 100644 --- a/source/blender/blenkernel/intern/ocean.c +++ b/source/blender/blenkernel/intern/ocean.c @@ -334,10 +334,10 @@ void BKE_ocean_eval_uv(struct Ocean *oc, struct OceanResult *ocr, float u, float i1 = i1 % oc->_M; j1 = j1 % oc->_N; - #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); diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 195f67d2bd9..b83bd524618 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -314,7 +314,7 @@ PaintCurve *BKE_paint_curve_add(Main *bmain, const char *name) return pc; } -PaintCurve *BKE_paint_curve_copy(Main *bmain, PaintCurve *pc) +PaintCurve *BKE_paint_curve_copy(Main *bmain, const PaintCurve *pc) { PaintCurve *pc_new; @@ -396,7 +396,7 @@ Palette *BKE_palette_add(Main *bmain, const char *name) return palette; } -Palette *BKE_palette_copy(Main *bmain, Palette *palette) +Palette *BKE_palette_copy(Main *bmain, const Palette *palette) { Palette *palette_new; diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index bb5cea9dcc7..416d63cfefb 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -253,11 +253,16 @@ struct LatticeDeformData *psys_create_lattice_deform_data(ParticleSimulationData if (psys_in_edit_mode(sim->scene, sim->psys) == 0) { Object *lattice = NULL; ModifierData *md = (ModifierData *)psys_get_modifier(sim->ob, sim->psys); + int mode = G.is_rendering ? eModifierMode_Render : eModifierMode_Realtime; for (; md; md = md->next) { if (md->type == eModifierType_Lattice) { - LatticeModifierData *lmd = (LatticeModifierData *)md; - lattice = lmd->object; + if (md->mode & mode) { + LatticeModifierData *lmd = (LatticeModifierData *)md; + lattice = lmd->object; + sim->psys->lattice_strength = lmd->strength; + } + break; } } @@ -590,7 +595,7 @@ void psys_free(Object *ob, ParticleSystem *psys) BLI_bvhtree_free(psys->bvhtree); BLI_kdtree_free(psys->tree); - + if (psys->fluid_springs) MEM_freeN(psys->fluid_springs); @@ -2706,7 +2711,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re /* lattices have to be calculated separately to avoid mixups between effector calculations */ if (psys->lattice_deform_data) { for (k = 0, ca = cache[p]; k <= segments; k++, ca++) - calc_latt_deform(psys->lattice_deform_data, ca->co, 1.0f); + calc_latt_deform(psys->lattice_deform_data, ca->co, psys->lattice_strength); } } @@ -3326,7 +3331,7 @@ void BKE_particlesettings_rough_curve_init(ParticleSettings *part) part->roughcurve = cumap; } -ParticleSettings *BKE_particlesettings_copy(Main *bmain, ParticleSettings *part) +ParticleSettings *BKE_particlesettings_copy(Main *bmain, const ParticleSettings *part) { ParticleSettings *partn; int a; @@ -3369,7 +3374,8 @@ void BKE_particlesettings_make_local(Main *bmain, ParticleSettings *part, const /* Textures */ /************************************************/ -static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int face_index, const float fuv[4], char *name, float *texco) +static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int index, const float fuv[4], + char *name, float *texco, bool from_vert) { MFace *mf; MTFace *tf; @@ -3385,11 +3391,15 @@ static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int face_index, co if (pa) { i = ELEM(pa->num_dmcache, DMCACHE_NOTFOUND, DMCACHE_ISCHILD) ? pa->num : pa->num_dmcache; - if (i >= dm->getNumTessFaces(dm)) + if ((!from_vert && i >= dm->getNumTessFaces(dm)) || + (from_vert && i >= dm->getNumVerts(dm))) + { i = -1; + } + } + else { + i = index; } - else - i = face_index; if (i == -1) { texco[0] = 0.0f; @@ -3397,7 +3407,22 @@ static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int face_index, co texco[2] = 0.0f; } else { - mf = dm->getTessFaceData(dm, i, CD_MFACE); + if (from_vert) { + mf = dm->getTessFaceDataArray(dm, CD_MFACE); + + /* This finds the first face to contain the emitting vertex, + * this is not ideal, but is mostly fine as UV seams generally + * map to equal-colored parts of a texture */ + for (int j = 0; j < dm->getNumTessFaces(dm); j++, mf++) { + if (ELEM(i, mf->v1, mf->v2, mf->v3, mf->v4)) { + i = j; + break; + } + } + } + else { + mf = dm->getTessFaceData(dm, i, CD_MFACE); + } psys_interpolate_uvs(&tf[i], mf->v4, fuv, texco); @@ -3464,8 +3489,11 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti mul_m4_v3(mtex->object->imat, texvec); break; case TEXCO_UV: - if (fw && get_particle_uv(dm, NULL, face_index, fw, mtex->uvname, texvec)) + if (fw && get_particle_uv(dm, NULL, face_index, fw, mtex->uvname, + texvec, (part->from == PART_FROM_VERT))) + { break; + } /* no break, failed to get uv's, so let's try orco's */ ATTR_FALLTHROUGH; case TEXCO_ORCO: @@ -3537,8 +3565,11 @@ void psys_get_texture(ParticleSimulationData *sim, ParticleData *pa, ParticleTex mul_m4_v3(mtex->object->imat, texvec); break; case TEXCO_UV: - if (get_particle_uv(sim->psmd->dm_final, pa, 0, pa->fuv, mtex->uvname, texvec)) + if (get_particle_uv(sim->psmd->dm_final, pa, 0, pa->fuv, mtex->uvname, + texvec, (part->from == PART_FROM_VERT))) + { break; + } /* no break, failed to get uv's, so let's try orco's */ ATTR_FALLTHROUGH; case TEXCO_ORCO: @@ -3748,7 +3779,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey * } if (psys->lattice_deform_data && edit == 0) - calc_latt_deform(psys->lattice_deform_data, state->co, 1.0f); + calc_latt_deform(psys->lattice_deform_data, state->co, psys->lattice_strength); } } } @@ -3987,7 +4018,7 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta do_child_modifiers(NULL, sim, NULL, key1->co, key1->vel, key1->rot, par_orco, cpa, cpa->fuv, mat, state, t); if (psys->lattice_deform_data) - calc_latt_deform(psys->lattice_deform_data, state->co, 1.0f); + calc_latt_deform(psys->lattice_deform_data, state->co, psys->lattice_strength); } else { if (pa->state.time == cfra || ELEM(part->phystype, PART_PHYS_NO, PART_PHYS_KEYED)) @@ -4046,7 +4077,7 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta } if (sim->psys->lattice_deform_data) - calc_latt_deform(sim->psys->lattice_deform_data, state->co, 1.0f); + calc_latt_deform(sim->psys->lattice_deform_data, state->co, psys->lattice_strength); } return 1; @@ -4293,7 +4324,7 @@ void psys_apply_hair_lattice(Scene *scene, Object *ob, ParticleSystem *psys) hkey = pa->hair; for (h = 0; h < pa->totkey; h++, hkey++) { mul_m4_v3(hairmat, hkey->co); - calc_latt_deform(psys->lattice_deform_data, hkey->co, 1.0f); + calc_latt_deform(psys->lattice_deform_data, hkey->co, psys->lattice_strength); mul_m4_v3(imat, hkey->co); } } diff --git a/source/blender/blenkernel/intern/particle_child.c b/source/blender/blenkernel/intern/particle_child.c index 842de869291..bfcda89a635 100644 --- a/source/blender/blenkernel/intern/particle_child.c +++ b/source/blender/blenkernel/intern/particle_child.c @@ -355,9 +355,13 @@ void psys_apply_child_modifiers(ParticleThreadContext *ctx, struct ListBase *mod { const float step_length = 1.0f / (float)(totkeys - 1); - float cur_length = 0.0f; - + + if (max_length <= 0.0f) { + keys->segments = -1; + totkeys = 0; + } + /* we have to correct velocity because of kink & clump */ for (k = 0, key = keys; k < totkeys; ++k, ++key) { if (k >= 2) { diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c index 44cf5b119c1..4f758bde7f9 100644 --- a/source/blender/blenkernel/intern/particle_distribute.c +++ b/source/blender/blenkernel/intern/particle_distribute.c @@ -427,12 +427,38 @@ static int distribute_binary_search(float *sum, int n, float value) static void distribute_from_verts_exec(ParticleTask *thread, ParticleData *pa, int p) { ParticleThreadContext *ctx= thread->ctx; - int rng_skip_tot= PSYS_RND_DIST_SKIP; /* count how many rng_* calls wont need skipping */ + MFace *mface; + + DM_ensure_tessface(ctx->dm); + mface = ctx->dm->getTessFaceDataArray(ctx->dm, CD_MFACE); + + int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls wont need skipping */ /* TODO_PARTICLE - use original index */ - pa->num= ctx->index[p]; - pa->fuv[0] = 1.0f; - pa->fuv[1] = pa->fuv[2] = pa->fuv[3] = 0.0; + pa->num = ctx->index[p]; + + zero_v4(pa->fuv); + + if (pa->num != DMCACHE_NOTFOUND && pa->num < ctx->dm->getNumVerts(ctx->dm)) { + + /* This finds the first face to contain the emitting vertex, + * this is not ideal, but is mostly fine as UV seams generally + * map to equal-colored parts of a texture */ + for (int i = 0; i < ctx->dm->getNumTessFaces(ctx->dm); i++, mface++) { + if (ELEM(pa->num, mface->v1, mface->v2, mface->v3, mface->v4)) { + unsigned int *vert = &mface->v1; + + for (int j = 0; j < 4; j++, vert++) { + if (*vert == pa->num) { + pa->fuv[j] = 1.0f; + break; + } + } + + break; + } + } + } #if ONLY_WORKING_WITH_PA_VERTS if (ctx->tree) { @@ -1092,7 +1118,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti /* For hair, sort by origindex (allows optimization's in rendering), */ /* however with virtual parents the children need to be in random order. */ - if (part->type == PART_HAIR && !(part->childtype==PART_CHILD_FACES && part->parents!=0.0f)) { + if (part->type == PART_HAIR && !(part->childtype==PART_CHILD_FACES && part->parents != 0.0f)) { int *orig_index = NULL; if (from == PART_FROM_VERT) { diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 943dc781246..3f9a92a5577 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -1000,7 +1000,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, part=psys->part; /* get precise emitter matrix if particle is born */ - if (part->type!=PART_HAIR && dtime > 0.f && pa->time < cfra && pa->time >= sim->psys->cfra) { + if (part->type != PART_HAIR && dtime > 0.f && pa->time < cfra && pa->time >= sim->psys->cfra) { evaluate_emitter_anim(sim->scene, sim->ob, pa->time); psys->flag |= PSYS_OB_ANIM_RESTORE; @@ -1183,7 +1183,7 @@ static void set_keyed_keys(ParticleSimulationData *sim) key->time = pa->time; } - if (psys->flag & PSYS_KEYED_TIMING && pt->duration!=0.0f) + if (psys->flag & PSYS_KEYED_TIMING && pt->duration != 0.0f) k++; ksim.psys->flag |= keyed_flag; diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index dacaad8d703..53dfffe2b97 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -1113,7 +1113,7 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode) GPU_pbvh_bmesh_buffers_build(bvh->flags & PBVH_DYNTOPO_SMOOTH_SHADING); break; } - + node->flag &= ~PBVH_RebuildDrawBuffers; } diff --git a/source/blender/blenkernel/intern/property.c b/source/blender/blenkernel/intern/property.c index dc4063b42ed..b163f623d21 100644 --- a/source/blender/blenkernel/intern/property.c +++ b/source/blender/blenkernel/intern/property.c @@ -65,7 +65,7 @@ void BKE_bproperty_free_list(ListBase *lb) } } -bProperty *BKE_bproperty_copy(bProperty *prop) +bProperty *BKE_bproperty_copy(const bProperty *prop) { bProperty *propn; @@ -80,7 +80,7 @@ bProperty *BKE_bproperty_copy(bProperty *prop) return propn; } -void BKE_bproperty_copy_list(ListBase *lbn, ListBase *lbo) +void BKE_bproperty_copy_list(ListBase *lbn, const ListBase *lbo) { bProperty *prop, *propn; BKE_bproperty_free_list(lbn); /* in case we are copying to an object with props */ diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index b3a36bfb089..e8c0cf53d0b 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -184,7 +184,7 @@ void BKE_rigidbody_free_constraint(Object *ob) * be added to relevant groups later... */ -RigidBodyOb *BKE_rigidbody_copy_object(Object *ob) +RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob) { RigidBodyOb *rboN = NULL; @@ -204,7 +204,7 @@ RigidBodyOb *BKE_rigidbody_copy_object(Object *ob) return rboN; } -RigidBodyCon *BKE_rigidbody_copy_constraint(Object *ob) +RigidBodyCon *BKE_rigidbody_copy_constraint(const Object *ob) { RigidBodyCon *rbcN = NULL; @@ -1486,24 +1486,60 @@ 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) { RigidBodyOb *rbo = ob->rigidbody_object; + bool correct_delta = !(rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE); /* return rigid body and object to their initial states */ copy_v3_v3(rbo->pos, ob->loc); copy_v3_v3(ob->loc, loc); + if (correct_delta) { + add_v3_v3(rbo->pos, ob->dloc); + } + if (ob->rotmode > 0) { - eulO_to_quat(rbo->orn, ob->rot, ob->rotmode); + float qt[4]; + eulO_to_quat(qt, ob->rot, ob->rotmode); + + if (correct_delta) { + float dquat[4]; + eulO_to_quat(dquat, ob->drot, ob->rotmode); + + mul_qt_qtqt(rbo->orn, dquat, qt); + } + else { + copy_qt_qt(rbo->orn, qt); + } + copy_v3_v3(ob->rot, rot); } else if (ob->rotmode == ROT_MODE_AXISANGLE) { - axis_angle_to_quat(rbo->orn, ob->rotAxis, ob->rotAngle); + float qt[4]; + axis_angle_to_quat(qt, ob->rotAxis, ob->rotAngle); + + if (correct_delta) { + float dquat[4]; + axis_angle_to_quat(dquat, ob->drotAxis, ob->drotAngle); + + mul_qt_qtqt(rbo->orn, dquat, qt); + } + else { + copy_qt_qt(rbo->orn, qt); + } + copy_v3_v3(ob->rotAxis, rotAxis); ob->rotAngle = rotAngle; } else { - copy_qt_qt(rbo->orn, ob->quat); + if (correct_delta) { + mul_qt_qtqt(rbo->orn, ob->dquat, ob->quat); + } + 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) @@ -1515,8 +1551,9 @@ void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], flo void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw) { - if (rbw) + if (rbw) { rbw->pointcache->flag |= PTCACHE_OUTDATED; + } } /* ------------------ */ @@ -1563,12 +1600,8 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime) BKE_ptcache_id_time(&pid, scene, ctime, &startframe, &endframe, NULL); cache = rbw->pointcache; - if (ctime <= startframe) { - rbw->ltime = startframe; - return; - } /* make sure we don't go out of cache frame range */ - else if (ctime > endframe) { + if (ctime > endframe) { ctime = endframe; } @@ -1582,9 +1615,12 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime) // RB_TODO deal with interpolated, old and baked results bool can_simulate = (ctime == rbw->ltime + 1) && !(cache->flag & PTCACHE_BAKED); + if (cache->flag & PTCACHE_OUTDATED || cache->last_exact == 0) { + rbw->ltime = cache->startframe; + } + if (BKE_ptcache_read(&pid, ctime, can_simulate)) { BKE_ptcache_validate(cache, (int)ctime); - rbw->ltime = ctime; return; } @@ -1622,8 +1658,8 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime) # pragma GCC diagnostic ignored "-Wunused-parameter" #endif -struct RigidBodyOb *BKE_rigidbody_copy_object(Object *ob) { return NULL; } -struct RigidBodyCon *BKE_rigidbody_copy_constraint(Object *ob) { return NULL; } +struct RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob) { return NULL; } +struct RigidBodyCon *BKE_rigidbody_copy_constraint(const Object *ob) { return NULL; } void BKE_rigidbody_validate_sim_world(Scene *scene, RigidBodyWorld *rbw, bool rebuild) {} void BKE_rigidbody_calc_volume(Object *ob, float *r_vol) { if (r_vol) *r_vol = 0.0f; } void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3]) { zero_v3(r_center); } diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c index 7920d8b5696..19d646daf9f 100644 --- a/source/blender/blenkernel/intern/sca.c +++ b/source/blender/blenkernel/intern/sca.c @@ -87,7 +87,7 @@ bSensor *copy_sensor(bSensor *sens) return sensn; } -void copy_sensors(ListBase *lbn, ListBase *lbo) +void copy_sensors(ListBase *lbn, const ListBase *lbo) { bSensor *sens, *sensn; @@ -251,7 +251,7 @@ bController *copy_controller(bController *cont) return contn; } -void copy_controllers(ListBase *lbn, ListBase *lbo) +void copy_controllers(ListBase *lbn, const ListBase *lbo) { bController *cont, *contn; @@ -389,7 +389,7 @@ bActuator *copy_actuator(bActuator *act) return actn; } -void copy_actuators(ListBase *lbn, ListBase *lbo) +void copy_actuators(ListBase *lbn, const ListBase *lbo) { bActuator *act, *actn; @@ -783,7 +783,7 @@ void BKE_sca_logic_links_remap(Main *bmain, Object *ob_old, Object *ob_new) * Handle the copying of logic data into a new object, including internal logic links update. * External links (links between logic bricks of different objects) must be handled separately. */ -void BKE_sca_logic_copy(Object *ob_new, Object *ob) +void BKE_sca_logic_copy(Object *ob_new, const Object *ob) { copy_sensors(&ob_new->sensors, &ob->sensors); copy_controllers(&ob_new->controllers, &ob->controllers); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 60b86efc384..c4dbec940a2 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -2142,7 +2142,7 @@ bool BKE_scene_remove_render_view(Scene *scene, SceneRenderView *srv) int get_render_subsurf_level(const RenderData *r, int lvl, bool for_render) { - if (r->mode & R_SIMPLIFY) { + if (r->mode & R_SIMPLIFY) { if (for_render) return min_ii(r->simplify_subsurf_render, lvl); else diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index 298671beedb..e435d87024e 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -684,7 +684,7 @@ static float invGammaCorrect(float c) else if (i >= RE_GAMMA_TABLE_SIZE) res = powf(c, valid_inv_gamma); else res = inv_gamma_range_table[i] + ((c - color_domain_table[i]) * inv_gamfactor_table[i]); - + return res; } diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 2de7cd49901..669f76cf90b 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -1775,7 +1775,7 @@ static ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int c if (proxy->anim == NULL) { return NULL; } - + seq_open_anim_file(context->scene, seq, true); sanim = seq->anims.first; @@ -1783,7 +1783,7 @@ static ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int c return IMB_anim_absolute(proxy->anim, frameno, IMB_TC_NONE, IMB_PROXY_NONE); } - + if (seq_proxy_get_fname(ed, seq, cfra, render_size, name, context->view_id) == 0) { return NULL; } @@ -2082,7 +2082,7 @@ void BKE_sequencer_proxy_set(struct Sequence *seq, bool value) } } else { - seq->flag ^= SEQ_USE_PROXY; + seq->flag &= ~SEQ_USE_PROXY; } } @@ -4190,9 +4190,10 @@ static bool update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *cha if (free_imbuf) { if (ibuf_change) { - if (seq->type == SEQ_TYPE_MOVIE) + if (seq->type == SEQ_TYPE_MOVIE) { BKE_sequence_free_anim(seq); - if (seq->type == SEQ_TYPE_SPEED) { + } + else if (seq->type == SEQ_TYPE_SPEED) { BKE_sequence_effect_speed_rebuild_map(scene, seq, true); } } @@ -5182,6 +5183,7 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad sound = BKE_sound_new_file(bmain, seq_load->path); /* handles relative paths */ if (sound->playback_handle == NULL) { + BKE_libblock_free(bmain, sound); #if 0 if (op) BKE_report(op->reports, RPT_ERROR, "Unsupported audio format"); diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 4f73e153074..600bc3f453d 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -2235,9 +2235,9 @@ static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float t static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, float timenow) { -/* rule we never alter free variables :bp->vec bp->pos in here ! - * this will ruin adaptive stepsize AKA heun! (BM) - */ + /* rule we never alter free variables :bp->vec bp->pos in here ! + * this will ruin adaptive stepsize AKA heun! (BM) + */ SoftBody *sb= ob->soft; /* is supposed to be there */ /*BodyPoint *bproot;*/ /* UNUSED */ ListBase *do_effector = NULL; diff --git a/source/blender/blenkernel/intern/speaker.c b/source/blender/blenkernel/intern/speaker.c index ee6886e3fb2..d00e4b1a0d2 100644 --- a/source/blender/blenkernel/intern/speaker.c +++ b/source/blender/blenkernel/intern/speaker.c @@ -68,7 +68,7 @@ void *BKE_speaker_add(Main *bmain, const char *name) return spk; } -Speaker *BKE_speaker_copy(Main *bmain, Speaker *spk) +Speaker *BKE_speaker_copy(Main *bmain, const Speaker *spk) { Speaker *spkn; diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 298790a9e9b..466bef7ff36 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -449,7 +449,7 @@ Text *BKE_text_load(Main *bmain, const char *file, const char *relpath) return BKE_text_load_ex(bmain, file, relpath, false); } -Text *BKE_text_copy(Main *bmain, Text *ta) +Text *BKE_text_copy(Main *bmain, const Text *ta) { Text *tan; TextLine *line, *tmp; diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index b62a72c7d9c..1e0659d3d67 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -846,7 +846,7 @@ MTex *BKE_texture_mtex_add_id(ID *id, int slot) /* ------------------------------------------------------------------------- */ -Tex *BKE_texture_copy(Main *bmain, Tex *tex) +Tex *BKE_texture_copy(Main *bmain, const Tex *tex) { Tex *texn; @@ -1263,7 +1263,7 @@ EnvMap *BKE_texture_envmap_add(void) /* ------------------------------------------------------------------------- */ -EnvMap *BKE_texture_envmap_copy(EnvMap *env) +EnvMap *BKE_texture_envmap_copy(const EnvMap *env) { EnvMap *envn; int a; @@ -1336,7 +1336,7 @@ PointDensity *BKE_texture_pointdensity_add(void) return pd; } -PointDensity *BKE_texture_pointdensity_copy(PointDensity *pd) +PointDensity *BKE_texture_pointdensity_copy(const PointDensity *pd) { PointDensity *pdn; @@ -1430,7 +1430,7 @@ OceanTex *BKE_texture_ocean_add(void) return ot; } -OceanTex *BKE_texture_ocean_copy(struct OceanTex *ot) +OceanTex *BKE_texture_ocean_copy(const OceanTex *ot) { OceanTex *otn = MEM_dupallocN(ot); diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index bfe8dcbb21e..9120d384a16 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -190,7 +190,7 @@ void BKE_tracking_free(MovieTracking *tracking) } /* Copy the whole list of tracks. */ -static void tracking_tracks_copy(ListBase *tracks_dst, ListBase *tracks_src, GHash *tracks_mapping) +static void tracking_tracks_copy(ListBase *tracks_dst, const ListBase *tracks_src, GHash *tracks_mapping) { MovieTrackingTrack *track_dst, *track_src; @@ -210,7 +210,7 @@ static void tracking_tracks_copy(ListBase *tracks_dst, ListBase *tracks_src, GHa /* copy the whole list of plane tracks (need whole MovieTracking structures due to embedded pointers to tracks). * WARNING: implies tracking_[dst/src] and their tracks have already been copied. */ -static void tracking_plane_tracks_copy(ListBase *plane_tracks_dst, ListBase *plane_tracks_src, GHash *tracks_mapping) +static void tracking_plane_tracks_copy(ListBase *plane_tracks_dst, const ListBase *plane_tracks_src, GHash *tracks_mapping) { MovieTrackingPlaneTrack *plane_track_dst, *plane_track_src; @@ -232,7 +232,7 @@ static void tracking_plane_tracks_copy(ListBase *plane_tracks_dst, ListBase *pla /* Copy reconstruction structure. */ static void tracking_reconstruction_copy( - MovieTrackingReconstruction *reconstruction_dst, MovieTrackingReconstruction *reconstruction_src) + MovieTrackingReconstruction *reconstruction_dst, const MovieTrackingReconstruction *reconstruction_src) { *reconstruction_dst = *reconstruction_src; if (reconstruction_src->cameras) { @@ -242,14 +242,14 @@ static void tracking_reconstruction_copy( /* Copy stabilization structure. */ static void tracking_stabilization_copy( - MovieTrackingStabilization *stabilization_dst, MovieTrackingStabilization *stabilization_src) + MovieTrackingStabilization *stabilization_dst, const MovieTrackingStabilization *stabilization_src) { *stabilization_dst = *stabilization_src; } /* Copy tracking object. */ static void tracking_object_copy( - MovieTrackingObject *object_dst, MovieTrackingObject *object_src, GHash *tracks_mapping) + MovieTrackingObject *object_dst, const MovieTrackingObject *object_src, GHash *tracks_mapping) { *object_dst = *object_src; tracking_tracks_copy(&object_dst->tracks, &object_src->tracks, tracks_mapping); @@ -258,7 +258,7 @@ static void tracking_object_copy( } /* Copy list of tracking objects. */ -static void tracking_objects_copy(ListBase *objects_dst, ListBase *objects_src, GHash *tracks_mapping) +static void tracking_objects_copy(ListBase *objects_dst, const ListBase *objects_src, GHash *tracks_mapping) { MovieTrackingObject *object_dst, *object_src; @@ -272,7 +272,7 @@ static void tracking_objects_copy(ListBase *objects_dst, ListBase *objects_src, } /* Copy tracking structure content. */ -void BKE_tracking_copy(MovieTracking *tracking_dst, MovieTracking *tracking_src) +void BKE_tracking_copy(MovieTracking *tracking_dst, const MovieTracking *tracking_src) { GHash *tracks_mapping = BLI_ghash_ptr_new(__func__); diff --git a/source/blender/blenkernel/intern/tracking_stabilize.c b/source/blender/blenkernel/intern/tracking_stabilize.c index 3dfaa1ed77d..b8dfb217c16 100644 --- a/source/blender/blenkernel/intern/tracking_stabilize.c +++ b/source/blender/blenkernel/intern/tracking_stabilize.c @@ -203,7 +203,7 @@ static float get_animated_scaleinf(StabContext *ctx, int framenr) static void get_animated_target_pos(StabContext *ctx, int framenr, - float target_pos[2]) + float target_pos[2]) { target_pos[0] = fetch_from_fcurve(ctx->target_pos[0], framenr, diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index caa9a1e357f..363c36e644d 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -119,7 +119,7 @@ World *add_world(Main *bmain, const char *name) return wrld; } -World *BKE_world_copy(Main *bmain, World *wrld) +World *BKE_world_copy(Main *bmain, const World *wrld) { World *wrldn; int a; diff --git a/source/blender/blenlib/BLI_array.h b/source/blender/blenlib/BLI_array.h index c645ff06c00..74f24c808ff 100644 --- a/source/blender/blenlib/BLI_array.h +++ b/source/blender/blenlib/BLI_array.h @@ -137,8 +137,8 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static, #define BLI_array_free(arr) \ if (arr && (char *)arr != _##arr##_static) { \ - BLI_array_fake_user(arr); \ - MEM_freeN(arr); \ + BLI_array_fake_user(arr); \ + MEM_freeN(arr); \ } (void)0 #define BLI_array_pop(arr) ( \ diff --git a/source/blender/blenlib/BLI_kdopbvh.h b/source/blender/blenlib/BLI_kdopbvh.h index ba565fca522..564659ad21e 100644 --- a/source/blender/blenlib/BLI_kdopbvh.h +++ b/source/blender/blenlib/BLI_kdopbvh.h @@ -36,7 +36,7 @@ */ #ifdef __cplusplus -extern "C" { +extern "C" { #endif struct BVHTree; @@ -62,7 +62,7 @@ typedef struct BVHTreeNearest { int index; /* the index of the nearest found (untouched if none is found within a dist radius from the given coordinates) */ float co[3]; /* nearest coordinates (untouched it none is found within a dist radius from the given coordinates) */ float no[3]; /* normal at nearest coordinates (untouched it none is found within a dist radius from the given coordinates) */ - float dist_sq; /* squared distance to search arround */ + float dist_sq; /* squared distance to search around */ int flags; } BVHTreeNearest; diff --git a/source/blender/blenlib/BLI_math_rotation.h b/source/blender/blenlib/BLI_math_rotation.h index d60be30e10d..e059327a490 100644 --- a/source/blender/blenlib/BLI_math_rotation.h +++ b/source/blender/blenlib/BLI_math_rotation.h @@ -218,8 +218,12 @@ 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]); +bool mat3_from_axis_conversion( + int src_forward, int src_up, int dst_forward, int dst_up, + float r_mat[3][3]); +bool mat3_from_axis_conversion_single( + int src_axis, int dst_axis, + float r_mat[3][3]); #ifdef __cplusplus } diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index 8e0884ba347..43f414f376a 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -286,6 +286,8 @@ float angle_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT; float angle_v3v3v3(const float a[3], const float b[3], const float c[3]) ATTR_WARN_UNUSED_RESULT; float cos_v3v3v3(const float p1[3], const float p2[3], const float p3[3]) ATTR_WARN_UNUSED_RESULT; float cos_v2v2v2(const float p1[2], const float p2[2], const float p3[2]) ATTR_WARN_UNUSED_RESULT; +float angle_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT; +float angle_signed_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT; float angle_normalized_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT; float angle_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT; float angle_signed_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT; @@ -299,6 +301,8 @@ void project_v2_v2v2(float out[2], const float p[2], const float v_proj[2]); void project_v3_v3v3(float out[3], const float p[3], const float v_proj[3]); void project_plane_v3_v3v3(float out[3], const float p[3], const float v_plane[3]); void project_plane_v2_v2v2(float out[2], const float p[2], const float v_plane[2]); +void project_plane_normalized_v3_v3v3(float out[3], const float p[3], const float v_plane[3]); +void project_plane_normalized_v2_v2v2(float out[2], const float p[2], const float v_plane[2]); void project_v3_plane(float out[3], const float plane_no[3], const float plane_co[3]); void reflect_v3_v3v3(float out[3], const float vec[3], const float normal[3]); void ortho_basis_v3v3_v3(float r_n1[3], float r_n2[3], const float n[3]); diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h index 041679ef876..21b9c75ac35 100644 --- a/source/blender/blenlib/BLI_rect.h +++ b/source/blender/blenlib/BLI_rect.h @@ -97,6 +97,7 @@ void BLI_rctf_union(struct rctf *rctf1, const struct rctf *rctf2); void BLI_rcti_rctf_copy(struct rcti *dst, const struct rctf *src); void BLI_rctf_rcti_copy(struct rctf *dst, const struct rcti *src); void BLI_rcti_rctf_copy_floor(struct rcti *dst, const struct rctf *src); +void BLI_rcti_rctf_copy_round(struct rcti *dst, const struct rctf *src); void BLI_rctf_rotate_expand(rctf *dst, const rctf *src, const float angle); diff --git a/source/blender/blenlib/BLI_stack.h b/source/blender/blenlib/BLI_stack.h index 222005ee92e..d54f2a7bab2 100644 --- a/source/blender/blenlib/BLI_stack.h +++ b/source/blender/blenlib/BLI_stack.h @@ -30,6 +30,10 @@ #include "BLI_compiler_attrs.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef struct BLI_Stack BLI_Stack; BLI_Stack *BLI_stack_new_ex( @@ -55,4 +59,8 @@ size_t BLI_stack_count(const BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONN bool BLI_stack_is_empty(const BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +#ifdef __cplusplus +} +#endif + #endif /* __BLI_STACK_H__ */ diff --git a/source/blender/blenlib/BLI_strict_flags.h b/source/blender/blenlib/BLI_strict_flags.h index 964ee06469d..86b7285655e 100644 --- a/source/blender/blenlib/BLI_strict_flags.h +++ b/source/blender/blenlib/BLI_strict_flags.h @@ -30,6 +30,8 @@ #ifdef __GNUC__ # if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 /* gcc4.6+ only */ # pragma GCC diagnostic error "-Wsign-compare" +# endif +# if __GNUC__ >= 6 /* gcc6+ only */ # pragma GCC diagnostic error "-Wconversion" # endif # if (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 diff --git a/source/blender/blenlib/BLI_task.h b/source/blender/blenlib/BLI_task.h index c3c587275e1..721327d26a8 100644 --- a/source/blender/blenlib/BLI_task.h +++ b/source/blender/blenlib/BLI_task.h @@ -106,6 +106,13 @@ void *BLI_task_pool_userdata(TaskPool *pool); /* optional mutex to use from run function */ ThreadMutex *BLI_task_pool_user_mutex(TaskPool *pool); +/* Delayed push, use that to reduce thread overhead by accumulating + * all new tasks into local queue first and pushing it to scheduler + * from within a single mutex lock. + */ +void BLI_task_pool_delayed_push_begin(TaskPool *pool, int thread_id); +void BLI_task_pool_delayed_push_end(TaskPool *pool, int thread_id); + /* Parallel for routines */ typedef void (*TaskParallelRangeFunc)(void *userdata, const int iter); typedef void (*TaskParallelRangeFuncEx)(void *userdata, void *userdata_chunk, const int iter, const int thread_id); diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c index d1fe3557801..69dee12c713 100644 --- a/source/blender/blenlib/intern/BLI_ghash.c +++ b/source/blender/blenlib/intern/BLI_ghash.c @@ -116,6 +116,12 @@ struct GHash { }; +/* -------------------------------------------------------------------- */ +/* GHash API */ + +/** \name Internal Utility API + * \{ */ + BLI_INLINE void ghash_entry_copy( GHash *gh_dst, Entry *dst, GHash *gh_src, Entry *src, GHashKeyCopyFP keycopyfp, GHashValCopyFP valcopyfp) @@ -132,12 +138,6 @@ BLI_INLINE void ghash_entry_copy( } } -/* -------------------------------------------------------------------- */ -/* GHash API */ - -/** \name Internal Utility API - * \{ */ - /** * Get the full hash for a key. */ diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index 857c2a5201c..e5ca53a0193 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -62,6 +62,13 @@ /* used for iterative_raycast */ // #define USE_SKIP_LINKS +/* Use to print balanced output. */ +// #define USE_PRINT_TREE + +/* Check tree is valid. */ +// #define USE_VERIFY_TREE + + #define MAX_TREETYPE 32 /* Setting zero so we can catch bugs in BLI_task/KDOPBVH. @@ -571,10 +578,12 @@ static void node_join(BVHTree *tree, BVHNode *node) } } -/* +#ifdef USE_PRINT_TREE + +/** * Debug and information functions */ -#if 0 + static void bvhtree_print_tree(BVHTree *tree, BVHNode *node, int depth) { int i; @@ -597,30 +606,29 @@ static void bvhtree_print_tree(BVHTree *tree, BVHNode *node, int depth) static void bvhtree_info(BVHTree *tree) { - printf("BVHTree info\n"); - printf("tree_type = %d, axis = %d, epsilon = %f\n", + printf("BVHTree Info: tree_type = %d, axis = %d, epsilon = %f\n", tree->tree_type, tree->axis, tree->epsilon); printf("nodes = %d, branches = %d, leafs = %d\n", tree->totbranch + tree->totleaf, tree->totbranch, tree->totleaf); - printf("Memory per node = %ldbytes\n", - sizeof(BVHNode) + sizeof(BVHNode *) * tree->tree_type + sizeof(float) * tree->axis); - printf("BV memory = %dbytes\n", - (int)MEM_allocN_len(tree->nodebv)); - - printf("Total memory = %ldbytes\n", sizeof(BVHTree) + - MEM_allocN_len(tree->nodes) + - MEM_allocN_len(tree->nodearray) + - MEM_allocN_len(tree->nodechild) + - MEM_allocN_len(tree->nodebv)); - -// bvhtree_print_tree(tree, tree->nodes[tree->totleaf], 0); + printf("Memory per node = %ubytes\n", + (uint)(sizeof(BVHNode) + sizeof(BVHNode *) * tree->tree_type + sizeof(float) * tree->axis)); + printf("BV memory = %ubytes\n", + (uint)MEM_allocN_len(tree->nodebv)); + + printf("Total memory = %ubytes\n", + (uint)(sizeof(BVHTree) + + MEM_allocN_len(tree->nodes) + + MEM_allocN_len(tree->nodearray) + + MEM_allocN_len(tree->nodechild) + + MEM_allocN_len(tree->nodebv))); + + bvhtree_print_tree(tree, tree->nodes[tree->totleaf], 0); } -#endif +#endif /* USE_PRINT_TREE */ -#if 0 +#ifdef USE_VERIFY_TREE - -static void verify_tree(BVHTree *tree) +static void bvhtree_verify(BVHTree *tree) { int i, j, check = 0; @@ -661,7 +669,7 @@ static void verify_tree(BVHTree *tree) printf("branches: %d, leafs: %d, total: %d\n", tree->totbranch, tree->totleaf, tree->totbranch + tree->totleaf); } -#endif +#endif /* USE_VERIFY_TREE */ /* Helper data and structures to build a min-leaf generalized implicit tree * This code can be easily reduced @@ -907,16 +915,24 @@ static void non_recursive_bvh_div_nodes( /* Loop tree levels (log N) loops */ for (i = 1, depth = 1; i <= num_branches; i = i * tree_type + tree_offset, depth++) { const int first_of_next_level = i * tree_type + tree_offset; - const int end_j = min_ii(first_of_next_level, num_branches + 1); /* index of last branch on this level */ + const int i_stop = min_ii(first_of_next_level, num_branches + 1); /* index of last branch on this level */ /* Loop all branches on this level */ cb_data.first_of_next_level = first_of_next_level; cb_data.i = i; cb_data.depth = depth; - BLI_task_parallel_range( - i, end_j, &cb_data, non_recursive_bvh_div_nodes_task_cb, - num_leafs > KDOPBVH_THREAD_LEAF_THRESHOLD); + if (true) { + BLI_task_parallel_range( + i, i_stop, &cb_data, non_recursive_bvh_div_nodes_task_cb, + num_leafs > KDOPBVH_THREAD_LEAF_THRESHOLD); + } + else { + /* Less hassle for debugging. */ + for (int i_task = i; i_task < i_stop; i_task++) { + non_recursive_bvh_div_nodes_task_cb(&cb_data, i_task); + } + } } } @@ -1050,7 +1066,13 @@ void BLI_bvhtree_balance(BVHTree *tree) build_skip_links(tree, tree->nodes[tree->totleaf], NULL, NULL); #endif - /* bvhtree_info(tree); */ +#ifdef USE_VERIFY_TREE + bvhtree_verify(tree); +#endif + +#ifdef USE_PRINT_TREE + bvhtree_info(tree); +#endif } void BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints) diff --git a/source/blender/blenlib/intern/array_store.c b/source/blender/blenlib/intern/array_store.c index 5d1b2433084..d3a63aceb89 100644 --- a/source/blender/blenlib/intern/array_store.c +++ b/source/blender/blenlib/intern/array_store.c @@ -1560,7 +1560,7 @@ BArrayState *BLI_array_store_state_add( const void *data, const size_t data_len, const BArrayState *state_reference) { - /* ensure we're aligned to the stride */ + /* ensure we're aligned to the stride */ BLI_assert((data_len % bs->info.chunk_stride) == 0); #ifdef USE_PARANOID_CHECKS diff --git a/source/blender/blenlib/intern/math_color_blend_inline.c b/source/blender/blenlib/intern/math_color_blend_inline.c index 048ab71c6dc..dc3874f83a2 100644 --- a/source/blender/blenlib/intern/math_color_blend_inline.c +++ b/source/blender/blenlib/intern/math_color_blend_inline.c @@ -444,7 +444,7 @@ MINLINE void blend_color_vividlight_byte(unsigned char dst[4], unsigned const ch else if (src2[i] == 0) { temp = 0; } - else if (src2[i] > 127) { + else if (src2[i] > 127) { temp = min_ii(((src1[i]) * 255) / (2 * (255 - src2[i])), 255); } else { diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 58699a0593b..bfe1aefcbbd 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -572,8 +572,8 @@ float dist_squared_to_ray_v3( } /** * Find the closest point in a seg to a ray and return the distance squared. - * \param r_point : Is the point on segment closest to ray (or to ray_origin if the ray and the segment are parallel). - * \param depth: the distance of r_point projection on ray to the ray_origin. + * \param r_point: Is the point on segment closest to ray (or to ray_origin if the ray and the segment are parallel). + * \param r_depth: the distance of r_point projection on ray to the ray_origin. */ float dist_squared_ray_to_seg_v3( const float ray_origin[3], const float ray_direction[3], @@ -1828,7 +1828,7 @@ bool isect_tri_tri_epsilon_v3( (range[0].max < range[1].min)) == 0) { if (r_i1 && r_i2) { - project_plane_v3_v3v3(plane_co, plane_co, plane_no); + project_plane_normalized_v3_v3v3(plane_co, plane_co, plane_no); madd_v3_v3v3fl(r_i1, plane_co, plane_no, max_ff(range[0].min, range[1].min)); madd_v3_v3v3fl(r_i2, plane_co, plane_no, min_ff(range[0].max, range[1].max)); } diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 9a60c670ec7..f47f9ad76e6 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -1738,16 +1738,16 @@ void blend_m4_m4m4(float out[4][4], float dst[4][4], float src[4][4], const floa /** * A polar-decomposition-based interpolation between matrix A and matrix B. * - * \note This code is about five times slower as the 'naive' interpolation done by \a blend_m3_m3m3 - * (it typically remains below 2 usec on an average i74700, while \a blend_m3_m3m3 remains below 0.4 usec). + * \note This code is about five times slower as the 'naive' interpolation done by #blend_m3_m3m3 + * (it typically remains below 2 usec on an average i74700, while #blend_m3_m3m3 remains below 0.4 usec). * However, it gives expected results even with non-uniformaly scaled matrices, see T46418 for an example. * * Based on "Matrix Animation and Polar Decomposition", by Ken Shoemake & Tom Duff * - * @return R the interpolated matrix. - * @param A the intput matrix which is totally effective with \a t = 0.0. - * @param B the intput matrix which is totally effective with \a t = 1.0. - * @param t the interpolation factor. + * \param R: Resulting interpolated matrix. + * \param A: Input matrix which is totally effective with `t = 0.0`. + * \param B: Input matrix which is totally effective with `t = 1.0`. + * \param t: Interpolation factor. */ void interp_m3_m3m3(float R[3][3], float A[3][3], float B[3][3], const float t) { @@ -1777,12 +1777,12 @@ void interp_m3_m3m3(float R[3][3], float A[3][3], float B[3][3], const float t) } /** - * Complete transform matrix interpolation, based on polar-decomposition-based interpolation from interp_m3_m3m3. + * Complete transform matrix interpolation, based on polar-decomposition-based interpolation from #interp_m3_m3m3. * - * @return R the interpolated matrix. - * @param A the intput matrix which is totally effective with \a t = 0.0. - * @param B the intput matrix which is totally effective with \a t = 1.0. - * @param t the interpolation factor. + * \param R: Resulting interpolated matrix. + * \param A: Input matrix which is totally effective with `t = 0.0`. + * \param B: Input matrix which is totally effective with `t = 1.0`. + * \param t: Interpolation factor. */ void interp_m4_m4m4(float R[4][4], float A[4][4], float B[4][4], const float t) { diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c index fa58fe368d1..23bd5e60e22 100644 --- a/source/blender/blenlib/intern/math_rotation.c +++ b/source/blender/blenlib/intern/math_rotation.c @@ -2147,38 +2147,37 @@ BLI_INLINE 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]) +bool mat3_from_axis_conversion( + int src_forward, int src_up, int dst_forward, int dst_up, + float r_mat[3][3]) { // from functools import reduce int value; - unsigned int i; - if (from_forward == to_forward && from_up == to_up) { + if (src_forward == dst_forward && src_up == dst_up) { unit_m3(r_mat); return false; } - if ((_axis_signed(from_forward) == _axis_signed(from_up)) || - (_axis_signed(to_forward) == _axis_signed(to_up))) + if ((_axis_signed(src_forward) == _axis_signed(src_up)) || + (_axis_signed(dst_forward) == _axis_signed(dst_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))); + value = ((src_forward << (0 * 3)) | + (src_up << (1 * 3)) | + (dst_forward << (2 * 3)) | + (dst_up << (3 * 3))); - for (i = 0; i < (sizeof(_axis_convert_matrix) / sizeof(*_axis_convert_matrix)); i++) { - unsigned int j; - for (j = 0; j < (sizeof(*_axis_convert_lut) / sizeof(*_axis_convert_lut[0])); j++) { + for (uint i = 0; i < (sizeof(_axis_convert_matrix) / sizeof(*_axis_convert_matrix)); i++) { + for (uint 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; @@ -2189,3 +2188,27 @@ int mat3_from_axis_conversion(int from_forward, int from_up, int to_forward, int // BLI_assert(0); return false; } + +/** + * Use when the second axis can be guessed. + */ +bool mat3_from_axis_conversion_single( + int src_axis, int dst_axis, + float r_mat[3][3]) +{ + if (src_axis == dst_axis) { + unit_m3(r_mat); + return false; + } + + /* Pick predictable next axis. */ + int src_axis_next = (src_axis + 1) % 3; + int dst_axis_next = (dst_axis + 1) % 3; + + if ((src_axis < 3) != (dst_axis < 3)) { + /* Flip both axis so matrix sign remains positive. */ + dst_axis_next += 3; + } + + return mat3_from_axis_conversion(src_axis, src_axis_next, dst_axis, dst_axis_next, r_mat); +} diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c index 37897e2cd32..c6e9b8229ba 100644 --- a/source/blender/blenlib/intern/math_vector.c +++ b/source/blender/blenlib/intern/math_vector.c @@ -518,38 +518,27 @@ float angle_normalized_v2v2(const float v1[2], const float v2[2]) } /** - * angle between 2 vectors defined by 3 coords, about an axis. */ -float angle_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3]) + * Angle between 2 vectors, about an axis (axis can be considered a plane). + */ +float angle_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3]) { - float v1_proj[3], v2_proj[3], tproj[3]; - - sub_v3_v3v3(v1_proj, v1, v2); - sub_v3_v3v3(v2_proj, v3, v2); + float v1_proj[3], v2_proj[3]; /* project the vectors onto the axis */ - project_v3_v3v3(tproj, v1_proj, axis); - sub_v3_v3(v1_proj, tproj); - - project_v3_v3v3(tproj, v2_proj, axis); - sub_v3_v3(v2_proj, tproj); + project_plane_normalized_v3_v3v3(v1_proj, v1, axis); + project_plane_normalized_v3_v3v3(v2_proj, v2, axis); return angle_v3v3(v1_proj, v2_proj); } -float angle_signed_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3]) +float angle_signed_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3]) { float v1_proj[3], v2_proj[3], tproj[3]; float angle; - sub_v3_v3v3(v1_proj, v1, v2); - sub_v3_v3v3(v2_proj, v3, v2); - /* project the vectors onto the axis */ - project_v3_v3v3(tproj, v1_proj, axis); - sub_v3_v3(v1_proj, tproj); - - project_v3_v3v3(tproj, v2_proj, axis); - sub_v3_v3(v2_proj, tproj); + project_plane_normalized_v3_v3v3(v1_proj, v1, axis); + project_plane_normalized_v3_v3v3(v2_proj, v2, axis); angle = angle_v3v3(v1_proj, v2_proj); @@ -562,6 +551,29 @@ float angle_signed_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const return angle; } +/** + * Angle between 2 vectors defined by 3 coords, about an axis (axis can be considered a plane). + */ +float angle_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3]) +{ + float vec1[3], vec2[3]; + + sub_v3_v3v3(vec1, v1, v2); + sub_v3_v3v3(vec2, v3, v2); + + return angle_on_axis_v3v3_v3(vec1, vec2, axis); +} + +float angle_signed_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3]) +{ + float vec1[3], vec2[3]; + + sub_v3_v3v3(vec1, v1, v2); + sub_v3_v3v3(vec2, v3, v2); + + return angle_signed_on_axis_v3v3_v3(vec1, vec2, axis); +} + void angle_tri_v3(float angles[3], const float v1[3], const float v2[3], const float v3[3]) { float ed1[3], ed2[3], ed3[3]; @@ -669,6 +681,25 @@ void project_plane_v2_v2v2(float out[2], const float p[2], const float v_plane[2 out[1] = p[1] - (mul * v_plane[1]); } +void project_plane_normalized_v3_v3v3(float out[3], const float p[3], const float v_plane[3]) +{ + BLI_ASSERT_UNIT_V3(v_plane); + const float mul = dot_v3v3(p, v_plane); + + out[0] = p[0] - (mul * v_plane[0]); + out[1] = p[1] - (mul * v_plane[1]); + out[2] = p[2] - (mul * v_plane[2]); +} + +void project_plane_normalized_v2_v2v2(float out[2], const float p[2], const float v_plane[2]) +{ + BLI_ASSERT_UNIT_V2(v_plane); + const float mul = dot_v2v2(p, v_plane); + + out[0] = p[0] - (mul * v_plane[0]); + out[1] = p[1] - (mul * v_plane[1]); +} + /* project a vector on a plane defined by normal and a plane point p */ void project_v3_plane(float out[3], const float plane_no[3], const float plane_co[3]) { diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c index f834c5b4c74..347640aae0d 100644 --- a/source/blender/blenlib/intern/noise.c +++ b/source/blender/blenlib/intern/noise.c @@ -1394,6 +1394,11 @@ static float voronoi_CrS(float x, float y, float z) /* returns unsigned cellnoise */ static float cellNoiseU(float x, float y, float z) { + /* avoid precision issues on unit coordinates */ + x = (x + 0.000001f)*0.999999f; + y = (y + 0.000001f)*0.999999f; + z = (z + 0.000001f)*0.999999f; + int xi = (int)(floor(x)); int yi = (int)(floor(y)); int zi = (int)(floor(z)); @@ -1411,6 +1416,11 @@ float cellNoise(float x, float y, float z) /* returns a vector/point/color in ca, using point hasharray directly */ void cellNoiseV(float x, float y, float z, float ca[3]) { + /* avoid precision issues on unit coordinates */ + x = (x + 0.000001f)*0.999999f; + y = (y + 0.000001f)*0.999999f; + z = (z + 0.000001f)*0.999999f; + int xi = (int)(floor(x)); int yi = (int)(floor(y)); int zi = (int)(floor(z)); diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c index fd24a00156d..e0c4cbe9990 100644 --- a/source/blender/blenlib/intern/rct.c +++ b/source/blender/blenlib/intern/rct.c @@ -693,6 +693,14 @@ void BLI_rcti_rctf_copy_floor(rcti *dst, const rctf *src) dst->ymax = floorf(src->ymax); } +void BLI_rcti_rctf_copy_round(rcti *dst, const rctf *src) +{ + dst->xmin = floorf(src->xmin + 0.5f); + dst->xmax = floorf(src->xmax + 0.5f); + dst->ymin = floorf(src->ymin + 0.5f); + dst->ymax = floorf(src->ymax + 0.5f); +} + void BLI_rctf_rcti_copy(rctf *dst, const rcti *src) { dst->xmin = src->xmin; diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c index 48280c14d7d..b819c513fbd 100644 --- a/source/blender/blenlib/intern/storage.c +++ b/source/blender/blenlib/intern/storage.c @@ -422,13 +422,13 @@ void BLI_file_free_lines(LinkNode *lines) bool BLI_file_older(const char *file1, const char *file2) { #ifdef WIN32 - struct _stat st1, st2; + struct _stat st1, st2; UTF16_ENCODE(file1); UTF16_ENCODE(file2); if (_wstat(file1_16, &st1)) return false; - if (_wstat(file2_16, &st2)) return false; + if (_wstat(file2_16, &st2)) return false; UTF16_UN_ENCODE(file2); UTF16_UN_ENCODE(file1); diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c index b7e5e3e101e..229a97a2fa7 100644 --- a/source/blender/blenlib/intern/string_utf8.c +++ b/source/blender/blenlib/intern/string_utf8.c @@ -167,7 +167,7 @@ utf8_error: /** * Remove any invalid utf-8 byte (taking into account multi-bytes sequence of course). * - * @return number of stripped bytes. + * \return number of stripped bytes. */ int BLI_utf8_invalid_strip(char *str, size_t length) { diff --git a/source/blender/blenlib/intern/task.c b/source/blender/blenlib/intern/task.c index eb4e6e91aee..e050f3148b8 100644 --- a/source/blender/blenlib/intern/task.c +++ b/source/blender/blenlib/intern/task.c @@ -52,7 +52,14 @@ * * This allows thread to fetch next task without locking the whole queue. */ -#define LOCALQUEUE_SIZE 1 +#define LOCAL_QUEUE_SIZE 1 + +/* Number of tasks which are allowed to be scheduled in a delayed manner. + * + * This allows to use less locks per graph node children schedule. More details + * could be found at TaskThreadLocalStorage::do_delayed_push. + */ +#define DELAYED_QUEUE_SIZE 4096 #ifndef NDEBUG # define ASSERT_THREAD_ID(scheduler, thread_id) \ @@ -129,9 +136,28 @@ typedef struct TaskMemPoolStats { #endif typedef struct TaskThreadLocalStorage { + /* Memory pool for faster task allocation. + * The idea is to re-use memory of finished/discarded tasks by this thread. + */ TaskMemPool task_mempool; + + /* Local queue keeps thread alive by keeping small amount of tasks ready + * to be picked up without causing global thread locks for synchronization. + */ int num_local_queue; - Task *local_queue[LOCALQUEUE_SIZE]; + Task *local_queue[LOCAL_QUEUE_SIZE]; + + /* Thread can be marked for delayed tasks push. This is helpful when it's + * know that lots of subsequent task pushed will happen from the same thread + * without "interrupting" for task execution. + * + * We try to accumulate as much tasks as possible in a local queue without + * any locks first, and then we push all of them into a scheduler's queue + * from within a single mutex lock. + */ + bool do_delayed_push; + int num_delayed_queue; + Task *delayed_queue[DELAYED_QUEUE_SIZE]; } TaskThreadLocalStorage; struct TaskPool { @@ -378,6 +404,7 @@ static bool task_scheduler_thread_wait_pop(TaskScheduler *scheduler, Task **task BLI_INLINE void handle_local_queue(TaskThreadLocalStorage *tls, const int thread_id) { + BLI_assert(!tls->do_delayed_push); while (tls->num_local_queue > 0) { /* We pop task from queue before handling it so handler of the task can * push next job to the local queue. @@ -391,6 +418,7 @@ BLI_INLINE void handle_local_queue(TaskThreadLocalStorage *tls, local_task->run(local_pool, local_task->taskdata, thread_id); task_free(local_pool, local_task, thread_id); } + BLI_assert(!tls->do_delayed_push); } static void *task_scheduler_thread_run(void *thread_p) @@ -408,7 +436,9 @@ static void *task_scheduler_thread_run(void *thread_p) TaskPool *pool = task->pool; /* run task */ + BLI_assert(!tls->do_delayed_push); task->run(pool, task->taskdata, thread_id); + BLI_assert(!tls->do_delayed_push); /* delete task */ task_free(pool, task, thread_id); @@ -547,6 +577,27 @@ static void task_scheduler_push(TaskScheduler *scheduler, Task *task, TaskPriori BLI_mutex_unlock(&scheduler->queue_mutex); } +static void task_scheduler_push_all(TaskScheduler *scheduler, + TaskPool *pool, + Task **tasks, + int num_tasks) +{ + if (num_tasks == 0) { + return; + } + + task_pool_num_increase(pool, num_tasks); + + BLI_mutex_lock(&scheduler->queue_mutex); + + for (int i = 0; i < num_tasks; i++) { + BLI_addhead(&scheduler->queue, tasks[i]); + } + + BLI_condition_notify_all(&scheduler->queue_cond); + BLI_mutex_unlock(&scheduler->queue_mutex); +} + static void task_scheduler_clear(TaskScheduler *scheduler, TaskPool *pool) { Task *task, *nexttask; @@ -714,38 +765,59 @@ void BLI_task_pool_free(TaskPool *pool) BLI_end_threaded_malloc(); } +BLI_INLINE bool task_can_use_local_queues(TaskPool *pool, int thread_id) +{ + return (thread_id != -1 && (thread_id != pool->thread_id || pool->do_work)); +} + static void task_pool_push( TaskPool *pool, TaskRunFunction run, void *taskdata, bool free_taskdata, TaskFreeFunction freedata, TaskPriority priority, int thread_id) { + /* Allocate task and fill it's properties. */ Task *task = task_alloc(pool, thread_id); - task->run = run; task->taskdata = taskdata; task->free_taskdata = free_taskdata; task->freedata = freedata; task->pool = pool; - + /* For suspended pools we put everything yo a global queue first + * and exit as soon as possible. + * + * This tasks will be moved to actual execution when pool is + * activated by work_and_wait(). + */ if (pool->is_suspended) { BLI_addhead(&pool->suspended_queue, task); atomic_fetch_and_add_z(&pool->num_suspended, 1); return; } - - if (thread_id != -1 && - (thread_id != pool->thread_id || pool->do_work)) - { + /* Populate to any local queue first, this is cheapest push ever. */ + if (task_can_use_local_queues(pool, thread_id)) { ASSERT_THREAD_ID(pool->scheduler, thread_id); - TaskThreadLocalStorage *tls = get_task_tls(pool, thread_id); - if (tls->num_local_queue < LOCALQUEUE_SIZE) { + /* Try to push to a local execution queue. + * These tasks will be picked up next. + */ + if (tls->num_local_queue < LOCAL_QUEUE_SIZE) { tls->local_queue[tls->num_local_queue] = task; tls->num_local_queue++; return; } + /* If we are in the delayed tasks push mode, we push tasks to a + * temporary local queue first without any locks, and then move them + * to global execution queue with a single lock. + */ + if (tls->do_delayed_push && tls->num_delayed_queue < DELAYED_QUEUE_SIZE) { + tls->delayed_queue[tls->num_delayed_queue] = task; + tls->num_delayed_queue++; + return; + } } - + /* Do push to a global execution ppol, slowest possible method, + * causes quite reasonable amount of threading overhead. + */ task_scheduler_push(pool->scheduler, task, priority); } @@ -816,7 +888,9 @@ void BLI_task_pool_work_and_wait(TaskPool *pool) /* if found task, do it, otherwise wait until other tasks are done */ if (found_task) { /* run task */ + BLI_assert(!tls->do_delayed_push); work_task->run(pool, work_task->taskdata, pool->thread_id); + BLI_assert(!tls->do_delayed_push); /* delete task */ task_free(pool, task, pool->thread_id); @@ -871,6 +945,30 @@ ThreadMutex *BLI_task_pool_user_mutex(TaskPool *pool) return &pool->user_mutex; } +void BLI_task_pool_delayed_push_begin(TaskPool *pool, int thread_id) +{ + if (task_can_use_local_queues(pool, thread_id)) { + ASSERT_THREAD_ID(pool->scheduler, thread_id); + TaskThreadLocalStorage *tls = get_task_tls(pool, thread_id); + tls->do_delayed_push = true; + } +} + +void BLI_task_pool_delayed_push_end(TaskPool *pool, int thread_id) +{ + if (task_can_use_local_queues(pool, thread_id)) { + ASSERT_THREAD_ID(pool->scheduler, thread_id); + TaskThreadLocalStorage *tls = get_task_tls(pool, thread_id); + BLI_assert(tls->do_delayed_push); + task_scheduler_push_all(pool->scheduler, + pool, + tls->delayed_queue, + tls->num_delayed_queue); + tls->do_delayed_push = false; + tls->num_delayed_queue = 0; + } +} + /* Parallel range routines */ /** @@ -1029,7 +1127,7 @@ static void task_parallel_range_ex( atomic_fetch_and_add_uint32((uint32_t *)(&state.iter), 0); if (use_userdata_chunk) { - userdata_chunk_array = MALLOCA(userdata_chunk_size * num_tasks); + userdata_chunk_array = MALLOCA(userdata_chunk_size * num_tasks); } for (i = 0; i < num_tasks; i++) { diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 01951b0266f..f224f0b5633 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -10159,7 +10159,7 @@ void BLO_library_link_copypaste(Main *mainl, BlendHandle *bh) static ID *link_named_part_ex( Main *mainl, FileData *fd, const short idcode, const char *name, const short flag, - Scene *scene, View3D *v3d, const bool use_placeholders, const bool force_indirect) + Scene *scene, View3D *v3d, const bool use_placeholders, const bool force_indirect) { ID *id = link_named_part(mainl, fd, idcode, name, use_placeholders, force_indirect); diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index d2f43a2d79e..94d335870ca 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -1236,12 +1236,19 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) SEQ_BEGIN (scene->ed, seq) { - if (seq->type == SEQ_TYPE_TEXT) { - TextVars *data = seq->effectdata; - if (data->color[3] == 0.0f) { - copy_v4_fl(data->color, 1.0f); - data->shadow_color[3] = 1.0f; - } + if (seq->type != SEQ_TYPE_TEXT) { + continue; + } + + if (seq->effectdata == NULL) { + struct SeqEffectHandle effect_handle = BKE_sequence_get_effect(seq); + effect_handle.init(seq); + } + + TextVars *data = seq->effectdata; + if (data->color[3] == 0.0f) { + copy_v4_fl(data->color, 1.0f); + data->shadow_color[3] = 1.0f; } } SEQ_END diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c index bd71f6e75ea..f813c8ca79b 100644 --- a/source/blender/blenloader/intern/versioning_defaults.c +++ b/source/blender/blenloader/intern/versioning_defaults.c @@ -247,13 +247,13 @@ void BLO_update_defaults_startup_blend(Main *bmain) /* remove polish brush (flatten/contrast does the same) */ br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Polish"); if (br) { - BKE_libblock_free(bmain, br); + BKE_libblock_delete(bmain, br); } /* remove brush brush (huh?) from some modes (draw brushes do the same) */ br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Brush"); if (br) { - BKE_libblock_free(bmain, br); + BKE_libblock_delete(bmain, br); } /* remove draw brush from texpaint (draw brushes do the same) */ diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index d2f0fc1721c..200a31b1a57 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -1741,6 +1741,8 @@ static BMOpDefine bmo_bevel_def = { }, /* slots_out */ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */ + {"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* output edges */ + {"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */ {{'\0'}}, }, diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index a774f278c98..f5c14304ea3 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -1515,16 +1515,30 @@ float BM_loop_calc_face_angle(const BMLoop *l) */ void BM_loop_calc_face_normal(const BMLoop *l, float r_normal[3]) { - if (normal_tri_v3(r_normal, - l->prev->v->co, - l->v->co, - l->next->v->co) != 0.0f) - { - /* pass */ +#define FEPSILON 1e-5f + + /* Note: we cannot use result of normal_tri_v3 here to detect colinear vectors (vertex on a straight line) + * from zero value, because it does not normalize both vectors before making crossproduct. + * Instead of adding two costly normalize computations, just check ourselves for colinear case. */ + /* Note: FEPSILON might need some finer tweaking at some point? Seems to be working OK for now though. */ + float v1[3], v2[3], v_tmp[3]; + sub_v3_v3v3(v1, l->prev->v->co, l->v->co); + sub_v3_v3v3(v2, l->next->v->co, l->v->co); + + const float fac = (v2[0] == 0.0f) ? ((v2[1] == 0.0f) ? ((v2[2] == 0.0f) ? 0.0f : v1[2] / v2[2]) : v1[1] / v2[1]) : v1[0] / v2[0]; + + mul_v3_v3fl(v_tmp, v2, fac); + sub_v3_v3(v_tmp, v1); + if (fac != 0.0f && !is_zero_v3(v1) && len_manhattan_v3(v_tmp) > FEPSILON) { + /* Not co-linear, we can compute crossproduct and normalize it into normal. */ + cross_v3_v3v3(r_normal, v1, v2); + normalize_v3(r_normal); } else { copy_v3_v3(r_normal, l->f->no); } + +#undef FEPSILON } /** diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c index d5afb39d7b7..2ae87b64286 100644 --- a/source/blender/bmesh/operators/bmo_bevel.c +++ b/source/blender/bmesh/operators/bmo_bevel.c @@ -66,5 +66,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op) BM_mesh_bevel(bm, offset, offset_type, seg, profile, vonly, false, clamp_overlap, NULL, -1, material, loop_slide); BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG); + 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, "verts.out", BM_VERT, BM_ELEM_TAG); } } diff --git a/source/blender/bmesh/operators/bmo_connect_pair.c b/source/blender/bmesh/operators/bmo_connect_pair.c index a73c86fd122..b474ad9fc7b 100644 --- a/source/blender/bmesh/operators/bmo_connect_pair.c +++ b/source/blender/bmesh/operators/bmo_connect_pair.c @@ -530,8 +530,8 @@ static void bm_vert_pair_to_matrix(BMVert *v_pair[2], float r_unit_mat[3][3]) float basis_nor_b[3]; /* align normal to direction */ - project_plane_v3_v3v3(basis_nor_a, v_pair[0]->no, basis_dir); - project_plane_v3_v3v3(basis_nor_b, v_pair[1]->no, basis_dir); + project_plane_normalized_v3_v3v3(basis_nor_a, v_pair[0]->no, basis_dir); + project_plane_normalized_v3_v3v3(basis_nor_b, v_pair[1]->no, basis_dir); /* don't normalize before combining so as normals approach the direction, they have less effect (T46784). */ @@ -569,7 +569,7 @@ static void bm_vert_pair_to_matrix(BMVert *v_pair[2], float r_unit_mat[3][3]) float angle_cos_test; /* project basis dir onto the normal to find its closest angle */ - project_plane_v3_v3v3(basis_dir_proj, basis_dir, l->f->no); + project_plane_normalized_v3_v3v3(basis_dir_proj, basis_dir, l->f->no); if (normalize_v3(basis_dir_proj) > eps) { angle_cos_test = dot_v3v3(basis_dir_proj, basis_dir); @@ -586,7 +586,7 @@ static void bm_vert_pair_to_matrix(BMVert *v_pair[2], float r_unit_mat[3][3]) * note: we could add the directions, * but this more often gives 45d rotated matrix, so just use the best one. */ copy_v3_v3(basis_nor, axis_pair[axis_pair[0].angle_cos < axis_pair[1].angle_cos].nor); - project_plane_v3_v3v3(basis_nor, basis_nor, basis_dir); + project_plane_normalized_v3_v3v3(basis_nor, basis_nor, basis_dir); cross_v3_v3v3(basis_tmp, basis_dir, basis_nor); diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c index a980baf8626..fa08d009d40 100644 --- a/source/blender/bmesh/operators/bmo_create.c +++ b/source/blender/bmesh/operators/bmo_create.c @@ -74,13 +74,13 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op) BMVert *verts[2]; BMEdge *e; - BMO_iter_as_array(op->slots_in, "geom", BM_VERT, (void **)verts, 2); - - /* create edge */ - e = BM_edge_create(bm, verts[0], verts[1], NULL, BM_CREATE_NO_DOUBLE); - BMO_edge_flag_enable(bm, e, ELE_OUT); - tote += 1; - BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, ELE_OUT); + if (BMO_iter_as_array(op->slots_in, "geom", BM_VERT, (void **)verts, 2) == 2) { + /* create edge */ + e = BM_edge_create(bm, verts[0], verts[1], NULL, BM_CREATE_NO_DOUBLE); + BMO_edge_flag_enable(bm, e, ELE_OUT); + tote += 1; + BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, ELE_OUT); + } return; } @@ -283,13 +283,13 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op) */ if (totv > 2) { /* TODO, some of these vertes may be connected by edges, - * this connectivity could be used rather then treating + * this connectivity could be used rather than treating * them as a bunch of isolated verts. */ BMVert **vert_arr = MEM_mallocN(sizeof(BMVert *) * totv, __func__); BMFace *f; - BMO_iter_as_array(op->slots_in, "geom", BM_VERT, (void **)vert_arr, totv); + totv = BMO_iter_as_array(op->slots_in, "geom", BM_VERT, (void **)vert_arr, totv); BM_verts_sort_radial_plane(vert_arr, totv); diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c index 18704a6679f..7d19d90807a 100644 --- a/source/blender/bmesh/operators/bmo_removedoubles.c +++ b/source/blender/bmesh/operators/bmo_removedoubles.c @@ -440,20 +440,24 @@ void bmo_collapse_exec(BMesh *bm, BMOperator *op) edge_stack = BLI_stack_new(sizeof(BMEdge *), __func__); BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - float min[3], max[3], center[3]; + float center[3]; + int count = 0; BMVert *v_tar; + zero_v3(center); + if (!BMO_edge_flag_test(bm, e, EDGE_MARK)) continue; BLI_assert(BLI_stack_is_empty(edge_stack)); - INIT_MINMAX(min, max); for (e = BMW_begin(&walker, e->v1); e; e = BMW_step(&walker)) { BLI_stack_push(edge_stack, &e); - minmax_v3v3_v3(min, max, e->v1->co); - minmax_v3v3_v3(min, max, e->v2->co); + add_v3_v3(center, e->v1->co); + add_v3_v3(center, e->v2->co); + + count += 2; /* prevent adding to slot_targetmap multiple times */ BM_elem_flag_disable(e->v1, BM_ELEM_TAG); @@ -461,8 +465,7 @@ void bmo_collapse_exec(BMesh *bm, BMOperator *op) } if (!BLI_stack_is_empty(edge_stack)) { - - mid_v3_v3v3(center, min, max); + mul_v3_fl(center, 1.0f / count); /* snap edges to a point. for initial testing purposes anyway */ e = *(BMEdge **)BLI_stack_peek(edge_stack); diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 74841dc2756..6673c5d25cf 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -205,6 +205,29 @@ static int bev_debug_flags = 0; #define DEBUG_OLD_PROJ_TO_PERP_PLANE (bev_debug_flags & 2) #define DEBUG_OLD_FLAT_MID (bev_debug_flags & 4) +/* this flag values will get set on geom we want to return in 'out' slots for edges and verts */ +#define EDGE_OUT 4 +#define VERT_OUT 8 + +/* If we're called from the modifier, tool flags aren't available, but don't need output geometry */ +static void flag_out_edge(BMesh *bm, BMEdge *bme) +{ + if (bm->use_toolflags) + BMO_edge_flag_enable(bm, bme, EDGE_OUT); +} + +static void flag_out_vert(BMesh *bm, BMVert *bmv) +{ + if (bm->use_toolflags) + BMO_vert_flag_enable(bm, bmv, VERT_OUT); +} + +static void disable_flag_out_edge(BMesh *bm, BMEdge *bme) +{ + if (bm->use_toolflags) + BMO_edge_flag_disable(bm, bme, EDGE_OUT); +} + /* Are d1 and d2 parallel or nearly so? */ static bool nearly_parallel(const float d1[3], const float d2[3]) { @@ -262,6 +285,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, BM_CREATE_NOP); BM_elem_flag_disable(nv->v, BM_ELEM_TAG); + flag_out_vert(bm, nv->v); } static void copy_mesh_vert( @@ -504,9 +528,12 @@ static BMFace *bev_create_ngon( } /* not essential for bevels own internal logic, - * this is done so the operator can select newly created faces */ + * this is done so the operator can select newly created geometry */ if (f) { BM_elem_flag_enable(f, BM_ELEM_TAG); + BM_ITER_ELEM(bme, &iter, f, BM_EDGES_OF_FACE) { + flag_out_edge(bm, bme); + } } if (mat_nr >= 0) @@ -3213,6 +3240,7 @@ static void bevel_build_trifan(BevelParams *bp, BMesh *bm, BevVert *bv) BMFace *f_new; BLI_assert(v_fan == l_fan->v); f_new = BM_face_split(bm, f, l_fan, l_fan->next->next, &l_new, NULL, false); + flag_out_edge(bm, l_new->e); if (f_new->len > f->len) { f = f_new; @@ -3259,6 +3287,7 @@ static void bevel_build_quadstrip(BevelParams *bp, BMesh *bm, BevVert *bv) else { BM_face_split(bm, f, l_a, l_b, &l_new, NULL, false); f = l_new->f; + flag_out_edge(bm, l_new->e); /* walk around the new face to get the next verts to split */ l_a = l_new->prev; @@ -3278,7 +3307,7 @@ static void bevel_vert_two_edges(BevelParams *bp, BMesh *bm, BevVert *bv) { VMesh *vm = bv->vmesh; BMVert *v1, *v2; - BMEdge *e_eg; + BMEdge *e_eg, *bme; Profile *pro; float co[3]; BoundVert *bndv; @@ -3320,7 +3349,9 @@ static void bevel_vert_two_edges(BevelParams *bp, BMesh *bm, BevVert *bv) v1 = mesh_vert(vm, 0, 0, k)->v; v2 = mesh_vert(vm, 0, 0, k + 1)->v; BLI_assert(v1 != NULL && v2 != NULL); - BM_edge_create(bm, v1, v2, e_eg, BM_CREATE_NO_DOUBLE); + bme = BM_edge_create(bm, v1, v2, e_eg, BM_CREATE_NO_DOUBLE); + if (bme) + flag_out_edge(bm, bme); } } } @@ -3901,7 +3932,7 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v) /* Face f has at least one beveled vertex. Rebuild f */ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f) { - BMIter liter; + BMIter liter, eiter, fiter; BMLoop *l, *lprev; BevVert *bv; BoundVert *v, *vstart, *vend; @@ -3909,10 +3940,10 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f) VMesh *vm; int i, k, n; bool do_rebuild = false; - bool go_ccw, corner3special; + bool go_ccw, corner3special, keep; BMVert *bmv; BMEdge *bme, *bme_new, *bme_prev; - BMFace *f_new; + BMFace *f_new, *f_other; BMVert **vv = NULL; BMVert **vv_fix = NULL; BMEdge **ee = NULL; @@ -4050,9 +4081,21 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f) } } - /* don't select newly created boundary faces... */ + /* don't select newly or return created boundary faces... */ if (f_new) { BM_elem_flag_disable(f_new, BM_ELEM_TAG); + /* Also don't want new edges that aren't part of a new bevel face */ + BM_ITER_ELEM(bme, &eiter, f_new, BM_EDGES_OF_FACE) { + keep = false; + BM_ITER_ELEM(f_other, &fiter, bme, BM_FACES_OF_EDGE) { + if (BM_elem_flag_test(f_other, BM_ELEM_TAG)) { + keep = true; + break; + } + } + if (!keep) + disable_flag_out_edge(bm, bme); + } } } @@ -4134,8 +4177,9 @@ static void bevel_reattach_wires(BMesh *bm, BevelParams *bp, BMVert *v) } } } while ((bndv = bndv->next) != bv->vmesh->boundstart); - if (vclosest) + if (vclosest) { BM_edge_create(bm, vclosest, votherclosest, e, BM_CREATE_NO_DOUBLE); + } } } @@ -4539,9 +4583,9 @@ static float bevel_limit_offset(BMesh *bm, BevelParams *bp) /** * - Currently only bevels BM_ELEM_TAG'd verts and edges. * - * - Newly created faces are BM_ELEM_TAG'd too, - * the caller needs to ensure this is cleared before calling - * if its going to use this face tag. + * - Newly created faces, edges, and verts are BM_ELEM_TAG'd too, + * the caller needs to ensure these are cleared before calling + * if its going to use this tag. * * - If limit_offset is set, adjusts offset down if necessary * to avoid geometry collisions. @@ -4633,6 +4677,20 @@ void BM_mesh_bevel( } } + /* When called from operator (as opposed to modifier), bm->use_toolflags + * will be set, and we to transfer the oflags to BM_ELEM_TAGs */ + if (bm->use_toolflags) { + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + if (BMO_vert_flag_test(bm, v, VERT_OUT)) + BM_elem_flag_enable(v, BM_ELEM_TAG); + } + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (BMO_edge_flag_test(bm, e, EDGE_OUT)) { + BM_elem_flag_enable(e, BM_ELEM_TAG); + } + } + } + /* primary free */ BLI_ghash_free(bp.vert_hash, NULL, NULL); BLI_memarena_free(bp.mem_arena); diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp index 9348f3b3285..d2495a8cb9f 100644 --- a/source/blender/collada/ArmatureExporter.cpp +++ b/source/blender/collada/ArmatureExporter.cpp @@ -116,7 +116,10 @@ bool ArmatureExporter::add_instance_controller(Object *ob) write_bone_URLs(ins, ob_arm, bone); } - InstanceWriter::add_material_bindings(ins.getBindMaterial(), ob, this->export_settings->active_uv_only); + InstanceWriter::add_material_bindings(ins.getBindMaterial(), + ob, + this->export_settings->active_uv_only, + this->export_settings->export_texture_type); ins.add(); return true; diff --git a/source/blender/collada/ControllerExporter.cpp b/source/blender/collada/ControllerExporter.cpp index 1c2642e8313..5cd5e6d271a 100644 --- a/source/blender/collada/ControllerExporter.cpp +++ b/source/blender/collada/ControllerExporter.cpp @@ -98,7 +98,10 @@ bool ControllerExporter::add_instance_controller(Object *ob) write_bone_URLs(ins, ob_arm, bone); } - InstanceWriter::add_material_bindings(ins.getBindMaterial(), ob, this->export_settings->active_uv_only); + InstanceWriter::add_material_bindings(ins.getBindMaterial(), + ob, + this->export_settings->active_uv_only, + this->export_settings->export_texture_type); ins.add(); return true; diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index bd32e989ae3..634071bc90f 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -138,7 +138,8 @@ extern bool bc_has_object_type(LinkNode *export_set, short obtype); char *bc_CustomData_get_layer_name(const struct CustomData *data, int type, int n) { int layer_index = CustomData_get_layer_index(data, type); - if (layer_index < 0) return NULL; + if (layer_index < 0) + return NULL; return data->layers[layer_index + n].name; } @@ -147,9 +148,10 @@ char *bc_CustomData_get_active_layer_name(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 NULL; + if (layer_index < 1) + return NULL; - return data->layers[layer_index].name; + return bc_CustomData_get_layer_name(data, type, layer_index-1); } DocumentExporter::DocumentExporter(const ExportSettings *export_settings) : export_settings(export_settings) { diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp index 226f319cefd..435eaa0208a 100644 --- a/source/blender/collada/DocumentImporter.cpp +++ b/source/blender/collada/DocumentImporter.cpp @@ -388,9 +388,7 @@ Object *DocumentImporter::create_camera_object(COLLADAFW::InstanceCamera *camera Camera *cam = uid_camera_map[cam_uid]; Camera *old_cam = (Camera *)ob->data; ob->data = cam; - id_us_min(&old_cam->id); - if (old_cam->id.us == 0) - BKE_libblock_free(G.main, old_cam); + BKE_libblock_free_us(G.main, old_cam); return ob; } @@ -406,9 +404,7 @@ Object *DocumentImporter::create_lamp_object(COLLADAFW::InstanceLight *lamp, Sce Lamp *la = uid_lamp_map[lamp_uid]; Lamp *old_lamp = (Lamp *)ob->data; ob->data = la; - id_us_min(&old_lamp->id); - if (old_lamp->id.us == 0) - BKE_libblock_free(G.main, old_lamp); + BKE_libblock_free_us(G.main, old_lamp); return ob; } diff --git a/source/blender/collada/EffectExporter.cpp b/source/blender/collada/EffectExporter.cpp index 76b51148509..2bf0859b0f0 100644 --- a/source/blender/collada/EffectExporter.cpp +++ b/source/blender/collada/EffectExporter.cpp @@ -27,7 +27,6 @@ #include <map> -#include <set> #include "COLLADASWEffectProfile.h" #include "COLLADAFWColorOrTexture.h" @@ -49,21 +48,10 @@ extern "C" { #include "BKE_material.h" } -// OB_MESH is assumed -static std::string getActiveUVLayerName(Object *ob) -{ - Mesh *me = (Mesh *)ob->data; - - int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE); - if (num_layers) - return std::string(bc_CustomData_get_active_layer_name(&me->fdata, CD_MTFACE)); - - return ""; -} - EffectsExporter::EffectsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryEffects(sw), export_settings(export_settings) { } + bool EffectsExporter::hasEffects(Scene *sce) { Base *base = (Base *)sce->base.first; @@ -86,13 +74,49 @@ bool EffectsExporter::hasEffects(Scene *sce) void EffectsExporter::exportEffects(Scene *sce) { - if (hasEffects(sce)) { - this->scene = sce; - openLibrary(); - MaterialFunctor mf; - mf.forEachMaterialInExportSet<EffectsExporter>(sce, *this, this->export_settings->export_set); - - closeLibrary(); + this->scene = sce; + + if (this->export_settings->export_texture_type == BC_TEXTURE_TYPE_MAT) { + if (hasEffects(sce)) { + MaterialFunctor mf; + openLibrary(); + mf.forEachMaterialInExportSet<EffectsExporter>(sce, *this, this->export_settings->export_set); + closeLibrary(); + } + } + else { + std::set<Object *> uv_textured_obs = bc_getUVTexturedObjects(sce, !this->export_settings->active_uv_only); + std::set<Image *> uv_images = bc_getUVImages(sce, !this->export_settings->active_uv_only); + if (uv_images.size() > 0) { + openLibrary(); + std::set<Image *>::iterator uv_images_iter; + for (uv_images_iter = uv_images.begin(); + uv_images_iter != uv_images.end(); + uv_images_iter++) { + + Image *ima = *uv_images_iter; + std::string key(id_name(ima)); + key = translate_id(key); + COLLADASW::Sampler sampler(COLLADASW::Sampler::SAMPLER_TYPE_2D, + key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX, + key + COLLADASW::Sampler::SURFACE_SID_SUFFIX); + sampler.setImageId(key); + + openEffect(key + "-effect"); + COLLADASW::EffectProfile ep(mSW); + ep.setProfileType(COLLADASW::EffectProfile::COMMON); + ep.setShaderType(COLLADASW::EffectProfile::PHONG); + ep.setDiffuse(createTexture(ima, key, &sampler), false, "diffuse"); + COLLADASW::ColorOrTexture cot = getcol(0, 0, 0, 1.0f); + ep.setSpecular(cot, false, "specular"); + ep.openProfile(); + ep.addProfileElements(); + ep.addExtraTechniques(mSW); + ep.closeProfile(); + closeEffect(); + } + closeLibrary(); + } } } @@ -176,8 +200,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob) { // create a list of indices to textures of type TEX_IMAGE std::vector<int> tex_indices; - if (this->export_settings->include_material_textures) - createTextureIndices(ma, tex_indices); + createTextureIndices(ma, tex_indices); openEffect(translate_id(id_name(ma)) + "-effect"); @@ -311,61 +334,9 @@ void EffectsExporter::operator()(Material *ma, Object *ob) } } - int active_uv_layer = -1; - std::set<Image *> uv_textures; - if (ob->type == OB_MESH && ob->totcol && this->export_settings->include_uv_textures) { - bool active_uv_only = this->export_settings->active_uv_only; - Mesh *me = (Mesh *) ob->data; - active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY); - - BKE_mesh_tessface_ensure(me); - for (int i = 0; i < me->pdata.totlayer; i++) { - if (!active_uv_only || active_uv_layer == i) - { - if (me->pdata.layers[i].type == CD_MTEXPOLY) { - MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data; - MPoly *mpoly = me->mpoly; - for (int j = 0; j < me->totpoly; j++, mpoly++, txface++) { - - Material *mat = give_current_material(ob, mpoly->mat_nr + 1); - if (mat != ma) - continue; - - Image *ima = txface->tpage; - if (ima == NULL) - continue; - - - bool not_in_list = uv_textures.find(ima)==uv_textures.end(); - if (not_in_list) { - std::string name = id_name(ima); - std::string key(name); - key = translate_id(key); - - // create only one <sampler>/<surface> pair for each unique image - if (im_samp_map.find(key) == im_samp_map.end()) { - //<newparam> <sampler> <source> - COLLADASW::Sampler sampler(COLLADASW::Sampler::SAMPLER_TYPE_2D, - key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX, - key + COLLADASW::Sampler::SURFACE_SID_SUFFIX); - sampler.setImageId(key); - samplers[a] = sampler; - samp_surf[b] = &samplers[a]; - im_samp_map[key] = b; - b++; - a++; - uv_textures.insert(ima); - } - } - } - } - } - } - } - // used as fallback when MTex->uvname is "" (this is pretty common) // it is indeed the correct value to use in that case - std::string active_uv(getActiveUVLayerName(ob)); + std::string active_uv(bc_get_active_uvlayer_name(ob)); // write textures // XXX very slow @@ -385,19 +356,6 @@ void EffectsExporter::operator()(Material *ma, Object *ob) writeTextures(ep, key, sampler, t, ima, uvname); } - std::set<Image *>::iterator uv_t_iter; - int idx; - for (idx = 0, uv_t_iter = uv_textures.begin(); uv_t_iter != uv_textures.end(); uv_t_iter++, idx++ ) { - if (active_uv_layer>-1 && idx==active_uv_layer) { - Image *ima = *uv_t_iter; - std::string key(id_name(ima)); - key = translate_id(key); - int i = im_samp_map[key]; - COLLADASW::Sampler *sampler = (COLLADASW::Sampler *)samp_surf[i]; - ep.setDiffuse(createTexture(ima, active_uv, sampler), false, "diffuse"); - } - } - // performs the actual writing ep.addProfileElements(); bool twoSided = false; diff --git a/source/blender/collada/EffectExporter.h b/source/blender/collada/EffectExporter.h index d20cbfdfe0b..7d45a085777 100644 --- a/source/blender/collada/EffectExporter.h +++ b/source/blender/collada/EffectExporter.h @@ -48,7 +48,6 @@ class EffectsExporter: COLLADASW::LibraryEffects public: EffectsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings); void exportEffects(Scene *sce); - void operator()(Material *ma, Object *ob); COLLADASW::ColorOrTexture createTexture(Image *ima, diff --git a/source/blender/collada/ErrorHandler.cpp b/source/blender/collada/ErrorHandler.cpp index 98aa85f8a9b..32aa5636e08 100644 --- a/source/blender/collada/ErrorHandler.cpp +++ b/source/blender/collada/ErrorHandler.cpp @@ -49,7 +49,7 @@ ErrorHandler::~ErrorHandler() //-------------------------------------------------------------------- bool ErrorHandler::handleError(const COLLADASaxFWL::IError *error) { - bool isError = true; + bool isError = false; if (error->getErrorClass() == COLLADASaxFWL::IError::ERROR_SAXPARSER) { COLLADASaxFWL::SaxParserError *saxParserError = (COLLADASaxFWL::SaxParserError *) error; @@ -81,10 +81,7 @@ bool ErrorHandler::handleError(const COLLADASaxFWL::IError *error) * Accept non critical errors as warnings (i.e. texture not found) * This makes the importer more graceful, so it now imports what makes sense. */ - if (saxFWLError->getSeverity() == COLLADASaxFWL::IError::SEVERITY_ERROR_NONCRITICAL) { - isError = false; - } - + isError = (saxFWLError->getSeverity() != COLLADASaxFWL::IError::SEVERITY_ERROR_NONCRITICAL); std::cout << "Sax FWL Error: " << saxFWLError->getErrorMessage() << std::endl; } else { @@ -93,5 +90,5 @@ bool ErrorHandler::handleError(const COLLADASaxFWL::IError *error) mError |= isError; - return false; // let OpenCollada decide when to abort + return isError; // let OpenCollada decide when to abort } diff --git a/source/blender/collada/ExportSettings.h b/source/blender/collada/ExportSettings.h index de91f68a492..6d90edd2f67 100644 --- a/source/blender/collada/ExportSettings.h +++ b/source/blender/collada/ExportSettings.h @@ -28,7 +28,6 @@ #define __EXPORTSETTINGS_H__ #include "collada.h" -#include "collada.h" struct ExportSettings { public: @@ -42,8 +41,7 @@ public: bool deform_bones_only; bool active_uv_only; - bool include_uv_textures; - bool include_material_textures; + BC_export_texture_type export_texture_type; bool use_texture_copies; bool triangulate; diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp index 7c7c57f3305..b8b1ff7fd95 100644 --- a/source/blender/collada/GeometryExporter.cpp +++ b/source/blender/collada/GeometryExporter.cpp @@ -52,6 +52,7 @@ extern "C" { #include "collada_internal.h" #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) { @@ -134,13 +135,22 @@ void GeometryExporter::operator()(Object *ob) // Only create Polylists if number of faces > 0 if (me->totface > 0) { // XXX slow - if (ob->totcol) { - for (int a = 0; a < ob->totcol; a++) { - createPolylist(a, has_uvs, has_color, ob, me, geom_id, norind); + std::set<Image *> uv_images = bc_getUVImages(ob, !this->export_settings->active_uv_only); + if (this->export_settings->export_texture_type == BC_TEXTURE_TYPE_MAT || uv_images.size() == 0) { + if (ob->totcol) { + for (int a = 0; a < ob->totcol; a++) { + createPolylist(a, has_uvs, has_color, ob, me, geom_id, norind); + } + } + else { + int i = 0; + createPolylist(i, has_uvs, has_color, ob, me, geom_id, norind); } } else { - createPolylist(0, has_uvs, has_color, ob, me, geom_id, norind); + bool all_uv_layers = !this->export_settings->active_uv_only; + std::set<Image *> uv_images = bc_getUVImages(ob, all_uv_layers); + createPolylists(uv_images, has_uvs, has_color, ob, me, geom_id, norind); } } @@ -220,13 +230,15 @@ void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb) //createLooseEdgeList(ob, me, geom_id, norind); // XXX slow - if (ob->totcol) { + if (ob->totcol && this->export_settings->export_texture_type == BC_TEXTURE_TYPE_MAT) { 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); + bool all_uv_layers = !this->export_settings->active_uv_only; + std::set<Image *> uv_images = bc_getUVImages(ob, all_uv_layers); + createPolylists(uv_images, has_uvs, has_color, ob, me, geom_id, norind); } closeMesh(); @@ -295,7 +307,44 @@ std::string GeometryExporter::makeVertexColorSourceId(std::string& geom_id, char return result; } -// powerful because it handles both cases when there is material and when there's not +static void prepareToAppendValues(bool is_triangulated, COLLADASW::PrimitivesBase *facelist, std::vector<unsigned long> &vcount_list) +{ + // performs the actual writing + if (is_triangulated) { + ((COLLADASW::Triangles *)facelist)->prepareToAppendValues(); + } + else { + // sets <vcount> + facelist->setVCountList(vcount_list); + ((COLLADASW::Polylist *)facelist)-> prepareToAppendValues(); + } +} + +static void finishList(bool is_triangulated, COLLADASW::PrimitivesBase *facelist) +{ + if (is_triangulated) { + ((COLLADASW::Triangles *)facelist)->finish(); + } + else { + ((COLLADASW::Polylist *)facelist)->finish(); + } +} + +COLLADASW::PrimitivesBase *getFacelist(bool is_triangulated, COLLADASW::StreamWriter *mSW) +{ + COLLADASW::PrimitivesBase *facelist; + + if (is_triangulated) + { + facelist = new COLLADASW::Triangles(mSW); + } + else { + facelist = new COLLADASW::Polylist(mSW); + } + return facelist; +} + +// Export meshes with Materials void GeometryExporter::createPolylist(short material_index, bool has_uvs, bool has_color, @@ -313,7 +362,7 @@ void GeometryExporter::createPolylist(short material_index, int i; int faces_in_polylist = 0; std::vector<unsigned long> vcount_list; - + bool is_triangulated = true; // count faces with this material for (i = 0; i < totpolys; i++) { MPoly *p = &mpolys[i]; @@ -321,6 +370,9 @@ void GeometryExporter::createPolylist(short material_index, if (p->mat_nr == material_index) { faces_in_polylist++; vcount_list.push_back(p->totloop); + if (p->totloop != 3) { + is_triangulated = false; + } } } @@ -331,20 +383,21 @@ void GeometryExporter::createPolylist(short material_index, } Material *ma = ob->totcol ? give_current_material(ob, material_index + 1) : NULL; - COLLADASW::Polylist polylist(mSW); + COLLADASW::PrimitivesBase *facelist = getFacelist(is_triangulated, mSW); + // sets count attribute in <polylist> - polylist.setCount(faces_in_polylist); + facelist->setCount(faces_in_polylist); // sets material name if (ma) { std::string material_id = get_material_id(ma); std::ostringstream ostr; ostr << translate_id(material_id); - polylist.setMaterial(ostr.str()); + facelist->setMaterial(ostr.str()); } - COLLADASW::InputList &til = polylist.getInputList(); + COLLADASW::InputList &til = facelist->getInputList(); // creates <input> in <polylist> for vertices COLLADASW::Input input1(COLLADASW::InputSemantic::VERTEX, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX), 0); @@ -360,13 +413,21 @@ void GeometryExporter::createPolylist(short material_index, int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE)-1; for (i = 0; i < num_layers; i++) { if (!this->export_settings->active_uv_only || i == active_uv_index) { - - // char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i); + + std::string uv_name(bc_get_uvlayer_name(me, i)); + std::string effective_id = geom_id; // (uv_name == "") ? geom_id : uv_name; + std::string layer_id = makeTexcoordSourceId( + effective_id, + i, this->export_settings->active_uv_only); + + /* Note: the third parameter denotes the offset of TEXCOORD in polylist elements + For now this is always 2 (This may change sometime/maybe) + */ COLLADASW::Input input3(COLLADASW::InputSemantic::TEXCOORD, - makeUrl(makeTexcoordSourceId(geom_id, i, this->export_settings->active_uv_only)), - 2, // this is only until we have optimized UV sets - (this->export_settings->active_uv_only) ? 0 : i // only_active_uv exported -> we have only one set - ); + makeUrl(layer_id), + 2, // this is only until we have optimized UV sets + (this->export_settings->active_uv_only) ? 0 : i // only_active_uv exported -> we have only one set + ); til.push_back(input3); } } @@ -387,12 +448,10 @@ void GeometryExporter::createPolylist(short material_index, } } - // sets <vcount> - polylist.setVCountList(vcount_list); // performs the actual writing - polylist.prepareToAppendValues(); - + prepareToAppendValues(is_triangulated, facelist, vcount_list); + // <p> int texindex = 0; for (i = 0; i < totpolys; i++) { @@ -404,22 +463,202 @@ void GeometryExporter::createPolylist(short material_index, BCPolygonNormalsIndices normal_indices = norind[i]; for (int j = 0; j < loop_count; j++) { - polylist.appendValues(l[j].v); - polylist.appendValues(normal_indices[j]); + facelist->appendValues(l[j].v); + facelist->appendValues(normal_indices[j]); if (has_uvs) - polylist.appendValues(texindex + j); + facelist->appendValues(texindex + j); if (has_color) - polylist.appendValues(texindex + j); + facelist->appendValues(texindex + j); } } texindex += loop_count; } - - polylist.finish(); + + finishList(is_triangulated, facelist); + delete facelist; +} + +void GeometryExporter::createPolylists(std::set<Image *> uv_images, + bool has_uvs, + bool has_color, + Object *ob, + Mesh *me, + std::string& geom_id, + std::vector<BCPolygonNormalsIndices>& norind) +{ + std::set<Image *>::iterator uv_images_iter; + for (uv_images_iter = uv_images.begin(); + uv_images_iter != uv_images.end(); + uv_images_iter++) { + + Image *ima = *uv_images_iter; + std::string imageid(id_name(ima)); + createPolylist(imageid, has_uvs, + has_color, + ob, + me, + geom_id, + norind); + } + + /* We msut add an additional collector for the case when + * some parts of the object are not textured at all. + * The next call creates a polylist for all untextured polygons + */ + + createPolylist("", has_uvs, + has_color, + ob, + me, + geom_id, + norind); + } +/* =========================================================================== + * Export Meshes with UV Textures (export as materials, see also in + * effectExporter and MaterialExporter) + * + * If imageid is the empty string, then collect only untextured polygons + * =========================================================================== */ +void GeometryExporter::createPolylist(std::string imageid, + bool has_uvs, + bool has_color, + Object *ob, + Mesh *me, + std::string& geom_id, + std::vector<BCPolygonNormalsIndices>& norind) +{ + + MPoly *mpolys = me->mpoly; + MLoop *mloops = me->mloop; + MTexPoly *mtpolys = me->mtpoly; + + int totpolys = me->totpoly; + + // <vcount> + int i; + int faces_in_polylist = 0; + std::vector<unsigned long> vcount_list; + bool is_triangulated = true; + // count faces with this material + for (i = 0; i < totpolys; i++) { + MTexPoly *tp = &mtpolys[i]; + MPoly *p = &mpolys[i]; + + std::string tpageid = (tp->tpage) ? id_name(tp->tpage):""; + if (tpageid == imageid) { + faces_in_polylist++; + vcount_list.push_back(p->totloop); + if (p->totloop != 3) { + is_triangulated = false; + } + } + } + + // no faces using this imageid + if (faces_in_polylist == 0) { + if (imageid != "") + fprintf(stderr, "%s: Image %s is not used.\n", id_name(ob).c_str(), imageid.c_str()); + return; + } + + COLLADASW::PrimitivesBase *facelist = getFacelist(is_triangulated, mSW); + + // sets count attribute in <polylist> + facelist->setCount(faces_in_polylist); + + if (imageid != "") { + // sets material name + std::string material_id = get_material_id_from_id(imageid); + std::ostringstream ostr; + ostr << translate_id(material_id); + facelist->setMaterial(ostr.str()); + } + COLLADASW::InputList &til = facelist->getInputList(); + + // creates <input> in <polylist> for vertices + COLLADASW::Input input1(COLLADASW::InputSemantic::VERTEX, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX), 0); + + // creates <input> in <polylist> for normals + COLLADASW::Input input2(COLLADASW::InputSemantic::NORMAL, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL), 1); + + til.push_back(input1); + til.push_back(input2); + + // if mesh has uv coords writes <input> for TEXCOORD + int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE); + int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE) - 1; + for (i = 0; i < num_layers; i++) { + if (!this->export_settings->active_uv_only || i == active_uv_index) { + + std::string uv_name(bc_get_uvlayer_name(me, i)); + std::string effective_id = geom_id; // (uv_name == "") ? geom_id : uv_name; + std::string layer_id = makeTexcoordSourceId( + effective_id, + i, this->export_settings->active_uv_only); + + /* Note: the third parameter denotes the offset of TEXCOORD in polylist elements + For now this is always 2 (This may change sometime/maybe) + */ + COLLADASW::Input input3(COLLADASW::InputSemantic::TEXCOORD, + makeUrl(layer_id), + 2, // this is only until we have optimized UV sets + (this->export_settings->active_uv_only) ? 0 : i // only_active_uv exported -> we have only one set + ); + til.push_back(input3); + } + } + + int totlayer_mcol = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL); + if (totlayer_mcol > 0) { + int map_index = 0; + + for (int a = 0; a < totlayer_mcol; a++) { + char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_MLOOPCOL, a); + COLLADASW::Input input4(COLLADASW::InputSemantic::COLOR, + makeUrl(makeVertexColorSourceId(geom_id, layer_name)), + (has_uvs) ? 3 : 2, // all color layers have same index order + map_index // set number equals color map index + ); + til.push_back(input4); + map_index++; + } + } + + // performs the actual writing + prepareToAppendValues(is_triangulated, facelist, vcount_list); + + // <p> + int texindex = 0; + for (i = 0; i < totpolys; i++) { + MTexPoly *tp = &mtpolys[i]; + MPoly *p = &mpolys[i]; + int loop_count = p->totloop; + std::string tpageid = (tp->tpage) ? id_name(tp->tpage) : ""; + if (tpageid == imageid) { + MLoop *l = &mloops[p->loopstart]; + BCPolygonNormalsIndices normal_indices = norind[i]; + + for (int j = 0; j < loop_count; j++) { + facelist->appendValues(l[j].v); + facelist->appendValues(normal_indices[j]); + if (has_uvs) + facelist->appendValues(texindex + j); + + if (has_color) + facelist->appendValues(texindex + j); + } + } + + texindex += loop_count; + } + + finishList(is_triangulated, facelist); + delete facelist; +} // creates <source> for positions void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me) @@ -537,7 +776,13 @@ void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me) MLoopUV *mloops = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, a); COLLADASW::FloatSourceF source(mSW); - std::string layer_id = makeTexcoordSourceId(geom_id, a, this->export_settings->active_uv_only); + std::string active_uv_name(bc_get_active_uvlayer_name(me)); + std::string effective_id = geom_id; // (active_uv_name == "") ? geom_id : active_uv_name; + std::string layer_id = makeTexcoordSourceId( + effective_id, + a, + this->export_settings->active_uv_only ); + source.setId(layer_id); source.setArrayId(layer_id + ARRAY_ID_SUFFIX); diff --git a/source/blender/collada/GeometryExporter.h b/source/blender/collada/GeometryExporter.h index 69d1067e6f4..890304f4568 100644 --- a/source/blender/collada/GeometryExporter.h +++ b/source/blender/collada/GeometryExporter.h @@ -85,15 +85,33 @@ public: Mesh *me, std::string& geom_id); - // powerful because it handles both cases when there is material and when there's not + // Create polylists for meshes with Materials void createPolylist(short material_index, - bool has_uvs, - bool has_color, - Object *ob, - Mesh *me, - std::string& geom_id, - std::vector<BCPolygonNormalsIndices>& norind); - + bool has_uvs, + bool has_color, + Object *ob, + Mesh *me, + std::string& geom_id, + std::vector<BCPolygonNormalsIndices>& norind); + + // Create polylists for meshes with UV Textures + void createPolylists(std::set<Image *> uv_images, + bool has_uvs, + bool has_color, + Object *ob, + Mesh *me, + std::string& geom_id, + std::vector<BCPolygonNormalsIndices>& norind); + + // Create polylists for meshes with UV Textures + void createPolylist(std::string imageid, + bool has_uvs, + bool has_color, + Object *ob, + Mesh *me, + std::string& geom_id, + std::vector<BCPolygonNormalsIndices>& norind); + // creates <source> for positions void createVertsSource(std::string geom_id, Mesh *me); diff --git a/source/blender/collada/ImageExporter.cpp b/source/blender/collada/ImageExporter.cpp index aac41e2e93c..93be7de6236 100644 --- a/source/blender/collada/ImageExporter.cpp +++ b/source/blender/collada/ImageExporter.cpp @@ -55,9 +55,9 @@ ImagesExporter::ImagesExporter(COLLADASW::StreamWriter *sw, const ExportSettings void ImagesExporter::export_UV_Image(Image *image, bool use_copies) { - std::string name(id_name(image)); - std::string translated_name(translate_id(name)); - bool not_yet_exported = find(mImages.begin(), mImages.end(), translated_name) == mImages.end(); + std::string id(id_name(image)); + std::string translated_id(translate_id(id)); + bool not_yet_exported = find(mImages.begin(), mImages.end(), translated_id) == mImages.end(); if (not_yet_exported) { @@ -88,7 +88,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)); + BLI_strncpy(export_file, id.c_str(), sizeof(export_file)); BKE_image_path_ensure_ext_from_imformat(export_file, &imageFormat); BLI_join_dirfile(export_path, sizeof(export_path), export_dir, export_file); @@ -143,10 +143,11 @@ void ImagesExporter::export_UV_Image(Image *image, bool use_copies) } } - COLLADASW::Image img(COLLADABU::URI(COLLADABU::URI::nativePathToUri(export_path)), translated_name, translated_name); /* set name also to mNameNC. This helps other viewers import files exported from Blender better */ + /* set name also to mNameNC. This helps other viewers import files exported from Blender better */ + COLLADASW::Image img(COLLADABU::URI(COLLADABU::URI::nativePathToUri(export_path)), translated_id, translated_id); img.add(mSW); fprintf(stdout, "Collada export: Added image: %s\n", export_file); - mImages.push_back(translated_name); + mImages.push_back(translated_id); BKE_image_release_ibuf(image, imbuf, NULL); } @@ -161,7 +162,7 @@ void ImagesExporter::export_UV_Images() for (node = this->export_settings->export_set; node; node = node->next) { Object *ob = (Object *)node->link; - if (ob->type == OB_MESH && ob->totcol) { + if (ob->type == OB_MESH) { Mesh *me = (Mesh *) ob->data; BKE_mesh_tessface_ensure(me); int active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY); @@ -189,7 +190,13 @@ void ImagesExporter::export_UV_Images() } } - +/* ============================================================ + * Check if there are any images to be exported + * Returns true as soon as an object is detected that + * either has an UV Texture assigned, or has a material + * assigned that uses an Image Texture. + * ============================================================ + */ bool ImagesExporter::hasImages(Scene *sce) { LinkNode *node; @@ -232,11 +239,10 @@ void ImagesExporter::exportImages(Scene *sce) openLibrary(); MaterialFunctor mf; - if (this->export_settings->include_material_textures) { + if (this->export_settings->export_texture_type == BC_TEXTURE_TYPE_MAT) { mf.forEachMaterialInExportSet<ImagesExporter>(sce, *this, this->export_settings->export_set); } - - if (this->export_settings->include_uv_textures) { + else { export_UV_Images(); } diff --git a/source/blender/collada/InstanceWriter.cpp b/source/blender/collada/InstanceWriter.cpp index 71371d280df..de1a4075462 100644 --- a/source/blender/collada/InstanceWriter.cpp +++ b/source/blender/collada/InstanceWriter.cpp @@ -32,43 +32,76 @@ #include "COLLADASWInstanceMaterial.h" extern "C" { - #include "BKE_customdata.h" - #include "BKE_material.h" - #include "DNA_mesh_types.h" +#include "BKE_customdata.h" +#include "BKE_material.h" +#include "DNA_mesh_types.h" } #include "InstanceWriter.h" #include "collada_internal.h" #include "collada_utils.h" -void InstanceWriter::add_material_bindings(COLLADASW::BindMaterial& bind_material, Object *ob, bool active_uv_only) +void InstanceWriter::add_material_bindings(COLLADASW::BindMaterial& bind_material, Object *ob, bool active_uv_only, BC_export_texture_type export_texture_type) { - for (int a = 0; a < ob->totcol; a++) { - Material *ma = give_current_material(ob, a + 1); - - COLLADASW::InstanceMaterialList& iml = bind_material.getInstanceMaterialList(); + bool all_uv_layers = !active_uv_only; + COLLADASW::InstanceMaterialList& iml = bind_material.getInstanceMaterialList(); - if (ma) { - std::string matid(get_material_id(ma)); - matid = translate_id(matid); + if (export_texture_type == BC_TEXTURE_TYPE_UV) + { + std::set<Image *> uv_images = bc_getUVImages(ob, all_uv_layers); + std::set<Image *>::iterator uv_images_iter; + for (uv_images_iter = uv_images.begin(); + uv_images_iter != uv_images.end(); + uv_images_iter++) { + Image *ima = *uv_images_iter; + std::string matid(id_name(ima)); + matid = get_material_id_from_id(matid); std::ostringstream ostr; ostr << matid; COLLADASW::InstanceMaterial im(ostr.str(), COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, matid)); - + // create <bind_vertex_input> for each uv map Mesh *me = (Mesh *)ob->data; int totlayer = CustomData_number_of_layers(&me->fdata, CD_MTFACE); - + int map_index = 0; - int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE) -1; + int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE) - 1; for (int b = 0; b < totlayer; b++) { if (!active_uv_only || b == active_uv_index) { char *name = bc_CustomData_get_layer_name(&me->fdata, CD_MTFACE, b); im.push_back(COLLADASW::BindVertexInput(name, "TEXCOORD", map_index++)); } } - + iml.push_back(im); } } + + else { + for (int a = 0; a < ob->totcol; a++) { + Material *ma = give_current_material(ob, a + 1); + if (ma) { + std::string matid(get_material_id(ma)); + matid = translate_id(matid); + std::ostringstream ostr; + ostr << matid; + COLLADASW::InstanceMaterial im(ostr.str(), COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, matid)); + + // create <bind_vertex_input> for each uv map + Mesh *me = (Mesh *)ob->data; + int totlayer = CustomData_number_of_layers(&me->fdata, CD_MTFACE); + + int map_index = 0; + int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE) - 1; + for (int b = 0; b < totlayer; b++) { + if (!active_uv_only || b == active_uv_index) { + char *name = bc_CustomData_get_layer_name(&me->fdata, CD_MTFACE, b); + im.push_back(COLLADASW::BindVertexInput(name, "TEXCOORD", map_index++)); + } + } + + iml.push_back(im); + } + } + } } diff --git a/source/blender/collada/InstanceWriter.h b/source/blender/collada/InstanceWriter.h index 49ddf091b1c..a46027325a2 100644 --- a/source/blender/collada/InstanceWriter.h +++ b/source/blender/collada/InstanceWriter.h @@ -31,11 +31,12 @@ #include "COLLADASWBindMaterial.h" #include "DNA_object_types.h" +#include "collada.h" class InstanceWriter { protected: - void add_material_bindings(COLLADASW::BindMaterial& bind_material, Object *ob, bool active_uv_only); + void add_material_bindings(COLLADASW::BindMaterial& bind_material, Object *ob, bool active_uv_only, BC_export_texture_type export_texture_type); }; #endif diff --git a/source/blender/collada/MaterialExporter.cpp b/source/blender/collada/MaterialExporter.cpp index 4aece997f72..6e6cc24be20 100644 --- a/source/blender/collada/MaterialExporter.cpp +++ b/source/blender/collada/MaterialExporter.cpp @@ -38,14 +38,39 @@ MaterialsExporter::MaterialsExporter(COLLADASW::StreamWriter *sw, const ExportSe void MaterialsExporter::exportMaterials(Scene *sce) { - if (hasMaterials(sce)) { - openLibrary(); + if (this->export_settings->export_texture_type == BC_TEXTURE_TYPE_MAT) + { + if (hasMaterials(sce)) { + openLibrary(); - MaterialFunctor mf; - mf.forEachMaterialInExportSet<MaterialsExporter>(sce, *this, this->export_settings->export_set); + MaterialFunctor mf; + mf.forEachMaterialInExportSet<MaterialsExporter>(sce, *this, this->export_settings->export_set); - closeLibrary(); + closeLibrary(); + } } + + else { + std::set<Image *> uv_images = bc_getUVImages(sce, !this->export_settings->active_uv_only); + if (uv_images.size() > 0) { + openLibrary(); + std::set<Image *>::iterator uv_images_iter; + for (uv_images_iter = uv_images.begin(); + uv_images_iter != uv_images.end(); + uv_images_iter++) { + + Image *ima = *uv_images_iter; + std::string matid(id_name(ima)); + + openMaterial(get_material_id_from_id(matid), translate_id(matid)); + std::string efid = translate_id(matid) + "-effect"; + addInstanceEffect(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, efid)); + closeMaterial(); + } + closeLibrary(); + } + } + } bool MaterialsExporter::hasMaterials(Scene *sce) diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp index a1bfce88131..6ca53c64299 100644 --- a/source/blender/collada/MeshImporter.cpp +++ b/source/blender/collada/MeshImporter.cpp @@ -1173,8 +1173,9 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta BKE_mesh_assign_object(ob, new_mesh); BKE_mesh_calc_normals(new_mesh); - if (old_mesh->id.us == 0) BKE_libblock_free(G.main, old_mesh); - + id_us_plus(&old_mesh->id); /* Because BKE_mesh_assign_object would have already decreased it... */ + BKE_libblock_free_us(G.main, old_mesh); + char layername[100]; layername[0] = '\0'; MTFace *texture_face = NULL; diff --git a/source/blender/collada/SceneExporter.cpp b/source/blender/collada/SceneExporter.cpp index 30cd6ddf197..73945539931 100644 --- a/source/blender/collada/SceneExporter.cpp +++ b/source/blender/collada/SceneExporter.cpp @@ -151,7 +151,10 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce) COLLADASW::InstanceGeometry instGeom(mSW); instGeom.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob, this->export_settings->use_object_instantiation))); instGeom.setName(translate_id(id_name(ob))); - InstanceWriter::add_material_bindings(instGeom.getBindMaterial(), ob, this->export_settings->active_uv_only); + InstanceWriter::add_material_bindings(instGeom.getBindMaterial(), + ob, + this->export_settings->active_uv_only, + this->export_settings->export_texture_type); instGeom.add(); } diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp index bfe3180909b..024bc4a4a5c 100644 --- a/source/blender/collada/collada.cpp +++ b/source/blender/collada/collada.cpp @@ -80,8 +80,7 @@ int collada_export(Scene *sce, int deform_bones_only, int active_uv_only, - int include_uv_textures, - int include_material_textures, + BC_export_texture_type export_texture_type, int use_texture_copies, int triangulate, @@ -106,8 +105,7 @@ int collada_export(Scene *sce, export_settings.deform_bones_only = deform_bones_only != 0; export_settings.active_uv_only = active_uv_only != 0; - export_settings.include_uv_textures = include_uv_textures != 0; - export_settings.include_material_textures= include_material_textures != 0; + export_settings.export_texture_type = export_texture_type; export_settings.use_texture_copies = use_texture_copies != 0; export_settings.triangulate = triangulate != 0; diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h index 8035af59c8b..d31f5a8ba62 100644 --- a/source/blender/collada/collada.h +++ b/source/blender/collada/collada.h @@ -46,6 +46,11 @@ typedef enum BC_export_transformation_type { BC_TRANSFORMATION_TYPE_TRANSROTLOC } BC_export_transformation_type; +typedef enum BC_export_texture_type { + BC_TEXTURE_TYPE_MAT, + BC_TEXTURE_TYPE_UV +} BC_export_texture_type; + struct bContext; struct Scene; @@ -74,8 +79,7 @@ int collada_export(struct Scene *sce, int deform_bones_only, int active_uv_only, - int include_uv_textures, - int include_material_textures, + BC_export_texture_type export_texture_type, int use_texture_copies, int triangulate, @@ -84,9 +88,9 @@ int collada_export(struct Scene *sce, int sort_by_name, BC_export_transformation_type export_transformation_type, - int open_sim, - int limit_precision, - int keep_bind_info); + int open_sim, + int limit_precision, + int keep_bind_info); #ifdef __cplusplus } diff --git a/source/blender/collada/collada_internal.cpp b/source/blender/collada/collada_internal.cpp index 6ebde6bd773..8974acb3460 100644 --- a/source/blender/collada/collada_internal.cpp +++ b/source/blender/collada/collada_internal.cpp @@ -344,7 +344,13 @@ std::string get_camera_id(Object *ob) std::string get_material_id(Material *mat) { - return translate_id(id_name(mat)) + "-material"; + std::string id = id_name(mat); + return get_material_id_from_id(id); +} + +std::string get_material_id_from_id(std::string id) +{ + return translate_id(id) + "-material"; } std::string get_morph_id(Object *ob) diff --git a/source/blender/collada/collada_internal.h b/source/blender/collada/collada_internal.h index 1c7aa160f57..5f3fa34edc1 100644 --- a/source/blender/collada/collada_internal.h +++ b/source/blender/collada/collada_internal.h @@ -103,6 +103,7 @@ extern std::string get_joint_sid(Bone *bone, Object *ob_arm); extern std::string get_camera_id(Object *ob); extern std::string get_material_id(Material *mat); +extern std::string get_material_id_from_id(std::string id); extern std::string get_morph_id(Object *ob); diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp index ac4395e1430..b09732f9102 100644 --- a/source/blender/collada/collada_utils.cpp +++ b/source/blender/collada/collada_utils.cpp @@ -32,6 +32,8 @@ #include "COLLADAFWMeshPrimitive.h" #include "COLLADAFWMeshVertexData.h" +#include <set> + extern "C" { #include "DNA_modifier_types.h" #include "DNA_customdata_types.h" @@ -831,4 +833,160 @@ void bc_sanitize_mat(float mat[4][4], int precision) for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) mat[i][j] = double_round(mat[i][j], precision); +} + +/* +* Returns name of Active UV Layer or empty String if no active UV Layer defined. +* Assuming the Object is of type MESH +*/ +std::string bc_get_active_uvlayer_name(Object *ob) +{ + Mesh *me = (Mesh *)ob->data; + return bc_get_active_uvlayer_name(me); +} + +/* + * Returns name of Active UV Layer or empty String if no active UV Layer defined + */ +std::string bc_get_active_uvlayer_name(Mesh *me) +{ + int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE); + if (num_layers) { + return std::string(bc_CustomData_get_active_layer_name(&me->fdata, CD_MTFACE)); + } + return ""; +} + +/* + * Returns UV Layer name or empty string if layer index is out of range + */ +std::string bc_get_uvlayer_name(Mesh *me, int layer) +{ + int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE); + if (num_layers && layer < num_layers) { + return std::string(bc_CustomData_get_layer_name(&me->fdata, CD_MTFACE, layer)); + } + return ""; +} + +/********************************************************************** +* +* Return the list of Mesh objects with assigned UVtextures and Images +* Note: We need to create artificaial materials for each of them +* +***********************************************************************/ +std::set<Object *> bc_getUVTexturedObjects(Scene *sce, bool all_uv_layers) +{ + std::set <Object *> UVObjects; + Base *base = (Base *)sce->base.first; + + while (base) { + Object *ob = base->object; + bool has_uvimage = false; + if (ob->type == OB_MESH) { + Mesh *me = (Mesh *)ob->data; + int active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY); + + for (int i = 0; i < me->pdata.totlayer && !has_uvimage; i++) { + if (all_uv_layers || active_uv_layer == i) + { + if (me->pdata.layers[i].type == CD_MTEXPOLY) { + MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data; + MPoly *mpoly = me->mpoly; + for (int j = 0; j < me->totpoly; j++, mpoly++, txface++) { + + Image *ima = txface->tpage; + if (ima != NULL) { + has_uvimage = true; + break; + } + } + } + } + } + + if (has_uvimage) { + UVObjects.insert(ob); + } + } + base = base->next; + } + return UVObjects; +} + +/********************************************************************** +* +* Return the list of UV Texture images from all exported Mesh Items +* Note: We need to create one artificial material for each Image. +* +***********************************************************************/ +std::set<Image *> bc_getUVImages(Scene *sce, bool all_uv_layers) +{ + std::set <Image *> UVImages; + Base *base = (Base *)sce->base.first; + + while (base) { + Object *ob = base->object; + bool has_uvimage = false; + if (ob->type == OB_MESH) { + Mesh *me = (Mesh *)ob->data; + int active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY); + + for (int i = 0; i < me->pdata.totlayer && !has_uvimage; i++) { + if (all_uv_layers || active_uv_layer == i) + { + if (me->pdata.layers[i].type == CD_MTEXPOLY) { + MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data; + MPoly *mpoly = me->mpoly; + for (int j = 0; j < me->totpoly; j++, mpoly++, txface++) { + + Image *ima = txface->tpage; + if (ima != NULL) { + if (UVImages.find(ima) == UVImages.end()) + UVImages.insert(ima); + } + } + } + } + } + } + base = base->next; + } + return UVImages; +} + +/********************************************************************** +* +* Return the list of UV Texture images for the given Object +* Note: We need to create one artificial material for each Image. +* +***********************************************************************/ +std::set<Image *> bc_getUVImages(Object *ob, bool all_uv_layers) +{ + std::set <Image *> UVImages; + + bool has_uvimage = false; + if (ob->type == OB_MESH) { + Mesh *me = (Mesh *)ob->data; + int active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY); + + for (int i = 0; i < me->pdata.totlayer && !has_uvimage; i++) { + if (all_uv_layers || active_uv_layer == i) + { + if (me->pdata.layers[i].type == CD_MTEXPOLY) { + MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data; + MPoly *mpoly = me->mpoly; + for (int j = 0; j < me->totpoly; j++, mpoly++, txface++) { + + Image *ima = txface->tpage; + if (ima != NULL) { + if (UVImages.find(ima) == UVImages.end()) + UVImages.insert(ima); + } + } + } + } + } + } + return UVImages; }
\ No newline at end of file diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h index 38c0bd5096a..5447c39e902 100644 --- a/source/blender/collada/collada_utils.h +++ b/source/blender/collada/collada_utils.h @@ -34,6 +34,7 @@ #include <vector> #include <map> +#include <set> #include <algorithm> extern "C" { @@ -80,6 +81,7 @@ extern void bc_set_mark(Object *ob); extern char *bc_CustomData_get_layer_name(const CustomData *data, int type, int n); extern char *bc_CustomData_get_active_layer_name(const CustomData *data, int type); +extern char *bc_CustomData_get_layer_name(const CustomData *data, int layer_index, int type); extern void bc_bubble_sort_by_Object_name(LinkNode *export_set); extern bool bc_is_root_bone(Bone *aBone, bool deform_bones_only); @@ -109,6 +111,14 @@ extern bool bc_get_property_matrix(Bone *bone, std::string key, float mat[4][4]) extern void bc_create_restpose_mat(const ExportSettings *export_settings, Bone *bone, float to_mat[4][4], float world[4][4], bool use_local_space); +extern std::string bc_get_active_uvlayer_name(Object *ob); +extern std::string bc_get_active_uvlayer_name(Mesh *me); +extern std::string bc_get_uvlayer_name(Mesh *me, int layer); + +extern std::set<Image *> bc_getUVImages(Scene *sce, bool all_uv_layers); +extern std::set<Image *> bc_getUVImages(Object *ob, bool all_uv_layers); +extern std::set<Object *> bc_getUVTexturedObjects(Scene *sce, bool all_uv_layers); + class BCPolygonNormalsIndices { std::vector<unsigned int> normal_indices; diff --git a/source/blender/compositor/nodes/COM_ImageNode.cpp b/source/blender/compositor/nodes/COM_ImageNode.cpp index 462947f32a3..81891d853d2 100644 --- a/source/blender/compositor/nodes/COM_ImageNode.cpp +++ b/source/blender/compositor/nodes/COM_ImageNode.cpp @@ -99,6 +99,11 @@ void ImageNode::convertToOperations(NodeConverter &converter, const CompositorCo RenderPass *rpass = (RenderPass *)BLI_findstring(&rl->passes, storage->pass_name, offsetof(RenderPass, name)); int view = 0; + if (STREQ(storage->pass_name, RE_PASSNAME_COMBINED) && STREQ(bnodeSocket->name, "Alpha")) { + /* Alpha output is already handled with the associated combined output. */ + continue; + } + /* returns the image view to use for the current active view */ if (BLI_listbase_count_ex(&image->rr->views, 2) > 1) { const int view_image = imageuser->view; @@ -140,16 +145,24 @@ void ImageNode::convertToOperations(NodeConverter &converter, const CompositorCo converter.addPreview(operation->getOutputSocket()); } if (STREQ(rpass->name, RE_PASSNAME_COMBINED)) { - BLI_assert(operation != NULL); - BLI_assert(index < numberOfOutputs - 1); - NodeOutput *outputSocket = this->getOutputSocket(index + 1); - SeparateChannelOperation *separate_operation; - separate_operation = new SeparateChannelOperation(); - separate_operation->setChannel(3); - converter.addOperation(separate_operation); - converter.addLink(operation->getOutputSocket(), separate_operation->getInputSocket(0)); - converter.mapOutputSocket(outputSocket, separate_operation->getOutputSocket()); - index++; + for (int alphaIndex = 0; alphaIndex < numberOfOutputs; alphaIndex++) { + NodeOutput *alphaSocket = this->getOutputSocket(alphaIndex); + bNodeSocket *bnodeAlphaSocket = alphaSocket->getbNodeSocket(); + if (!STREQ(bnodeAlphaSocket->name, "Alpha")) { + continue; + } + NodeImageLayer *alphaStorage = (NodeImageLayer *)bnodeSocket->storage; + if (!STREQ(alphaStorage->pass_name, RE_PASSNAME_COMBINED)) { + continue; + } + SeparateChannelOperation *separate_operation; + separate_operation = new SeparateChannelOperation(); + separate_operation->setChannel(3); + converter.addOperation(separate_operation); + converter.addLink(operation->getOutputSocket(), separate_operation->getInputSocket(0)); + converter.mapOutputSocket(alphaSocket, separate_operation->getOutputSocket()); + break; + } } } diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp index 1ec52571be8..9ff0bf9ce12 100644 --- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp @@ -286,9 +286,9 @@ void InverseSearchRadiusOperation::initExecution() this->m_inputRadius = this->getInputSocketReader(0); } -voi *InverseSearchRadiusOperation::initializeTileData(rcti *rect) +void *InverseSearchRadiusOperation::initializeTileData(rcti *rect) { - MemoryBuffer * data = new MemoryBuffer(NULL, rect); + MemoryBuffer * data = new MemoryBuffer(COM_DT_COLOR, rect); float *buffer = data->getBuffer(); int x, y; int width = this->m_inputRadius->getWidth(); @@ -343,7 +343,7 @@ voi *InverseSearchRadiusOperation::initializeTileData(rcti *rect) void InverseSearchRadiusOperation::executePixelChunk(float output[4], int x, int y, void *data) { MemoryBuffer *buffer = (MemoryBuffer *)data; - buffer->readNoCheck(color, x, y); + buffer->readNoCheck(output, x, y); } void InverseSearchRadiusOperation::deinitializeTileData(rcti *rect, void *data) diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt index b664af570b1..33a7628c68d 100644 --- a/source/blender/depsgraph/CMakeLists.txt +++ b/source/blender/depsgraph/CMakeLists.txt @@ -87,6 +87,7 @@ set(SRC intern/depsgraph_intern.h intern/depsgraph_types.h + util/deg_util_foreach.h util/deg_util_function.h ) diff --git a/source/blender/depsgraph/DEG_depsgraph_build.h b/source/blender/depsgraph/DEG_depsgraph_build.h index fdc86540171..b65d921cfd1 100644 --- a/source/blender/depsgraph/DEG_depsgraph_build.h +++ b/source/blender/depsgraph/DEG_depsgraph_build.h @@ -153,7 +153,8 @@ void DEG_add_object_cache_relation(struct DepsNodeHandle *handle, eDepsObjectComponentType component, const char *description); -/* TODO(sergey): Remove once all geometry update is granular. */ + +struct Depsgraph *DEG_get_graph_from_handle(struct DepsNodeHandle *handle); void DEG_add_special_eval_flag(struct Depsgraph *graph, struct ID *id, short flag); /* Utility functions for physics modifiers */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc index 143f9908db8..086fd0c1144 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder.cc @@ -36,10 +36,7 @@ #include "BLI_utildefines.h" #include "BLI_ghash.h" - -extern "C" { #include "BLI_stack.h" -} #include "intern/depsgraph.h" #include "intern/depsgraph_types.h" @@ -79,7 +76,7 @@ void deg_graph_build_flush_layers(Depsgraph *graph) node->done = 0; node->num_links_pending = 0; foreach (DepsRelation *rel, node->outlinks) { - if ((rel->from->type == DEPSNODE_TYPE_OPERATION) && + if ((rel->from->type == DEG_NODE_TYPE_OPERATION) && (rel->flag & DEPSREL_FLAG_CYCLIC) == 0) { ++node->num_links_pending; @@ -97,14 +94,14 @@ void deg_graph_build_flush_layers(Depsgraph *graph) BLI_stack_pop(stack, &node); /* Flush layers to parents. */ foreach (DepsRelation *rel, node->inlinks) { - if (rel->from->type == DEPSNODE_TYPE_OPERATION) { + if (rel->from->type == DEG_NODE_TYPE_OPERATION) { OperationDepsNode *from = (OperationDepsNode *)rel->from; from->owner->layers |= node->owner->layers; } } /* Schedule parent nodes. */ foreach (DepsRelation *rel, node->inlinks) { - if (rel->from->type == DEPSNODE_TYPE_OPERATION) { + if (rel->from->type == DEG_NODE_TYPE_OPERATION) { OperationDepsNode *from = (OperationDepsNode *)rel->from; if ((rel->flag & DEPSREL_FLAG_CYCLIC) == 0) { BLI_assert(from->num_links_pending > 0); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc b/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc index 1420b5fc8a5..3eed0697b5e 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc @@ -33,10 +33,8 @@ #include <cstdio> #include <cstdlib> -extern "C" { #include "BLI_utildefines.h" #include "BLI_stack.h" -} #include "util/deg_util_foreach.h" @@ -71,7 +69,7 @@ void deg_graph_detect_cycles(Depsgraph *graph) foreach (OperationDepsNode *node, graph->operations) { bool has_inlinks = false; foreach (DepsRelation *rel, node->inlinks) { - if (rel->from->type == DEPSNODE_TYPE_OPERATION) { + if (rel->from->type == DEG_NODE_TYPE_OPERATION) { has_inlinks = true; } } @@ -95,7 +93,7 @@ void deg_graph_detect_cycles(Depsgraph *graph) bool all_child_traversed = true; for (int i = node->done; i < node->outlinks.size(); ++i) { DepsRelation *rel = node->outlinks[i]; - if (rel->to->type == DEPSNODE_TYPE_OPERATION) { + if (rel->to->type == DEG_NODE_TYPE_OPERATION) { OperationDepsNode *to = (OperationDepsNode *)rel->to; if (to->tag == NODE_IN_STACK) { printf("Dependency cycle detected:\n"); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 49ebdc8b8ac..55f1f93be6a 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -37,11 +37,11 @@ #include "MEM_guardedalloc.h" -extern "C" { #include "BLI_blenlib.h" #include "BLI_string.h" #include "BLI_utildefines.h" +extern "C" { #include "DNA_action_types.h" #include "DNA_anim_types.h" #include "DNA_armature_types.h" @@ -94,13 +94,13 @@ extern "C" { #include "BKE_tracking.h" #include "BKE_world.h" -#include "DEG_depsgraph.h" -#include "DEG_depsgraph_build.h" - #include "RNA_access.h" #include "RNA_types.h" } /* extern "C" */ +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" + #include "intern/builder/deg_builder.h" #include "intern/nodes/deg_node.h" #include "intern/nodes/deg_node_component.h" @@ -160,55 +160,14 @@ DepsgraphNodeBuilder::~DepsgraphNodeBuilder() { } -RootDepsNode *DepsgraphNodeBuilder::add_root_node() -{ - return m_graph->add_root_node(); -} - IDDepsNode *DepsgraphNodeBuilder::add_id_node(ID *id) { return m_graph->add_id_node(id, id->name); } -TimeSourceDepsNode *DepsgraphNodeBuilder::add_time_source(ID *id) +TimeSourceDepsNode *DepsgraphNodeBuilder::add_time_source() { - /* determine which node to attach timesource to */ - if (id) { -#if 0 /* XXX TODO */ - /* get ID node */ - IDDepsNode id_node = m_graph->find_id_node(id); - - /* depends on what this is... */ - switch (GS(id->name)) { - case ID_SCE: /* Scene - Usually sequencer strip causing time remapping... */ - { - // TODO... - } - break; - - case ID_GR: /* Group */ - { - // TODO... - } - break; - - // XXX: time source... - - default: /* Unhandled */ - printf("%s(): Unhandled ID - %s \n", __func__, id->name); - break; - } -#endif - } - else { - /* root-node */ - RootDepsNode *root_node = m_graph->root_node; - if (root_node) { - return root_node->add_time_source("Time Source"); - } - } - - return NULL; + return m_graph->add_time_source(); } ComponentDepsNode *DepsgraphNodeBuilder::add_component_node( @@ -224,8 +183,7 @@ ComponentDepsNode *DepsgraphNodeBuilder::add_component_node( OperationDepsNode *DepsgraphNodeBuilder::add_operation_node( ComponentDepsNode *comp_node, - eDepsOperation_Type optype, - DepsEvalOperationCb op, + const DepsEvalOperationCb& op, eDepsOperation_Code opcode, const char *name, int name_tag) @@ -234,7 +192,7 @@ OperationDepsNode *DepsgraphNodeBuilder::add_operation_node( name, name_tag); if (op_node == NULL) { - op_node = comp_node->add_operation(optype, op, opcode, name, name_tag); + op_node = comp_node->add_operation(op, opcode, name, name_tag); m_graph->operations.push_back(op_node); } else { @@ -252,21 +210,19 @@ OperationDepsNode *DepsgraphNodeBuilder::add_operation_node( ID *id, eDepsNode_Type comp_type, const char *comp_name, - eDepsOperation_Type optype, - DepsEvalOperationCb op, + const DepsEvalOperationCb& op, eDepsOperation_Code opcode, const char *name, int name_tag) { ComponentDepsNode *comp_node = add_component_node(id, comp_type, comp_name); - return add_operation_node(comp_node, optype, op, opcode, name, name_tag); + return add_operation_node(comp_node, op, opcode, name, name_tag); } OperationDepsNode *DepsgraphNodeBuilder::add_operation_node( ID *id, eDepsNode_Type comp_type, - eDepsOperation_Type optype, - DepsEvalOperationCb op, + const DepsEvalOperationCb& op, eDepsOperation_Code opcode, const char *name, int name_tag) @@ -274,7 +230,6 @@ OperationDepsNode *DepsgraphNodeBuilder::add_operation_node( return add_operation_node(id, comp_type, "", - optype, op, opcode, name, @@ -352,41 +307,6 @@ void DepsgraphNodeBuilder::build_group(Scene *scene, } } -SubgraphDepsNode *DepsgraphNodeBuilder::build_subgraph(Group *group) -{ - /* sanity checks */ - if (!group) - return NULL; - - /* create new subgraph's data */ - Depsgraph *subgraph = reinterpret_cast<Depsgraph *>(DEG_graph_new()); - - DepsgraphNodeBuilder subgraph_builder(m_bmain, subgraph); - - /* add group objects */ - LINKLIST_FOREACH (GroupObject *, go, &group->gobject) { - /*Object *ob = go->ob;*/ - - /* Each "group object" is effectively a separate instance of the - * underlying object data. When the group is evaluated, the transform - * results and/or some other attributes end up getting overridden by - * the group. - */ - } - - /* Create a node for representing subgraph. */ - SubgraphDepsNode *subgraph_node = m_graph->add_subgraph_node(&group->id); - subgraph_node->graph = subgraph; - - /* Make a copy of the data this node will need? */ - /* XXX: do we do this now, or later? */ - /* TODO: need API function which queries graph's ID's hash, and duplicates - * those blocks thoroughly with all outside links removed. - */ - - return subgraph_node; -} - void DepsgraphNodeBuilder::build_object(Scene *scene, Base *base, Object *ob) { const bool has_object = (ob->id.tag & LIB_TAG_DOIT); @@ -512,15 +432,18 @@ void DepsgraphNodeBuilder::build_object(Scene *scene, Base *base, Object *ob) void DepsgraphNodeBuilder::build_object_transform(Scene *scene, Object *ob) { + OperationDepsNode *op_node; + /* local transforms (from transform channels - loc/rot/scale + deltas) */ - add_operation_node(&ob->id, DEPSNODE_TYPE_TRANSFORM, - DEPSOP_TYPE_INIT, function_bind(BKE_object_eval_local_transform, _1, scene, ob), - DEG_OPCODE_TRANSFORM_LOCAL); + op_node = add_operation_node(&ob->id, DEG_NODE_TYPE_TRANSFORM, + function_bind(BKE_object_eval_local_transform, _1, scene, ob), + DEG_OPCODE_TRANSFORM_LOCAL); + op_node->set_as_entry(); /* object parent */ if (ob->parent) { - add_operation_node(&ob->id, DEPSNODE_TYPE_TRANSFORM, - DEPSOP_TYPE_EXEC, function_bind(BKE_object_eval_parent, _1, scene, ob), + add_operation_node(&ob->id, DEG_NODE_TYPE_TRANSFORM, + function_bind(BKE_object_eval_parent, _1, scene, ob), DEG_OPCODE_TRANSFORM_PARENT); } @@ -536,14 +459,15 @@ void DepsgraphNodeBuilder::build_object_transform(Scene *scene, Object *ob) * * TODO(sergey): Get rid of this node. */ - add_operation_node(&ob->id, DEPSNODE_TYPE_TRANSFORM, - DEPSOP_TYPE_EXEC, function_bind(BKE_object_eval_uber_transform, _1, scene, ob), + add_operation_node(&ob->id, DEG_NODE_TYPE_TRANSFORM, + function_bind(BKE_object_eval_uber_transform, _1, scene, ob), DEG_OPCODE_OBJECT_UBEREVAL); /* object transform is done */ - add_operation_node(&ob->id, DEPSNODE_TYPE_TRANSFORM, - DEPSOP_TYPE_POST, function_bind(BKE_object_eval_done, _1, ob), - DEG_OPCODE_TRANSFORM_FINAL); + op_node = add_operation_node(&ob->id, DEG_NODE_TYPE_TRANSFORM, + function_bind(BKE_object_eval_done, _1, ob), + DEG_OPCODE_TRANSFORM_FINAL); + op_node->set_as_exit(); } /** @@ -566,8 +490,8 @@ void DepsgraphNodeBuilder::build_object_transform(Scene *scene, Object *ob) void DepsgraphNodeBuilder::build_object_constraints(Scene *scene, Object *ob) { /* create node for constraint stack */ - add_operation_node(&ob->id, DEPSNODE_TYPE_TRANSFORM, - DEPSOP_TYPE_EXEC, function_bind(BKE_object_eval_constraints, _1, scene, ob), + add_operation_node(&ob->id, DEG_NODE_TYPE_TRANSFORM, + function_bind(BKE_object_eval_constraints, _1, scene, ob), DEG_OPCODE_TRANSFORM_CONSTRAINTS); } @@ -589,8 +513,8 @@ void DepsgraphNodeBuilder::build_animdata(ID *id) /* actions and NLA - as a single unit for now, as it gets complicated to schedule otherwise */ if ((adt->action) || (adt->nla_tracks.first)) { /* create the node */ - add_operation_node(id, DEPSNODE_TYPE_ANIMATION, - DEPSOP_TYPE_EXEC, function_bind(BKE_animsys_eval_animdata, _1, id), + add_operation_node(id, DEG_NODE_TYPE_ANIMATION, + function_bind(BKE_animsys_eval_animdata, _1, id), DEG_OPCODE_ANIMATION, id->name); // TODO: for each channel affected, we might also want to add some support for running RNA update callbacks on them @@ -620,15 +544,14 @@ OperationDepsNode *DepsgraphNodeBuilder::build_driver(ID *id, FCurve *fcu) * and use some tagging magic instead. */ OperationDepsNode *driver_op = find_operation_node(id, - DEPSNODE_TYPE_PARAMETERS, + DEG_NODE_TYPE_PARAMETERS, DEG_OPCODE_DRIVER, fcu->rna_path ? fcu->rna_path : "", fcu->array_index); if (driver_op == NULL) { driver_op = add_operation_node(id, - DEPSNODE_TYPE_PARAMETERS, - DEPSOP_TYPE_EXEC, + DEG_NODE_TYPE_PARAMETERS, function_bind(BKE_animsys_eval_driver, _1, id, fcu), DEG_OPCODE_DRIVER, fcu->rna_path ? fcu->rna_path : "", @@ -655,9 +578,9 @@ void DepsgraphNodeBuilder::build_world(World *world) build_animdata(world_id); /* world itself */ - add_component_node(world_id, DEPSNODE_TYPE_PARAMETERS); + add_component_node(world_id, DEG_NODE_TYPE_PARAMETERS); - add_operation_node(world_id, DEPSNODE_TYPE_PARAMETERS, DEPSOP_TYPE_EXEC, NULL, + add_operation_node(world_id, DEG_NODE_TYPE_PARAMETERS, NULL, DEG_OPCODE_PLACEHOLDER, "Parameters Eval"); /* textures */ @@ -693,14 +616,14 @@ void DepsgraphNodeBuilder::build_rigidbody(Scene *scene) /* XXX: is this the right component, or do we want to use another one instead? */ /* init/rebuild operation */ - /*OperationDepsNode *init_node =*/ add_operation_node(&scene->id, DEPSNODE_TYPE_TRANSFORM, - DEPSOP_TYPE_REBUILD, function_bind(BKE_rigidbody_rebuild_sim, _1, scene), + /*OperationDepsNode *init_node =*/ add_operation_node(&scene->id, DEG_NODE_TYPE_TRANSFORM, + function_bind(BKE_rigidbody_rebuild_sim, _1, scene), DEG_OPCODE_RIGIDBODY_REBUILD); /* do-sim operation */ // XXX: what happens if we need to split into several groups? - OperationDepsNode *sim_node = add_operation_node(&scene->id, DEPSNODE_TYPE_TRANSFORM, - DEPSOP_TYPE_SIM, function_bind(BKE_rigidbody_eval_simulation, _1, scene), + OperationDepsNode *sim_node = add_operation_node(&scene->id, DEG_NODE_TYPE_TRANSFORM, + function_bind(BKE_rigidbody_eval_simulation, _1, scene), DEG_OPCODE_RIGIDBODY_SIM); /* XXX: For now, the sim node is the only one that really matters here. If any other @@ -720,8 +643,8 @@ void DepsgraphNodeBuilder::build_rigidbody(Scene *scene) /* 2) create operation for flushing results */ /* object's transform component - where the rigidbody operation lives */ - add_operation_node(&ob->id, DEPSNODE_TYPE_TRANSFORM, - DEPSOP_TYPE_EXEC, function_bind(BKE_rigidbody_object_sync_transforms, _1, scene, ob), + add_operation_node(&ob->id, DEG_NODE_TYPE_TRANSFORM, + function_bind(BKE_rigidbody_object_sync_transforms, _1, scene, ob), DEG_OPCODE_TRANSFORM_RIGIDBODY); } } @@ -746,7 +669,7 @@ void DepsgraphNodeBuilder::build_particles(Scene *scene, Object *ob) /* component for all particle systems */ ComponentDepsNode *psys_comp = - add_component_node(&ob->id, DEPSNODE_TYPE_EVAL_PARTICLES); + add_component_node(&ob->id, DEG_NODE_TYPE_EVAL_PARTICLES); /* particle systems */ LINKLIST_FOREACH (ParticleSystem *, psys, &ob->particlesystem) { @@ -759,7 +682,6 @@ void DepsgraphNodeBuilder::build_particles(Scene *scene, Object *ob) /* this particle system */ // TODO: for now, this will just be a placeholder "ubereval" node add_operation_node(psys_comp, - DEPSOP_TYPE_EXEC, function_bind(BKE_particle_system_eval, _1, scene, @@ -776,9 +698,8 @@ void DepsgraphNodeBuilder::build_particles(Scene *scene, Object *ob) void DepsgraphNodeBuilder::build_cloth(Scene *scene, Object *object) { ComponentDepsNode *cache_comp = add_component_node(&object->id, - DEPSNODE_TYPE_CACHE); + DEG_NODE_TYPE_CACHE); add_operation_node(cache_comp, - DEPSOP_TYPE_EXEC, function_bind(BKE_object_eval_cloth, _1, scene, @@ -792,7 +713,7 @@ void DepsgraphNodeBuilder::build_shapekeys(Key *key) { build_animdata(&key->id); - add_operation_node(&key->id, DEPSNODE_TYPE_GEOMETRY, DEPSOP_TYPE_EXEC, NULL, + add_operation_node(&key->id, DEG_NODE_TYPE_GEOMETRY, NULL, DEG_OPCODE_PLACEHOLDER, "Shapekey Eval"); } @@ -801,18 +722,19 @@ void DepsgraphNodeBuilder::build_shapekeys(Key *key) void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob) { ID *obdata = (ID *)ob->data; + OperationDepsNode *op_node; /* TODO(sergey): This way using this object's properties as driver target * works fine. * * Does this depend on other nodes? */ - add_operation_node(&ob->id, - DEPSNODE_TYPE_PARAMETERS, - DEPSOP_TYPE_POST, - NULL, - DEG_OPCODE_PLACEHOLDER, - "Parameters Eval"); + op_node = add_operation_node(&ob->id, + DEG_NODE_TYPE_PARAMETERS, + NULL, + DEG_OPCODE_PLACEHOLDER, + "Parameters Eval"); + op_node->set_as_exit(); /* Temporary uber-update node, which does everything. * It is for the being we're porting old dependencies into the new system. @@ -821,33 +743,23 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob) * * TODO(sergey): Get rid of this node. */ - add_operation_node(&ob->id, - DEPSNODE_TYPE_GEOMETRY, - DEPSOP_TYPE_POST, - function_bind(BKE_object_eval_uber_data, _1, scene, ob), - DEG_OPCODE_GEOMETRY_UBEREVAL); - - add_operation_node(&ob->id, - DEPSNODE_TYPE_GEOMETRY, - DEPSOP_TYPE_INIT, - NULL, - DEG_OPCODE_PLACEHOLDER, - "Eval Init"); + op_node = add_operation_node(&ob->id, + DEG_NODE_TYPE_GEOMETRY, + function_bind(BKE_object_eval_uber_data, _1, scene, ob), + DEG_OPCODE_GEOMETRY_UBEREVAL); + op_node->set_as_exit(); + + op_node = add_operation_node(&ob->id, + DEG_NODE_TYPE_GEOMETRY, + NULL, + DEG_OPCODE_PLACEHOLDER, + "Eval Init"); + op_node->set_as_entry(); // TODO: "Done" operation - /* Modifiers */ + /* Cloyth modifier. */ LINKLIST_FOREACH (ModifierData *, md, &ob->modifiers) { - add_operation_node(&ob->id, - DEPSNODE_TYPE_GEOMETRY, - DEPSOP_TYPE_EXEC, - function_bind(BKE_object_eval_modifier, - _1, - scene, - ob, - md), - DEG_OPCODE_GEOMETRY_MODIFIER, - md->name); if (md->type == eModifierType_Cloth) { build_cloth(scene, ob); } @@ -887,14 +799,14 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob) //Mesh *me = (Mesh *)ob->data; /* evaluation operations */ - add_operation_node(obdata, - DEPSNODE_TYPE_GEOMETRY, - DEPSOP_TYPE_INIT, - function_bind(BKE_mesh_eval_geometry, - _1, - (Mesh *)obdata), - DEG_OPCODE_PLACEHOLDER, - "Geometry Eval"); + op_node = add_operation_node(obdata, + DEG_NODE_TYPE_GEOMETRY, + function_bind(BKE_mesh_eval_geometry, + _1, + (Mesh *)obdata), + DEG_OPCODE_PLACEHOLDER, + "Geometry Eval"); + op_node->set_as_entry(); break; } @@ -906,14 +818,14 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob) if (mom == ob) { /* metaball evaluation operations */ /* NOTE: only the motherball gets evaluated! */ - add_operation_node(obdata, - DEPSNODE_TYPE_GEOMETRY, - DEPSOP_TYPE_INIT, - function_bind(BKE_mball_eval_geometry, - _1, - (MetaBall *)obdata), - DEG_OPCODE_PLACEHOLDER, - "Geometry Eval"); + op_node = add_operation_node(obdata, + DEG_NODE_TYPE_GEOMETRY, + function_bind(BKE_mball_eval_geometry, + _1, + (MetaBall *)obdata), + DEG_OPCODE_PLACEHOLDER, + "Geometry Eval"); + op_node->set_as_entry(); } break; } @@ -924,20 +836,19 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob) { /* Curve/nurms evaluation operations. */ /* - calculate curve geometry (including path) */ - add_operation_node(obdata, - DEPSNODE_TYPE_GEOMETRY, - DEPSOP_TYPE_INIT, - function_bind(BKE_curve_eval_geometry, - _1, - (Curve *)obdata), - DEG_OPCODE_PLACEHOLDER, - "Geometry Eval"); + op_node = add_operation_node(obdata, + DEG_NODE_TYPE_GEOMETRY, + function_bind(BKE_curve_eval_geometry, + _1, + (Curve *)obdata), + DEG_OPCODE_PLACEHOLDER, + "Geometry Eval"); + op_node->set_as_entry(); /* Calculate curve path - this is used by constraints, etc. */ if (ELEM(ob->type, OB_CURVE, OB_FONT)) { add_operation_node(obdata, - DEPSNODE_TYPE_GEOMETRY, - DEPSOP_TYPE_EXEC, + DEG_NODE_TYPE_GEOMETRY, function_bind(BKE_curve_eval_path, _1, (Curve *)obdata), @@ -964,24 +875,24 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob) case OB_LATTICE: { /* Lattice evaluation operations. */ - add_operation_node(obdata, - DEPSNODE_TYPE_GEOMETRY, - DEPSOP_TYPE_INIT, - function_bind(BKE_lattice_eval_geometry, - _1, - (Lattice *)obdata), - DEG_OPCODE_PLACEHOLDER, - "Geometry Eval"); + op_node = add_operation_node(obdata, + DEG_NODE_TYPE_GEOMETRY, + function_bind(BKE_lattice_eval_geometry, + _1, + (Lattice *)obdata), + DEG_OPCODE_PLACEHOLDER, + "Geometry Eval"); + op_node->set_as_entry(); break; } } - add_operation_node(obdata, DEPSNODE_TYPE_GEOMETRY, - DEPSOP_TYPE_POST, NULL, - DEG_OPCODE_PLACEHOLDER, "Eval Done"); + op_node = add_operation_node(obdata, DEG_NODE_TYPE_GEOMETRY, NULL, + DEG_OPCODE_PLACEHOLDER, "Eval Done"); + op_node->set_as_exit(); /* Parameters for driver sources. */ - add_operation_node(obdata, DEPSNODE_TYPE_PARAMETERS, DEPSOP_TYPE_EXEC, NULL, + add_operation_node(obdata, DEG_NODE_TYPE_PARAMETERS, NULL, DEG_OPCODE_PLACEHOLDER, "Parameters Eval"); } @@ -997,15 +908,13 @@ void DepsgraphNodeBuilder::build_camera(Object *ob) build_animdata(&cam->id); - add_operation_node(camera_id, DEPSNODE_TYPE_PARAMETERS, DEPSOP_TYPE_EXEC, NULL, + add_operation_node(camera_id, DEG_NODE_TYPE_PARAMETERS, NULL, DEG_OPCODE_PLACEHOLDER, "Parameters Eval"); if (cam->dof_ob != NULL) { /* TODO(sergey): For now parametrs are on object level. */ - add_operation_node(&ob->id, DEPSNODE_TYPE_PARAMETERS, - DEPSOP_TYPE_EXEC, NULL, - DEG_OPCODE_PLACEHOLDER, - "Camera DOF"); + add_operation_node(&ob->id, DEG_NODE_TYPE_PARAMETERS, NULL, + DEG_OPCODE_PLACEHOLDER, "Camera DOF"); } } @@ -1021,10 +930,10 @@ void DepsgraphNodeBuilder::build_lamp(Object *ob) build_animdata(&la->id); /* node for obdata */ - add_component_node(lamp_id, DEPSNODE_TYPE_PARAMETERS); + add_component_node(lamp_id, DEG_NODE_TYPE_PARAMETERS); /* TODO(sergey): Is it really how we're supposed to work with drivers? */ - add_operation_node(lamp_id, DEPSNODE_TYPE_PARAMETERS, DEPSOP_TYPE_EXEC, NULL, + add_operation_node(lamp_id, DEG_NODE_TYPE_PARAMETERS, NULL, DEG_OPCODE_PLACEHOLDER, "Parameters Eval"); /* lamp's nodetree */ @@ -1043,12 +952,14 @@ void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree) /* nodetree itself */ ID *ntree_id = &ntree->id; + OperationDepsNode *op_node; build_animdata(ntree_id); /* Parameters for drivers. */ - add_operation_node(ntree_id, DEPSNODE_TYPE_PARAMETERS, DEPSOP_TYPE_POST, NULL, - DEG_OPCODE_PLACEHOLDER, "Parameters Eval"); + op_node = add_operation_node(ntree_id, DEG_NODE_TYPE_PARAMETERS, NULL, + DEG_OPCODE_PLACEHOLDER, "Parameters Eval"); + op_node->set_as_exit(); /* nodetree's nodes... */ LINKLIST_FOREACH (bNode *, bnode, &ntree->nodes) { @@ -1087,8 +998,7 @@ void DepsgraphNodeBuilder::build_material(Material *ma) /* material itself */ add_id_node(ma_id); - add_operation_node(ma_id, DEPSNODE_TYPE_SHADING, - DEPSOP_TYPE_EXEC, NULL, + add_operation_node(ma_id, DEG_NODE_TYPE_SHADING, NULL, DEG_OPCODE_PLACEHOLDER, "Material Update"); /* material animation */ @@ -1144,8 +1054,7 @@ void DepsgraphNodeBuilder::build_image(Image *image) { add_id_node(image_id); /* Placeholder so we can add relations and tag ID node for update. */ add_operation_node(image_id, - DEPSNODE_TYPE_PARAMETERS, - DEPSOP_TYPE_EXEC, + DEG_NODE_TYPE_PARAMETERS, NULL, DEG_OPCODE_PLACEHOLDER, "Image Eval"); @@ -1156,10 +1065,10 @@ void DepsgraphNodeBuilder::build_compositor(Scene *scene) /* For now, just a plain wrapper? */ // TODO: create compositing component? // XXX: component type undefined! - //graph->get_node(&scene->id, NULL, DEPSNODE_TYPE_COMPOSITING, NULL); + //graph->get_node(&scene->id, NULL, DEG_NODE_TYPE_COMPOSITING, NULL); /* for now, nodetrees are just parameters; compositing occurs in internals of renderer... */ - add_component_node(&scene->id, DEPSNODE_TYPE_PARAMETERS); + add_component_node(&scene->id, DEG_NODE_TYPE_PARAMETERS); build_nodetree(scene->nodetree); } @@ -1181,9 +1090,8 @@ void DepsgraphNodeBuilder::build_cachefile(CacheFile *cache_file) { ID *cache_file_id = &cache_file->id; - add_component_node(cache_file_id, DEPSNODE_TYPE_CACHE); - add_operation_node(cache_file_id, DEPSNODE_TYPE_CACHE, - DEPSOP_TYPE_EXEC, NULL, + add_component_node(cache_file_id, DEG_NODE_TYPE_CACHE); + add_operation_node(cache_file_id, DEG_NODE_TYPE_CACHE, NULL, DEG_OPCODE_PLACEHOLDER, "Cache File Update"); add_id_node(cache_file_id); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index 745f8283328..a54b1c76c77 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -61,8 +61,6 @@ namespace DEG { struct Depsgraph; struct DepsNode; -struct RootDepsNode; -struct SubgraphDepsNode; struct IDDepsNode; struct TimeSourceDepsNode; struct ComponentDepsNode; @@ -74,32 +72,28 @@ struct DepsgraphNodeBuilder { void begin_build(Main *bmain); - RootDepsNode *add_root_node(); IDDepsNode *add_id_node(ID *id); - TimeSourceDepsNode *add_time_source(ID *id); + TimeSourceDepsNode *add_time_source(); ComponentDepsNode *add_component_node(ID *id, eDepsNode_Type comp_type, const char *comp_name = ""); OperationDepsNode *add_operation_node(ComponentDepsNode *comp_node, - eDepsOperation_Type optype, - DepsEvalOperationCb op, + const DepsEvalOperationCb& op, eDepsOperation_Code opcode, const char *name = "", int name_tag = -1); OperationDepsNode *add_operation_node(ID *id, eDepsNode_Type comp_type, const char *comp_name, - eDepsOperation_Type optype, - DepsEvalOperationCb op, + const DepsEvalOperationCb& op, eDepsOperation_Code opcode, const char *name = "", int name_tag = -1); OperationDepsNode *add_operation_node(ID *id, eDepsNode_Type comp_type, - eDepsOperation_Type optype, - DepsEvalOperationCb op, + const DepsEvalOperationCb& op, eDepsOperation_Code opcode, const char *name = "", int name_tag = -1); @@ -125,7 +119,6 @@ struct DepsgraphNodeBuilder { int name_tag = -1); void build_scene(Main *bmain, Scene *scene); - SubgraphDepsNode *build_subgraph(Group *group); void build_group(Scene *scene, Base *base, Group *group); void build_object(Scene *scene, Base *base, Object *ob); void build_object_transform(Scene *scene, Object *ob); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc index e307909cb11..fe7ccaa7fc0 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc @@ -37,11 +37,11 @@ #include "MEM_guardedalloc.h" -extern "C" { +#include "BLI_utildefines.h" #include "BLI_blenlib.h" #include "BLI_string.h" -#include "BLI_utildefines.h" +extern "C" { #include "DNA_anim_types.h" #include "DNA_armature_types.h" #include "DNA_constraint_types.h" @@ -49,10 +49,10 @@ extern "C" { #include "BKE_action.h" #include "BKE_armature.h" +} /* extern "C" */ #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" -} /* extern "C" */ #include "intern/builder/deg_builder.h" #include "intern/nodes/deg_node.h" @@ -67,8 +67,7 @@ namespace DEG { void DepsgraphNodeBuilder::build_pose_constraints(Scene *scene, Object *ob, bPoseChannel *pchan) { /* create node for constraint stack */ - add_operation_node(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, - DEPSOP_TYPE_EXEC, + add_operation_node(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, function_bind(BKE_pose_constraints_evaluate, _1, scene, ob, pchan), DEG_OPCODE_BONE_CONSTRAINTS); } @@ -81,15 +80,15 @@ void DepsgraphNodeBuilder::build_ik_pose(Scene *scene, Object *ob, bPoseChannel /* Find the chain's root. */ bPoseChannel *rootchan = BKE_armature_ik_solver_find_root(pchan, data); - if (has_operation_node(&ob->id, DEPSNODE_TYPE_EVAL_POSE, rootchan->name, + if (has_operation_node(&ob->id, DEG_NODE_TYPE_EVAL_POSE, rootchan->name, DEG_OPCODE_POSE_IK_SOLVER)) { return; } /* Operation node for evaluating/running IK Solver. */ - add_operation_node(&ob->id, DEPSNODE_TYPE_EVAL_POSE, rootchan->name, - DEPSOP_TYPE_SIM, function_bind(BKE_pose_iktree_evaluate, _1, scene, ob, rootchan), + add_operation_node(&ob->id, DEG_NODE_TYPE_EVAL_POSE, rootchan->name, + function_bind(BKE_pose_iktree_evaluate, _1, scene, ob, rootchan), DEG_OPCODE_POSE_IK_SOLVER); } @@ -104,8 +103,8 @@ void DepsgraphNodeBuilder::build_splineik_pose(Scene *scene, Object *ob, bPoseCh /* Operation node for evaluating/running Spline IK Solver. * Store the "root bone" of this chain in the solver, so it knows where to start. */ - add_operation_node(&ob->id, DEPSNODE_TYPE_EVAL_POSE, rootchan->name, - DEPSOP_TYPE_SIM, function_bind(BKE_pose_splineik_evaluate, _1, scene, ob, rootchan), + add_operation_node(&ob->id, DEG_NODE_TYPE_EVAL_POSE, rootchan->name, + function_bind(BKE_pose_splineik_evaluate, _1, scene, ob, rootchan), DEG_OPCODE_POSE_SPLINE_IK_SOLVER); } @@ -113,6 +112,7 @@ void DepsgraphNodeBuilder::build_splineik_pose(Scene *scene, Object *ob, bPoseCh void DepsgraphNodeBuilder::build_rig(Scene *scene, Object *ob) { bArmature *arm = (bArmature *)ob->data; + OperationDepsNode *op_node; /* animation and/or drivers linking posebones to base-armature used to define them * NOTE: AnimData here is really used to control animated deform properties, @@ -125,8 +125,7 @@ void DepsgraphNodeBuilder::build_rig(Scene *scene, Object *ob) /* Make sure pose is up-to-date with armature updates. */ add_operation_node(&arm->id, - DEPSNODE_TYPE_PARAMETERS, - DEPSOP_TYPE_EXEC, + DEG_NODE_TYPE_PARAMETERS, NULL, DEG_OPCODE_PLACEHOLDER, "Armature Eval"); @@ -175,30 +174,37 @@ void DepsgraphNodeBuilder::build_rig(Scene *scene, Object *ob) */ /* pose eval context */ - add_operation_node(&ob->id, DEPSNODE_TYPE_EVAL_POSE, - DEPSOP_TYPE_INIT, function_bind(BKE_pose_eval_init, _1, scene, ob, ob->pose), DEG_OPCODE_POSE_INIT); - - add_operation_node(&ob->id, DEPSNODE_TYPE_EVAL_POSE, - DEPSOP_TYPE_POST, function_bind(BKE_pose_eval_flush, _1, scene, ob, ob->pose), DEG_OPCODE_POSE_DONE); + op_node = add_operation_node(&ob->id, + DEG_NODE_TYPE_EVAL_POSE, + function_bind(BKE_pose_eval_init, _1, scene, ob, ob->pose), + DEG_OPCODE_POSE_INIT); + op_node->set_as_entry(); + + op_node = add_operation_node(&ob->id, + DEG_NODE_TYPE_EVAL_POSE, + function_bind(BKE_pose_eval_flush, _1, scene, ob, ob->pose), + DEG_OPCODE_POSE_DONE); + op_node->set_as_exit(); /* bones */ LINKLIST_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) { /* node for bone eval */ - add_operation_node(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, - DEPSOP_TYPE_INIT, NULL, // XXX: BKE_pose_eval_bone_local - DEG_OPCODE_BONE_LOCAL); + op_node = add_operation_node(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, NULL, + DEG_OPCODE_BONE_LOCAL); + op_node->set_as_entry(); - add_operation_node(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, - DEPSOP_TYPE_EXEC, function_bind(BKE_pose_eval_bone, _1, scene, ob, pchan), // XXX: BKE_pose_eval_bone_pose + add_operation_node(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, + function_bind(BKE_pose_eval_bone, _1, scene, ob, pchan), DEG_OPCODE_BONE_POSE_PARENT); - add_operation_node(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, - DEPSOP_TYPE_OUT, NULL, /* NOTE: dedicated noop for easier relationship construction */ + add_operation_node(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, + NULL, /* NOTE: dedicated noop for easier relationship construction */ DEG_OPCODE_BONE_READY); - add_operation_node(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, - DEPSOP_TYPE_POST, function_bind(BKE_pose_bone_done, _1, pchan), - DEG_OPCODE_BONE_DONE); + op_node = add_operation_node(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, + function_bind(BKE_pose_bone_done, _1, pchan), + DEG_OPCODE_BONE_DONE); + op_node->set_as_exit(); /* constraints */ if (pchan->constraints.first != NULL) { @@ -236,6 +242,8 @@ void DepsgraphNodeBuilder::build_rig(Scene *scene, Object *ob) void DepsgraphNodeBuilder::build_proxy_rig(Object *ob) { ID *obdata = (ID *)ob->data; + OperationDepsNode *op_node; + build_animdata(obdata); BLI_assert(ob->pose != NULL); @@ -246,31 +254,28 @@ void DepsgraphNodeBuilder::build_proxy_rig(Object *ob) BKE_pose_update_constraint_flags(ob->pose); } - add_operation_node(&ob->id, - DEPSNODE_TYPE_EVAL_POSE, - DEPSOP_TYPE_INIT, - function_bind(BKE_pose_eval_proxy_copy, _1, ob), - DEG_OPCODE_POSE_INIT); + op_node = add_operation_node(&ob->id, + DEG_NODE_TYPE_EVAL_POSE, + function_bind(BKE_pose_eval_proxy_copy, _1, ob), + DEG_OPCODE_POSE_INIT); + op_node->set_as_entry(); LINKLIST_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) { - add_operation_node(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, - DEPSOP_TYPE_INIT, NULL, - DEG_OPCODE_BONE_LOCAL); + op_node = add_operation_node(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, + NULL, DEG_OPCODE_BONE_LOCAL); + op_node->set_as_entry(); - add_operation_node(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, - DEPSOP_TYPE_EXEC, NULL, - DEG_OPCODE_BONE_READY); + add_operation_node(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, + NULL, DEG_OPCODE_BONE_READY); - add_operation_node(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, - DEPSOP_TYPE_POST, NULL, - DEG_OPCODE_BONE_DONE); + op_node = add_operation_node(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, + NULL, DEG_OPCODE_BONE_DONE); + op_node->set_as_exit(); } - add_operation_node(&ob->id, - DEPSNODE_TYPE_EVAL_POSE, - DEPSOP_TYPE_POST, - NULL, - DEG_OPCODE_POSE_DONE); + op_node = add_operation_node(&ob->id, DEG_NODE_TYPE_EVAL_POSE, + NULL, DEG_OPCODE_POSE_DONE); + op_node->set_as_exit(); } } // namespace DEG diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc index 7dd694cb570..3249867e416 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc @@ -37,21 +37,21 @@ #include "MEM_guardedalloc.h" -extern "C" { +#include "BLI_utildefines.h" #include "BLI_blenlib.h" #include "BLI_string.h" -#include "BLI_utildefines.h" +extern "C" { #include "DNA_node_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "BKE_main.h" #include "BKE_node.h" +} /* extern "C" */ #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" -} /* extern "C" */ #include "intern/builder/deg_builder.h" #include "intern/nodes/deg_node.h" @@ -69,7 +69,7 @@ void DepsgraphNodeBuilder::build_scene(Main *bmain, Scene *scene) add_id_node(&scene->id); /* timesource */ - add_time_source(NULL); + add_time_source(); /* build subgraph for set, and link this in... */ // XXX: depending on how this goes, that scene itself could probably store its diff --git a/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc b/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc index f870a33fb68..59eb7ed8cf1 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc @@ -33,10 +33,8 @@ #include <stdio.h> #include <string.h> -extern "C" { #include "BLI_utildefines.h" #include "BLI_ghash.h" -} namespace DEG { diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index df56ff5897c..62a7d6c6ab7 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -38,10 +38,10 @@ #include "MEM_guardedalloc.h" -extern "C" { -#include "BLI_blenlib.h" #include "BLI_utildefines.h" +#include "BLI_blenlib.h" +extern "C" { #include "DNA_action_types.h" #include "DNA_anim_types.h" #include "DNA_armature_types.h" @@ -92,13 +92,13 @@ extern "C" { #include "BKE_tracking.h" #include "BKE_world.h" -#include "DEG_depsgraph.h" -#include "DEG_depsgraph_build.h" - #include "RNA_access.h" #include "RNA_types.h" } /* extern "C" */ +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" + #include "intern/builder/deg_builder.h" #include "intern/builder/deg_builder_pchanmap.h" @@ -198,13 +198,6 @@ DepsgraphRelationBuilder::DepsgraphRelationBuilder(Depsgraph *graph) : { } -RootDepsNode *DepsgraphRelationBuilder::find_node(const RootKey &key) const -{ - (void)key; - BLI_assert(!"Doesn't seem to be correct"); - return m_graph->root_node; -} - TimeSourceDepsNode *DepsgraphRelationBuilder::find_node( const TimeSourceKey &key) const { @@ -213,7 +206,7 @@ TimeSourceDepsNode *DepsgraphRelationBuilder::find_node( return NULL; } else { - return m_graph->root_node->time_source; + return m_graph->time_source; } } @@ -282,7 +275,7 @@ void DepsgraphRelationBuilder::add_time_relation(TimeSourceDepsNode *timesrc, const char *description) { if (timesrc && node_to) { - m_graph->add_new_relation(timesrc, node_to, DEPSREL_TYPE_TIME, description); + m_graph->add_new_relation(timesrc, node_to, description); } else { DEG_DEBUG_PRINTF("add_time_relation(%p = %s, %p = %s, %s) Failed\n", @@ -295,17 +288,16 @@ void DepsgraphRelationBuilder::add_time_relation(TimeSourceDepsNode *timesrc, void DepsgraphRelationBuilder::add_operation_relation( OperationDepsNode *node_from, OperationDepsNode *node_to, - eDepsRelation_Type type, const char *description) { if (node_from && node_to) { - m_graph->add_new_relation(node_from, node_to, type, description); + m_graph->add_new_relation(node_from, node_to, description); } else { - DEG_DEBUG_PRINTF("add_operation_relation(%p = %s, %p = %s, %d, %s) Failed\n", + DEG_DEBUG_PRINTF("add_operation_relation(%p = %s, %p = %s, %s) Failed\n", node_from, (node_from) ? node_from->identifier().c_str() : "<None>", node_to, (node_to) ? node_to->identifier().c_str() : "<None>", - type, description); + description); } } @@ -318,11 +310,11 @@ void DepsgraphRelationBuilder::add_collision_relations(const OperationKey &key, { Object *ob1 = collobjs[i]; - ComponentKey trf_key(&ob1->id, DEPSNODE_TYPE_TRANSFORM); - add_relation(trf_key, key, DEPSREL_TYPE_STANDARD, name); + ComponentKey trf_key(&ob1->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(trf_key, key, name); - ComponentKey coll_key(&ob1->id, DEPSNODE_TYPE_GEOMETRY); - add_relation(coll_key, key, DEPSREL_TYPE_STANDARD, name); + ComponentKey coll_key(&ob1->id, DEG_NODE_TYPE_GEOMETRY); + add_relation(coll_key, key, name); } if (collobjs) @@ -336,31 +328,31 @@ void DepsgraphRelationBuilder::add_forcefield_relations(const OperationKey &key, if (effectors) { for (EffectorCache *eff = (EffectorCache *)effectors->first; eff; eff = eff->next) { if (eff->ob != ob) { - ComponentKey eff_key(&eff->ob->id, DEPSNODE_TYPE_TRANSFORM); - add_relation(eff_key, key, DEPSREL_TYPE_STANDARD, name); + ComponentKey eff_key(&eff->ob->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(eff_key, key, name); } if (eff->psys) { if (eff->ob != ob) { - ComponentKey eff_key(&eff->ob->id, DEPSNODE_TYPE_EVAL_PARTICLES); - add_relation(eff_key, key, DEPSREL_TYPE_STANDARD, name); + ComponentKey eff_key(&eff->ob->id, DEG_NODE_TYPE_EVAL_PARTICLES); + add_relation(eff_key, key, name); /* TODO: remove this when/if EVAL_PARTICLES is sufficient for up to date particles */ - ComponentKey mod_key(&eff->ob->id, DEPSNODE_TYPE_GEOMETRY); - add_relation(mod_key, key, DEPSREL_TYPE_STANDARD, name); + ComponentKey mod_key(&eff->ob->id, DEG_NODE_TYPE_GEOMETRY); + add_relation(mod_key, key, name); } else if (eff->psys != psys) { - OperationKey eff_key(&eff->ob->id, DEPSNODE_TYPE_EVAL_PARTICLES, DEG_OPCODE_PSYS_EVAL, eff->psys->name); - add_relation(eff_key, key, DEPSREL_TYPE_STANDARD, name); + OperationKey eff_key(&eff->ob->id, DEG_NODE_TYPE_EVAL_PARTICLES, DEG_OPCODE_PSYS_EVAL, eff->psys->name); + add_relation(eff_key, key, name); } } if (eff->pd->forcefield == PFIELD_SMOKEFLOW && eff->pd->f_source) { - ComponentKey trf_key(&eff->pd->f_source->id, DEPSNODE_TYPE_TRANSFORM); - add_relation(trf_key, key, DEPSREL_TYPE_STANDARD, "Smoke Force Domain"); + ComponentKey trf_key(&eff->pd->f_source->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(trf_key, key, "Smoke Force Domain"); - ComponentKey eff_key(&eff->pd->f_source->id, DEPSNODE_TYPE_GEOMETRY); - add_relation(eff_key, key, DEPSREL_TYPE_STANDARD, "Smoke Force Domain"); + ComponentKey eff_key(&eff->pd->f_source->id, DEG_NODE_TYPE_GEOMETRY); + add_relation(eff_key, key, "Smoke Force Domain"); } if (add_absorption && (eff->pd->flag & PFIELD_VISIBILITY)) { @@ -372,6 +364,11 @@ void DepsgraphRelationBuilder::add_forcefield_relations(const OperationKey &key, pdEndEffectors(&effectors); } +Depsgraph *DepsgraphRelationBuilder::getGraph() +{ + return m_graph; +} + /* **** Functions to build relations between entities **** */ void DepsgraphRelationBuilder::begin_build(Main *bmain) @@ -398,17 +395,14 @@ void DepsgraphRelationBuilder::build_group(Main *bmain, ID *group_id = &group->id; bool group_done = (group_id->tag & LIB_TAG_DOIT) != 0; OperationKey object_local_transform_key(&object->id, - DEPSNODE_TYPE_TRANSFORM, + DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_LOCAL); LINKLIST_FOREACH (GroupObject *, go, &group->gobject) { if (!group_done) { build_object(bmain, scene, go->ob); } - ComponentKey dupli_transform_key(&go->ob->id, DEPSNODE_TYPE_TRANSFORM); - add_relation(dupli_transform_key, - object_local_transform_key, - DEPSREL_TYPE_TRANSFORM, - "Dupligroup"); + ComponentKey dupli_transform_key(&go->ob->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(dupli_transform_key, object_local_transform_key, "Dupligroup"); } group_id->tag |= LIB_TAG_DOIT; } @@ -422,13 +416,13 @@ void DepsgraphRelationBuilder::build_object(Main *bmain, Scene *scene, Object *o /* Object Transforms */ eDepsOperation_Code base_op = (ob->parent) ? DEG_OPCODE_TRANSFORM_PARENT : DEG_OPCODE_TRANSFORM_LOCAL; - OperationKey base_op_key(&ob->id, DEPSNODE_TYPE_TRANSFORM, base_op); + OperationKey base_op_key(&ob->id, DEG_NODE_TYPE_TRANSFORM, base_op); - OperationKey local_transform_key(&ob->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_LOCAL); - OperationKey parent_transform_key(&ob->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_PARENT); - OperationKey final_transform_key(&ob->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_FINAL); + OperationKey local_transform_key(&ob->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_LOCAL); + OperationKey parent_transform_key(&ob->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_PARENT); + OperationKey final_transform_key(&ob->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_FINAL); - OperationKey ob_ubereval_key(&ob->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_OBJECT_UBEREVAL); + OperationKey ob_ubereval_key(&ob->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_OBJECT_UBEREVAL); /* parenting */ if (ob->parent != NULL) { @@ -436,10 +430,7 @@ void DepsgraphRelationBuilder::build_object(Main *bmain, Scene *scene, Object *o build_object_parent(ob); /* local -> parent */ - add_relation(local_transform_key, - parent_transform_key, - DEPSREL_TYPE_COMPONENT_ORDER, - "[ObLocal -> ObParent]"); + add_relation(local_transform_key, parent_transform_key, "[ObLocal -> ObParent]"); } if (ob->modifiers.first != NULL) { @@ -460,7 +451,7 @@ void DepsgraphRelationBuilder::build_object(Main *bmain, Scene *scene, Object *o /* object constraints */ if (ob->constraints.first != NULL) { OperationKey constraint_key(&ob->id, - DEPSNODE_TYPE_TRANSFORM, + DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_CONSTRAINTS); /* constraint relations */ @@ -468,30 +459,18 @@ void DepsgraphRelationBuilder::build_object(Main *bmain, Scene *scene, Object *o // XXX: this is broken build_constraints(scene, &ob->id, - DEPSNODE_TYPE_TRANSFORM, + DEG_NODE_TYPE_TRANSFORM, "", &ob->constraints, NULL); /* operation order */ - add_relation(base_op_key, - constraint_key, - DEPSREL_TYPE_COMPONENT_ORDER, - "[ObBase-> Constraint Stack]"); - add_relation(constraint_key, - final_transform_key, - DEPSREL_TYPE_COMPONENT_ORDER, - "[ObConstraints -> Done]"); + add_relation(base_op_key, constraint_key, "[ObBase-> Constraint Stack]"); + add_relation(constraint_key, final_transform_key, "[ObConstraints -> Done]"); // XXX - add_relation(constraint_key, - ob_ubereval_key, - DEPSREL_TYPE_COMPONENT_ORDER, - "Temp Ubereval"); - add_relation(ob_ubereval_key, - final_transform_key, - DEPSREL_TYPE_COMPONENT_ORDER, - "Temp Ubereval"); + add_relation(constraint_key, ob_ubereval_key, "Temp Ubereval"); + add_relation(ob_ubereval_key, final_transform_key, "Temp Ubereval"); } else { /* NOTE: Keep an eye here, we skip some relations here to "streamline" @@ -502,31 +481,20 @@ void DepsgraphRelationBuilder::build_object(Main *bmain, Scene *scene, Object *o /* Rigid body will hook up another node inbetween, so skip * relation here to avoid transitive relation. */ - add_relation(base_op_key, - ob_ubereval_key, - DEPSREL_TYPE_COMPONENT_ORDER, - "Temp Ubereval"); + add_relation(base_op_key, ob_ubereval_key, "Temp Ubereval"); } - add_relation(ob_ubereval_key, - final_transform_key, - DEPSREL_TYPE_COMPONENT_ORDER, - "Temp Ubereval"); + add_relation(ob_ubereval_key, final_transform_key, "Temp Ubereval"); } - /* AnimData */ build_animdata(&ob->id); // XXX: This should be hooked up by the build_animdata code if (needs_animdata_node(&ob->id)) { - ComponentKey adt_key(&ob->id, DEPSNODE_TYPE_ANIMATION); - add_relation(adt_key, - local_transform_key, - DEPSREL_TYPE_OPERATION, - "Object Animation"); + ComponentKey adt_key(&ob->id, DEG_NODE_TYPE_ANIMATION); + add_relation(adt_key, local_transform_key, "Object Animation"); } - /* object data */ if (ob->data) { ID *obdata_id = (ID *)ob->data; @@ -567,12 +535,9 @@ void DepsgraphRelationBuilder::build_object(Main *bmain, Scene *scene, Object *o Key *key = BKE_key_from_object(ob); if (key != NULL) { - ComponentKey geometry_key((ID *)ob->data, DEPSNODE_TYPE_GEOMETRY); - ComponentKey key_key(&key->id, DEPSNODE_TYPE_GEOMETRY); - add_relation(key_key, - geometry_key, - DEPSREL_TYPE_GEOMETRY_EVAL, - "Shapekeys"); + ComponentKey geometry_key((ID *)ob->data, DEG_NODE_TYPE_GEOMETRY); + ComponentKey key_key(&key->id, DEG_NODE_TYPE_GEOMETRY); + add_relation(key_key, geometry_key, "Shapekeys"); } } @@ -593,9 +558,9 @@ void DepsgraphRelationBuilder::build_object(Main *bmain, Scene *scene, Object *o /* TODO(sergey): This is an inverted relation, matches old depsgraph * behavior and need to be investigated if it still need to be inverted. */ - ComponentKey ob_pose_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE); - ComponentKey proxy_pose_key(&ob->proxy->id, DEPSNODE_TYPE_EVAL_POSE); - add_relation(ob_pose_key, proxy_pose_key, DEPSREL_TYPE_TRANSFORM, "Proxy"); + ComponentKey ob_pose_key(&ob->id, DEG_NODE_TYPE_EVAL_POSE); + ComponentKey proxy_pose_key(&ob->proxy->id, DEG_NODE_TYPE_EVAL_POSE); + add_relation(ob_pose_key, proxy_pose_key, "Proxy"); } /* Object dupligroup. */ @@ -611,23 +576,23 @@ void DepsgraphRelationBuilder::build_object_parent(Object *ob) */ // XXX: @sergey - it would be good if we got that backwards flushing working // when tagging for updates. - //OperationKey ob_key(&ob->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_PARENT); - ComponentKey ob_key(&ob->id, DEPSNODE_TYPE_TRANSFORM); + //OperationKey ob_key(&ob->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_PARENT); + ComponentKey ob_key(&ob->id, DEG_NODE_TYPE_TRANSFORM); /* type-specific links */ switch (ob->partype) { case PARSKEL: /* Armature Deform (Virtual Modifier) */ { - ComponentKey parent_key(&ob->parent->id, DEPSNODE_TYPE_TRANSFORM); - add_relation(parent_key, ob_key, DEPSREL_TYPE_STANDARD, "Armature Deform Parent"); + ComponentKey parent_key(&ob->parent->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(parent_key, ob_key, "Armature Deform Parent"); break; } case PARVERT1: /* Vertex Parent */ case PARVERT3: { - ComponentKey parent_key(&ob->parent->id, DEPSNODE_TYPE_GEOMETRY); - add_relation(parent_key, ob_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Vertex Parent"); + ComponentKey parent_key(&ob->parent->id, DEG_NODE_TYPE_GEOMETRY); + add_relation(parent_key, ob_key, "Vertex Parent"); /* XXX not sure what this is for or how you could be done properly - lukas */ OperationDepsNode *parent_node = find_operation_node(parent_key); @@ -635,27 +600,21 @@ void DepsgraphRelationBuilder::build_object_parent(Object *ob) parent_node->customdata_mask |= CD_MASK_ORIGINDEX; } - ComponentKey transform_key(&ob->parent->id, DEPSNODE_TYPE_TRANSFORM); - add_relation(transform_key, ob_key, DEPSREL_TYPE_TRANSFORM, "Vertex Parent TFM"); + ComponentKey transform_key(&ob->parent->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(transform_key, ob_key, "Vertex Parent TFM"); break; } case PARBONE: /* Bone Parent */ { ComponentKey parent_bone_key(&ob->parent->id, - DEPSNODE_TYPE_BONE, + DEG_NODE_TYPE_BONE, ob->parsubstr); OperationKey parent_transform_key(&ob->parent->id, - DEPSNODE_TYPE_TRANSFORM, + DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_FINAL); - add_relation(parent_bone_key, - ob_key, - DEPSREL_TYPE_TRANSFORM, - "Bone Parent"); - add_relation(parent_transform_key, - ob_key, - DEPSREL_TYPE_TRANSFORM, - "Armature Parent"); + add_relation(parent_bone_key, ob_key, "Bone Parent"); + add_relation(parent_transform_key, ob_key, "Armature Parent"); break; } @@ -664,33 +623,33 @@ void DepsgraphRelationBuilder::build_object_parent(Object *ob) if (ob->parent->type == OB_LATTICE) { /* Lattice Deform Parent - Virtual Modifier */ // XXX: no virtual modifiers should be left! - ComponentKey parent_key(&ob->parent->id, DEPSNODE_TYPE_TRANSFORM); - ComponentKey geom_key(&ob->parent->id, DEPSNODE_TYPE_GEOMETRY); + ComponentKey parent_key(&ob->parent->id, DEG_NODE_TYPE_TRANSFORM); + ComponentKey geom_key(&ob->parent->id, DEG_NODE_TYPE_GEOMETRY); - add_relation(parent_key, ob_key, DEPSREL_TYPE_STANDARD, "Lattice Deform Parent"); - add_relation(geom_key, ob_key, DEPSREL_TYPE_STANDARD, "Lattice Deform Parent Geom"); + add_relation(parent_key, ob_key, "Lattice Deform Parent"); + add_relation(geom_key, ob_key, "Lattice Deform Parent Geom"); } else if (ob->parent->type == OB_CURVE) { Curve *cu = (Curve *)ob->parent->data; if (cu->flag & CU_PATH) { /* Follow Path */ - ComponentKey parent_key(&ob->parent->id, DEPSNODE_TYPE_GEOMETRY); - add_relation(parent_key, ob_key, DEPSREL_TYPE_TRANSFORM, "Curve Follow Parent"); + ComponentKey parent_key(&ob->parent->id, DEG_NODE_TYPE_GEOMETRY); + add_relation(parent_key, ob_key, "Curve Follow Parent"); - ComponentKey transform_key(&ob->parent->id, DEPSNODE_TYPE_TRANSFORM); - add_relation(transform_key, ob_key, DEPSREL_TYPE_TRANSFORM, "Curve Follow TFM"); + ComponentKey transform_key(&ob->parent->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(transform_key, ob_key, "Curve Follow TFM"); } else { /* Standard Parent */ - ComponentKey parent_key(&ob->parent->id, DEPSNODE_TYPE_TRANSFORM); - add_relation(parent_key, ob_key, DEPSREL_TYPE_TRANSFORM, "Curve Parent"); + ComponentKey parent_key(&ob->parent->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(parent_key, ob_key, "Curve Parent"); } } else { /* Standard Parent */ - ComponentKey parent_key(&ob->parent->id, DEPSNODE_TYPE_TRANSFORM); - add_relation(parent_key, ob_key, DEPSREL_TYPE_TRANSFORM, "Parent"); + ComponentKey parent_key(&ob->parent->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(parent_key, ob_key, "Parent"); } break; } @@ -706,7 +665,7 @@ void DepsgraphRelationBuilder::build_constraints(Scene *scene, ID *id, eDepsNode ListBase *constraints, RootPChanMap *root_map) { OperationKey constraint_op_key(id, component_type, component_subdata, - (component_type == DEPSNODE_TYPE_BONE) ? DEG_OPCODE_BONE_CONSTRAINTS : DEG_OPCODE_TRANSFORM_CONSTRAINTS); + (component_type == DEG_NODE_TYPE_BONE) ? DEG_OPCODE_BONE_CONSTRAINTS : DEG_OPCODE_TRANSFORM_CONSTRAINTS); /* add dependencies for each constraint in turn */ for (bConstraint *con = (bConstraint *)constraints->first; con; con = con->next) { @@ -729,8 +688,8 @@ void DepsgraphRelationBuilder::build_constraints(Scene *scene, ID *id, eDepsNode if (data->depth_ob) { // DAG_RL_DATA_OB | DAG_RL_OB_OB - ComponentKey depth_key(&data->depth_ob->id, DEPSNODE_TYPE_TRANSFORM); - add_relation(depth_key, constraint_op_key, DEPSREL_TYPE_TRANSFORM, cti->name); + ComponentKey depth_key(&data->depth_ob->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(depth_key, constraint_op_key, cti->name); } } else if (cti->type == CONSTRAINT_TYPE_OBJECTSOLVER) { @@ -739,24 +698,24 @@ void DepsgraphRelationBuilder::build_constraints(Scene *scene, ID *id, eDepsNode if (depends_on_camera && scene->camera) { // DAG_RL_DATA_OB | DAG_RL_OB_OB - ComponentKey camera_key(&scene->camera->id, DEPSNODE_TYPE_TRANSFORM); - add_relation(camera_key, constraint_op_key, DEPSREL_TYPE_TRANSFORM, cti->name); + ComponentKey camera_key(&scene->camera->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(camera_key, constraint_op_key, cti->name); } /* TODO(sergey): This is more a TimeSource -> MovieClip -> Constraint dependency chain. */ TimeSourceKey time_src_key; - add_relation(time_src_key, constraint_op_key, DEPSREL_TYPE_TIME, "[TimeSrc -> Animation]"); + add_relation(time_src_key, constraint_op_key, "[TimeSrc -> Animation]"); } else if (cti->type == CONSTRAINT_TYPE_TRANSFORM_CACHE) { /* TODO(kevin): This is more a TimeSource -> CacheFile -> Constraint dependency chain. */ TimeSourceKey time_src_key; - add_relation(time_src_key, constraint_op_key, DEPSREL_TYPE_TIME, "[TimeSrc -> Animation]"); + add_relation(time_src_key, constraint_op_key, "[TimeSrc -> Animation]"); bTransformCacheConstraint *data = (bTransformCacheConstraint *)con->data; if (data->cache_file) { - ComponentKey cache_key(&data->cache_file->id, DEPSNODE_TYPE_CACHE); - add_relation(cache_key, constraint_op_key, DEPSREL_TYPE_CACHE, cti->name); + ComponentKey cache_key(&data->cache_file->id, DEG_NODE_TYPE_CACHE); + add_relation(cache_key, constraint_op_key, cti->name); } } else if (cti->get_constraint_targets) { @@ -773,8 +732,8 @@ void DepsgraphRelationBuilder::build_constraints(Scene *scene, ID *id, eDepsNode } else if (ELEM(con->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO)) { /* these constraints require path geometry data... */ - ComponentKey target_key(&ct->tar->id, DEPSNODE_TYPE_GEOMETRY); - add_relation(target_key, constraint_op_key, DEPSREL_TYPE_GEOMETRY_EVAL, cti->name); // XXX: type = geom_transform + ComponentKey target_key(&ct->tar->id, DEG_NODE_TYPE_GEOMETRY); + add_relation(target_key, constraint_op_key, cti->name); // XXX: type = geom_transform // TODO: path dependency } else if ((ct->tar->type == OB_ARMATURE) && (ct->subtarget[0])) { @@ -793,20 +752,20 @@ void DepsgraphRelationBuilder::build_constraints(Scene *scene, ID *id, eDepsNode target_key_opcode = DEG_OPCODE_BONE_DONE; } - OperationKey target_key(&ct->tar->id, DEPSNODE_TYPE_BONE, ct->subtarget, target_key_opcode); - add_relation(target_key, constraint_op_key, DEPSREL_TYPE_TRANSFORM, cti->name); + OperationKey target_key(&ct->tar->id, DEG_NODE_TYPE_BONE, ct->subtarget, target_key_opcode); + add_relation(target_key, constraint_op_key, cti->name); } else { /* different armature - we can safely use the result of that */ - OperationKey target_key(&ct->tar->id, DEPSNODE_TYPE_BONE, ct->subtarget, DEG_OPCODE_BONE_DONE); - add_relation(target_key, constraint_op_key, DEPSREL_TYPE_TRANSFORM, cti->name); + OperationKey target_key(&ct->tar->id, DEG_NODE_TYPE_BONE, ct->subtarget, DEG_OPCODE_BONE_DONE); + add_relation(target_key, constraint_op_key, cti->name); } } else if (ELEM(ct->tar->type, OB_MESH, OB_LATTICE) && (ct->subtarget[0])) { /* vertex group */ /* NOTE: for now, we don't need to represent vertex groups separately... */ - ComponentKey target_key(&ct->tar->id, DEPSNODE_TYPE_GEOMETRY); - add_relation(target_key, constraint_op_key, DEPSREL_TYPE_GEOMETRY_EVAL, cti->name); + ComponentKey target_key(&ct->tar->id, DEG_NODE_TYPE_GEOMETRY); + add_relation(target_key, constraint_op_key, cti->name); if (ct->tar->type == OB_MESH) { OperationDepsNode *node2 = find_operation_node(target_key); @@ -817,12 +776,12 @@ void DepsgraphRelationBuilder::build_constraints(Scene *scene, ID *id, eDepsNode } else if (con->type == CONSTRAINT_TYPE_SHRINKWRAP) { /* Constraints which requires the target object surface. */ - ComponentKey target_key(&ct->tar->id, DEPSNODE_TYPE_GEOMETRY); - add_relation(target_key, constraint_op_key, DEPSREL_TYPE_TRANSFORM, cti->name); + ComponentKey target_key(&ct->tar->id, DEG_NODE_TYPE_GEOMETRY); + add_relation(target_key, constraint_op_key, cti->name); /* NOTE: obdata eval now doesn't necessarily depend on the object's transform... */ - ComponentKey target_transform_key(&ct->tar->id, DEPSNODE_TYPE_TRANSFORM); - add_relation(target_transform_key, constraint_op_key, DEPSREL_TYPE_TRANSFORM, cti->name); + ComponentKey target_transform_key(&ct->tar->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(target_transform_key, constraint_op_key, cti->name); } else { /* standard object relation */ @@ -834,19 +793,19 @@ void DepsgraphRelationBuilder::build_constraints(Scene *scene, ID *id, eDepsNode * - If however it is a real self targetting case, just make it depend on the * previous constraint (or the pre-constraint state)... */ - if ((ct->tar->type == OB_ARMATURE) && (component_type == DEPSNODE_TYPE_BONE)) { - OperationKey target_key(&ct->tar->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_FINAL); - add_relation(target_key, constraint_op_key, DEPSREL_TYPE_TRANSFORM, cti->name); + if ((ct->tar->type == OB_ARMATURE) && (component_type == DEG_NODE_TYPE_BONE)) { + OperationKey target_key(&ct->tar->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_FINAL); + add_relation(target_key, constraint_op_key, cti->name); } else { - OperationKey target_key(&ct->tar->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_LOCAL); - add_relation(target_key, constraint_op_key, DEPSREL_TYPE_TRANSFORM, cti->name); + OperationKey target_key(&ct->tar->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_LOCAL); + add_relation(target_key, constraint_op_key, cti->name); } } else { /* normal object dependency */ - OperationKey target_key(&ct->tar->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_FINAL); - add_relation(target_key, constraint_op_key, DEPSREL_TYPE_TRANSFORM, cti->name); + OperationKey target_key(&ct->tar->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_FINAL); + add_relation(target_key, constraint_op_key, cti->name); } } @@ -860,8 +819,8 @@ void DepsgraphRelationBuilder::build_constraints(Scene *scene, ID *id, eDepsNode CONSTRAINT_TYPE_TRANSLIKE)) { /* TODO(sergey): Add used space check. */ - ComponentKey target_transform_key(&ct->tar->id, DEPSNODE_TYPE_TRANSFORM); - add_relation(target_transform_key, constraint_op_key, DEPSREL_TYPE_TRANSFORM, cti->name); + ComponentKey target_transform_key(&ct->tar->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(target_transform_key, constraint_op_key, cti->name); } } @@ -879,13 +838,13 @@ void DepsgraphRelationBuilder::build_animdata(ID *id) if (adt == NULL) return; - ComponentKey adt_key(id, DEPSNODE_TYPE_ANIMATION); + ComponentKey adt_key(id, DEG_NODE_TYPE_ANIMATION); /* animation */ if (adt->action || adt->nla_tracks.first) { /* wire up dependency to time source */ TimeSourceKey time_src_key; - add_relation(time_src_key, adt_key, DEPSREL_TYPE_TIME, "[TimeSrc -> Animation]"); + add_relation(time_src_key, adt_key, "[TimeSrc -> Animation]"); // XXX: Hook up specific update callbacks for special properties which may need it... @@ -895,7 +854,7 @@ void DepsgraphRelationBuilder::build_animdata(ID *id) /* drivers */ LINKLIST_FOREACH (FCurve *, fcu, &adt->drivers) { OperationKey driver_key(id, - DEPSNODE_TYPE_PARAMETERS, + DEG_NODE_TYPE_PARAMETERS, DEG_OPCODE_DRIVER, fcu->rna_path ? fcu->rna_path : "", fcu->array_index); @@ -936,26 +895,22 @@ void DepsgraphRelationBuilder::build_animdata(ID *id) } if (fcu_prev != NULL) { OperationKey prev_driver_key(id, - DEPSNODE_TYPE_PARAMETERS, + DEG_NODE_TYPE_PARAMETERS, DEG_OPCODE_DRIVER, fcu_prev->rna_path ? fcu_prev->rna_path : "", fcu_prev->array_index); OperationKey driver_key(id, - DEPSNODE_TYPE_PARAMETERS, + DEG_NODE_TYPE_PARAMETERS, DEG_OPCODE_DRIVER, fcu->rna_path ? fcu->rna_path : "", fcu->array_index); - add_relation(prev_driver_key, - driver_key, - DEPSREL_TYPE_OPERATION, - "[Driver Order]"); + add_relation(prev_driver_key, driver_key, "[Driver Order]"); } } /* prevent driver from occurring before own animation... */ if (adt->action || adt->nla_tracks.first) { - add_relation(adt_key, driver_key, DEPSREL_TYPE_OPERATION, - "[AnimData Before Drivers]"); + add_relation(adt_key, driver_key, "[AnimData Before Drivers]"); } } } @@ -964,7 +919,7 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) { ChannelDriver *driver = fcu->driver; OperationKey driver_key(id, - DEPSNODE_TYPE_PARAMETERS, + DEG_NODE_TYPE_PARAMETERS, DEG_OPCODE_DRIVER, fcu->rna_path ? fcu->rna_path : "", fcu->array_index); @@ -975,7 +930,7 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) /* create dependency between driver and data affected by it */ /* - direct property relationship... */ //RNAPathKey affected_key(id, fcu->rna_path); - //add_relation(driver_key, affected_key, DEPSREL_TYPE_DRIVER, "[Driver -> Data] DepsRel"); + //add_relation(driver_key, affected_key, "[Driver -> Data] DepsRel"); /* driver -> data components (for interleaved evaluation - bones/constraints/modifiers) */ // XXX: this probably should probably be moved out into a separate function @@ -994,8 +949,8 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) } if (pchan) { - OperationKey bone_key(id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL); - add_relation(driver_key, bone_key, DEPSREL_TYPE_DRIVER, "[Driver -> Bone]"); + OperationKey bone_key(id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL); + add_relation(driver_key, bone_key, "[Driver -> Bone]"); } else { fprintf(stderr, @@ -1021,8 +976,8 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bone_name); // NOTE: ob->pose may be NULL if (pchan) { - OperationKey bone_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL); - add_relation(driver_key, bone_key, DEPSREL_TYPE_DRIVER, "[Arm Bone -> Driver -> Bone]"); + OperationKey bone_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL); + add_relation(driver_key, bone_key, "[Arm Bone -> Driver -> Bone]"); } } } @@ -1038,21 +993,12 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) } } else if (GS(id->name) == ID_OB && strstr(rna_path, "modifiers[")) { - /* modifier driver - connect directly to the modifier */ - char *modifier_name = BLI_str_quoted_substrN(rna_path, "modifiers["); - if (modifier_name) { - OperationKey modifier_key(id, - DEPSNODE_TYPE_GEOMETRY, - DEG_OPCODE_GEOMETRY_MODIFIER, - modifier_name); - if (has_node(modifier_key)) { - add_relation(driver_key, modifier_key, DEPSREL_TYPE_DRIVER, "[Driver -> Modifier]"); - } - else { - printf("Unexisting driver RNA path: %s\n", rna_path); - } - - MEM_freeN(modifier_name); + OperationKey modifier_key(id, DEG_NODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_UBEREVAL); + if (has_node(modifier_key)) { + add_relation(driver_key, modifier_key, "[Driver -> Modifier]"); + } + else { + printf("Unexisting driver RNA path: %s\n", rna_path); } } else if (GS(id->name) == ID_KE && strstr(rna_path, "key_blocks[")) { @@ -1060,22 +1006,22 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) // XXX: double check where this points Key *shape_key = (Key *)id; - ComponentKey geometry_key(shape_key->from, DEPSNODE_TYPE_GEOMETRY); - add_relation(driver_key, geometry_key, DEPSREL_TYPE_DRIVER, "[Driver -> ShapeKey Geom]"); + ComponentKey geometry_key(shape_key->from, DEG_NODE_TYPE_GEOMETRY); + add_relation(driver_key, geometry_key, "[Driver -> ShapeKey Geom]"); } else if (strstr(rna_path, "key_blocks[")) { - ComponentKey geometry_key(id, DEPSNODE_TYPE_GEOMETRY); - add_relation(driver_key, geometry_key, DEPSREL_TYPE_DRIVER, "[Driver -> ShapeKey Geom]"); + ComponentKey geometry_key(id, DEG_NODE_TYPE_GEOMETRY); + add_relation(driver_key, geometry_key, "[Driver -> ShapeKey Geom]"); } else { if (GS(id->name) == ID_OB) { /* assume that driver affects a transform... */ - OperationKey local_transform_key(id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_LOCAL); - add_relation(driver_key, local_transform_key, DEPSREL_TYPE_OPERATION, "[Driver -> Transform]"); + OperationKey local_transform_key(id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_LOCAL); + add_relation(driver_key, local_transform_key, "[Driver -> Transform]"); } else if (GS(id->name) == ID_KE) { - ComponentKey geometry_key(id, DEPSNODE_TYPE_GEOMETRY); - add_relation(driver_key, geometry_key, DEPSREL_TYPE_GEOMETRY_EVAL, "[Driver -> Shapekey Geometry]"); + ComponentKey geometry_key(id, DEG_NODE_TYPE_GEOMETRY); + add_relation(driver_key, geometry_key, "[Driver -> Shapekey Geometry]"); } } @@ -1108,14 +1054,14 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) { continue; } - OperationKey target_key(dtar->id, DEPSNODE_TYPE_BONE, target_pchan->name, DEG_OPCODE_BONE_DONE); - add_relation(target_key, driver_key, DEPSREL_TYPE_DRIVER_TARGET, "[Bone Target -> Driver]"); + OperationKey target_key(dtar->id, DEG_NODE_TYPE_BONE, target_pchan->name, DEG_OPCODE_BONE_DONE); + add_relation(target_key, driver_key, "[Bone Target -> Driver]"); } } else if (dtar->flag & DTAR_FLAG_STRUCT_REF) { /* get node associated with the object's transforms */ - OperationKey target_key(dtar->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_FINAL); - add_relation(target_key, driver_key, DEPSREL_TYPE_DRIVER_TARGET, "[Target -> Driver]"); + OperationKey target_key(dtar->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_FINAL); + add_relation(target_key, driver_key, "[Target -> Driver]"); } else if (dtar->rna_path && strstr(dtar->rna_path, "pose.bones[")) { /* workaround for ensuring that local bone transforms don't end up @@ -1135,8 +1081,8 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) { continue; } - OperationKey bone_key(dtar->id, DEPSNODE_TYPE_BONE, target_pchan->name, DEG_OPCODE_BONE_LOCAL); - add_relation(bone_key, driver_key, DEPSREL_TYPE_DRIVER, "[RNA Bone -> Driver]"); + OperationKey bone_key(dtar->id, DEG_NODE_TYPE_BONE, target_pchan->name, DEG_OPCODE_BONE_LOCAL); + add_relation(bone_key, driver_key, "[RNA Bone -> Driver]"); } } else { @@ -1148,7 +1094,7 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) } /* resolve path to get node */ RNAPathKey target_key(dtar->id, dtar->rna_path ? dtar->rna_path : ""); - add_relation(target_key, driver_key, DEPSREL_TYPE_DRIVER_TARGET, "[RNA Target -> Driver]"); + add_relation(target_key, driver_key, "[RNA Target -> Driver]"); } } DRIVER_TARGETS_LOOPER_END @@ -1162,7 +1108,7 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) python_driver_depends_on_time(driver)) { TimeSourceKey time_src_key; - add_relation(time_src_key, driver_key, DEPSREL_TYPE_TIME, "[TimeSrc -> Driver]"); + add_relation(time_src_key, driver_key, "[TimeSrc -> Driver]"); } } @@ -1184,10 +1130,9 @@ void DepsgraphRelationBuilder::build_world(World *world) /* world's nodetree */ if (world->nodetree != NULL) { build_nodetree(world->nodetree); - ComponentKey ntree_key(&world->nodetree->id, DEPSNODE_TYPE_PARAMETERS); - ComponentKey world_key(world_id, DEPSNODE_TYPE_PARAMETERS); - add_relation(ntree_key, world_key, - DEPSREL_TYPE_COMPONENT_ORDER, "NTree->World Parameters"); + ComponentKey ntree_key(&world->nodetree->id, DEG_NODE_TYPE_PARAMETERS); + ComponentKey world_key(world_id, DEG_NODE_TYPE_PARAMETERS); + add_relation(ntree_key, world_key, "NTree->World Parameters"); } } @@ -1195,20 +1140,17 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) { RigidBodyWorld *rbw = scene->rigidbody_world; - OperationKey init_key(&scene->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_RIGIDBODY_REBUILD); - OperationKey sim_key(&scene->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_RIGIDBODY_SIM); + OperationKey init_key(&scene->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_RIGIDBODY_REBUILD); + OperationKey sim_key(&scene->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_RIGIDBODY_SIM); /* rel between the two sim-nodes */ - add_relation(init_key, sim_key, DEPSREL_TYPE_OPERATION, "Rigidbody [Init -> SimStep]"); + add_relation(init_key, sim_key, "Rigidbody [Init -> SimStep]"); /* set up dependencies between these operations and other builtin nodes --------------- */ /* time dependency */ TimeSourceKey time_src_key; - add_relation(time_src_key, - init_key, - DEPSREL_TYPE_TIME, - "TimeSrc -> Rigidbody Reset/Rebuild (Optional)"); + add_relation(time_src_key, init_key, "TimeSrc -> Rigidbody Reset/Rebuild (Optional)"); /* objects - simulation participants */ if (rbw->group) { @@ -1226,12 +1168,12 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) * XXX: there's probably a difference between passive and active * - passive don't change, so may need to know full transform... */ - OperationKey rbo_key(&ob->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_RIGIDBODY); + OperationKey rbo_key(&ob->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_RIGIDBODY); eDepsOperation_Code trans_opcode = ob->parent ? DEG_OPCODE_TRANSFORM_PARENT : DEG_OPCODE_TRANSFORM_LOCAL; - OperationKey trans_op(&ob->id, DEPSNODE_TYPE_TRANSFORM, trans_opcode); + OperationKey trans_op(&ob->id, DEG_NODE_TYPE_TRANSFORM, trans_opcode); - add_relation(sim_key, rbo_key, DEPSREL_TYPE_COMPONENT_ORDER, "Rigidbody Sim Eval -> RBO Sync"); + add_relation(sim_key, rbo_key, "Rigidbody Sim Eval -> RBO Sync"); /* if constraints exist, those depend on the result of the rigidbody sim * - This allows constraints to modify the result of the sim (i.e. clamping) @@ -1243,12 +1185,9 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) */ if (ob->constraints.first) { OperationKey constraint_key(&ob->id, - DEPSNODE_TYPE_TRANSFORM, + DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_CONSTRAINTS); - add_relation(rbo_key, - constraint_key, - DEPSREL_TYPE_COMPONENT_ORDER, - "RBO Sync -> Ob Constraints"); + add_relation(rbo_key, constraint_key, "RBO Sync -> Ob Constraints"); } else { /* Final object transform depends on rigidbody. @@ -1257,19 +1196,13 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) * If it is gone we'll need to reconsider relation here. */ OperationKey uber_key(&ob->id, - DEPSNODE_TYPE_TRANSFORM, + DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_OBJECT_UBEREVAL); - add_relation(rbo_key, - uber_key, - DEPSREL_TYPE_COMPONENT_ORDER, - "RBO Sync -> Uber (Temp)"); + add_relation(rbo_key, uber_key, "RBO Sync -> Uber (Temp)"); } /* Needed to get correct base values. */ - add_relation(trans_op, - sim_key, - DEPSREL_TYPE_OPERATION, - "Base Ob Transform -> Rigidbody Sim Eval"); + add_relation(trans_op, sim_key, "Base Ob Transform -> Rigidbody Sim Eval"); } } @@ -1286,16 +1219,16 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) /* final result of the constraint object's transform controls how the * constraint affects the physics sim for these objects */ - ComponentKey trans_key(&ob->id, DEPSNODE_TYPE_TRANSFORM); - OperationKey ob1_key(&rbc->ob1->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_RIGIDBODY); - OperationKey ob2_key(&rbc->ob2->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_RIGIDBODY); + ComponentKey trans_key(&ob->id, DEG_NODE_TYPE_TRANSFORM); + OperationKey ob1_key(&rbc->ob1->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_RIGIDBODY); + OperationKey ob2_key(&rbc->ob2->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_RIGIDBODY); /* - constrained-objects sync depends on the constraint-holder */ - add_relation(trans_key, ob1_key, DEPSREL_TYPE_TRANSFORM, "RigidBodyConstraint -> RBC.Object_1"); - add_relation(trans_key, ob2_key, DEPSREL_TYPE_TRANSFORM, "RigidBodyConstraint -> RBC.Object_2"); + add_relation(trans_key, ob1_key, "RigidBodyConstraint -> RBC.Object_1"); + add_relation(trans_key, ob2_key, "RigidBodyConstraint -> RBC.Object_2"); /* - ensure that sim depends on this constraint's transform */ - add_relation(trans_key, sim_key, DEPSREL_TYPE_TRANSFORM, "RigidBodyConstraint Transform -> RB Simulation"); + add_relation(trans_key, sim_key, "RigidBodyConstraint Transform -> RB Simulation"); } } } @@ -1304,7 +1237,7 @@ void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob) { TimeSourceKey time_src_key; OperationKey obdata_ubereval_key(&ob->id, - DEPSNODE_TYPE_GEOMETRY, + DEG_NODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_UBEREVAL); /* particle systems */ @@ -1315,7 +1248,7 @@ void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob) build_animdata(&part->id); /* this particle system */ - OperationKey psys_key(&ob->id, DEPSNODE_TYPE_EVAL_PARTICLES, DEG_OPCODE_PSYS_EVAL, psys->name); + OperationKey psys_key(&ob->id, DEG_NODE_TYPE_EVAL_PARTICLES, DEG_OPCODE_PSYS_EVAL, psys->name); /* XXX: if particle system is later re-enabled, we must do full rebuild? */ if (!psys_check_enabled(ob, psys, G.is_rendering)) @@ -1324,46 +1257,13 @@ void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob) /* TODO(sergey): Are all particle systems depends on time? * Hair without dynamics i.e. */ - add_relation(time_src_key, psys_key, - DEPSREL_TYPE_TIME, - "TimeSrc -> PSys"); + add_relation(time_src_key, psys_key, "TimeSrc -> PSys"); /* TODO(sergey): Currently particle update is just a placeholder, * hook it to the ubereval node so particle system is getting updated * on playback. */ - add_relation(psys_key, - obdata_ubereval_key, - DEPSREL_TYPE_OPERATION, - "PSys -> UberEval"); - -#if 0 - if (ELEM(part->phystype, PART_PHYS_KEYED, PART_PHYS_BOIDS)) { - LINKLIST_FOREACH (ParticleTarget *, pt, &psys->targets) { - if (pt->ob && BLI_findlink(&pt->ob->particlesystem, pt->psys - 1)) { - node2 = dag_get_node(dag, pt->ob); - dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Particle Targets"); - } - } - } - - if (part->ren_as == PART_DRAW_OB && part->dup_ob) { - node2 = dag_get_node(dag, part->dup_ob); - /* note that this relation actually runs in the wrong direction, the problem - * is that dupli system all have this (due to parenting), and the render - * engine instancing assumes particular ordering of objects in list */ - dag_add_relation(dag, node, node2, DAG_RL_OB_OB, "Particle Object Visualization"); - if (part->dup_ob->type == OB_MBALL) - dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA, "Particle Object Visualization"); - } - - if (part->ren_as == PART_DRAW_GR && part->dup_group) { - LINKLIST_FOREACH (GroupObject *, go, &part->dup_group->gobject) { - node2 = dag_get_node(dag, go->ob); - dag_add_relation(dag, node2, node, DAG_RL_OB_OB, "Particle Group Visualization"); - } - } -#endif + add_relation(psys_key, obdata_ubereval_key, "PSys -> UberEval"); /* collisions */ if (part->type != PART_HAIR) { @@ -1387,19 +1287,16 @@ void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob) ruleob = ((BoidRuleFollowLeader *)rule)->ob; if (ruleob) { - ComponentKey ruleob_key(&ruleob->id, DEPSNODE_TYPE_TRANSFORM); - add_relation(ruleob_key, psys_key, DEPSREL_TYPE_TRANSFORM, "Boid Rule"); + ComponentKey ruleob_key(&ruleob->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(ruleob_key, psys_key, "Boid Rule"); } } } } if (part->ren_as == PART_DRAW_OB && part->dup_ob) { - ComponentKey dup_ob_key(&part->dup_ob->id, DEPSNODE_TYPE_TRANSFORM); - add_relation(dup_ob_key, - psys_key, - DEPSREL_TYPE_TRANSFORM, - "Particle Object Visualization"); + ComponentKey dup_ob_key(&part->dup_ob->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(dup_ob_key, psys_key, "Particle Object Visualization"); } } @@ -1409,11 +1306,8 @@ void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob) * TODO(sergey): This relation should be altered once real granular update * is implemented. */ - ComponentKey transform_key(&ob->id, DEPSNODE_TYPE_TRANSFORM); - add_relation(transform_key, - obdata_ubereval_key, - DEPSREL_TYPE_GEOMETRY_EVAL, - "Partcile Eval"); + ComponentKey transform_key(&ob->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(transform_key, obdata_ubereval_key, "Partcile Eval"); /* pointcache */ // TODO... @@ -1421,27 +1315,23 @@ void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob) void DepsgraphRelationBuilder::build_cloth(Scene * /*scene*/, Object *object, - ModifierData *md) + ModifierData * /*md*/) { OperationKey cache_key(&object->id, - DEPSNODE_TYPE_CACHE, + DEG_NODE_TYPE_CACHE, DEG_OPCODE_PLACEHOLDER, "Cloth Modifier"); /* Cache component affects on modifier. */ OperationKey modifier_key(&object->id, - DEPSNODE_TYPE_GEOMETRY, - DEG_OPCODE_GEOMETRY_MODIFIER, - md->name); - add_relation(cache_key, - modifier_key, - DEPSREL_TYPE_TIME, - "Cloth Cache -> Cloth"); + DEG_NODE_TYPE_GEOMETRY, + DEG_OPCODE_GEOMETRY_UBEREVAL); + add_relation(cache_key, modifier_key, "Cloth Cache -> Cloth"); } /* Shapekeys */ void DepsgraphRelationBuilder::build_shapekeys(ID *obdata, Key *key) { - ComponentKey obdata_key(obdata, DEPSNODE_TYPE_GEOMETRY); + ComponentKey obdata_key(obdata, DEG_NODE_TYPE_GEOMETRY); /* attach animdata to geometry */ build_animdata(&key->id); @@ -1449,8 +1339,8 @@ void DepsgraphRelationBuilder::build_shapekeys(ID *obdata, Key *key) if (key->adt) { // TODO: this should really be handled in build_animdata, since many of these cases will need it if (key->adt->action || key->adt->nla_tracks.first) { - ComponentKey adt_key(&key->id, DEPSNODE_TYPE_ANIMATION); - add_relation(adt_key, obdata_key, DEPSREL_TYPE_OPERATION, "Animation"); + ComponentKey adt_key(&key->id, DEG_NODE_TYPE_ANIMATION); + add_relation(adt_key, obdata_key, "Animation"); } /* NOTE: individual shapekey drivers are handled above already */ @@ -1458,8 +1348,8 @@ void DepsgraphRelationBuilder::build_shapekeys(ID *obdata, Key *key) /* attach to geometry */ // XXX: aren't shapekeys now done as a pseudo-modifier on object? - //ComponentKey key_key(&key->id, DEPSNODE_TYPE_GEOMETRY); // FIXME: this doesn't exist - //add_relation(key_key, obdata_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Shapekeys"); + //ComponentKey key_key(&key->id, DEG_NODE_TYPE_GEOMETRY); // FIXME: this doesn't exist + //add_relation(key_key, obdata_key, "Shapekeys"); } /** @@ -1487,34 +1377,26 @@ void DepsgraphRelationBuilder::build_obdata_geom(Main *bmain, Scene *scene, Obje ID *obdata = (ID *)ob->data; /* Init operation of object-level geometry evaluation. */ - OperationKey geom_init_key(&ob->id, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_PLACEHOLDER, "Eval Init"); + OperationKey geom_init_key(&ob->id, DEG_NODE_TYPE_GEOMETRY, DEG_OPCODE_PLACEHOLDER, "Eval Init"); /* get nodes for result of obdata's evaluation, and geometry evaluation on object */ - ComponentKey obdata_geom_key(obdata, DEPSNODE_TYPE_GEOMETRY); - ComponentKey geom_key(&ob->id, DEPSNODE_TYPE_GEOMETRY); + ComponentKey obdata_geom_key(obdata, DEG_NODE_TYPE_GEOMETRY); + ComponentKey geom_key(&ob->id, DEG_NODE_TYPE_GEOMETRY); /* link components to each other */ - add_relation(obdata_geom_key, geom_key, DEPSREL_TYPE_DATABLOCK, "Object Geometry Base Data"); + add_relation(obdata_geom_key, geom_key, "Object Geometry Base Data"); /* Modifiers */ - if (ob->modifiers.first) { - OperationKey prev_mod_key; + if (ob->modifiers.first != NULL) { + OperationKey obdata_ubereval_key(&ob->id, + DEG_NODE_TYPE_GEOMETRY, + DEG_OPCODE_GEOMETRY_UBEREVAL); LINKLIST_FOREACH (ModifierData *, md, &ob->modifiers) { const ModifierTypeInfo *mti = modifierType_getInfo((ModifierType)md->type); - OperationKey mod_key(&ob->id, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_MODIFIER, md->name); - - if (md->prev) { - /* Stack relation: modifier depends on previous modifier in the stack */ - add_relation(prev_mod_key, mod_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Modifier Stack"); - } - else { - /* Stack relation: first modifier depends on the geometry. */ - add_relation(geom_init_key, mod_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Modifier Stack"); - } if (mti->updateDepsgraph) { - DepsNodeHandle handle = create_node_handle(mod_key); + DepsNodeHandle handle = create_node_handle(obdata_ubereval_key); mti->updateDepsgraph( md, bmain, @@ -1525,7 +1407,7 @@ void DepsgraphRelationBuilder::build_obdata_geom(Main *bmain, Scene *scene, Obje if (BKE_object_modifier_use_time(ob, md)) { TimeSourceKey time_src_key; - add_relation(time_src_key, mod_key, DEPSREL_TYPE_TIME, "Time Source"); + add_relation(time_src_key, obdata_ubereval_key, "Time Source"); /* Hacky fix for T45633 (Animated modifiers aren't updated) * @@ -1534,16 +1416,14 @@ void DepsgraphRelationBuilder::build_obdata_geom(Main *bmain, Scene *scene, Obje */ /* XXX: Remove this hack when these links are added as part of build_animdata() instead */ if (modifier_dependsOnTime(md) == false && needs_animdata_node(&ob->id)) { - ComponentKey animation_key(&ob->id, DEPSNODE_TYPE_ANIMATION); - add_relation(animation_key, mod_key, DEPSREL_TYPE_OPERATION, "Modifier Animation"); + ComponentKey animation_key(&ob->id, DEG_NODE_TYPE_ANIMATION); + add_relation(animation_key, obdata_ubereval_key, "Modifier Animation"); } } if (md->type == eModifierType_Cloth) { build_cloth(scene, ob, md); } - - prev_mod_key = mod_key; } } @@ -1568,15 +1448,8 @@ void DepsgraphRelationBuilder::build_obdata_geom(Main *bmain, Scene *scene, Obje */ if (ob->type != OB_ARMATURE) { /* Armatures does no longer require uber node. */ - OperationKey obdata_ubereval_key(&ob->id, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_UBEREVAL); - if (ob->modifiers.last) { - ModifierData *md = (ModifierData *)ob->modifiers.last; - OperationKey mod_key(&ob->id, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_MODIFIER, md->name); - add_relation(mod_key, obdata_ubereval_key, DEPSREL_TYPE_OPERATION, "Object Geometry UberEval"); - } - else { - add_relation(geom_init_key, obdata_ubereval_key, DEPSREL_TYPE_OPERATION, "Object Geometry UberEval"); - } + OperationKey obdata_ubereval_key(&ob->id, DEG_NODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_UBEREVAL); + add_relation(geom_init_key, obdata_ubereval_key, "Object Geometry UberEval"); } if (obdata->tag & LIB_TAG_DOIT) { @@ -1585,13 +1458,26 @@ void DepsgraphRelationBuilder::build_obdata_geom(Main *bmain, Scene *scene, Obje obdata->tag |= LIB_TAG_DOIT; /* Link object data evaluation node to exit operation. */ - OperationKey obdata_geom_eval_key(obdata, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_PLACEHOLDER, "Geometry Eval"); - OperationKey obdata_geom_done_key(obdata, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_PLACEHOLDER, "Eval Done"); - add_relation(obdata_geom_eval_key, obdata_geom_done_key, DEPSREL_TYPE_DATABLOCK, "ObData Geom Eval Done"); + OperationKey obdata_geom_eval_key(obdata, DEG_NODE_TYPE_GEOMETRY, DEG_OPCODE_PLACEHOLDER, "Geometry Eval"); + OperationKey obdata_geom_done_key(obdata, DEG_NODE_TYPE_GEOMETRY, DEG_OPCODE_PLACEHOLDER, "Eval Done"); + add_relation(obdata_geom_eval_key, obdata_geom_done_key, "ObData Geom Eval Done"); /* type-specific node/links */ switch (ob->type) { case OB_MESH: + /* NOTE: This is compatibility code to support particle systems + * + * for viewport being properly rendered in final render mode. + * This relation is similar to what dag_object_time_update_flags() + * was doing for mesh objects with particle system/ + * + * Ideally we need to get rid of this relation. + */ + if (ob->particlesystem.first != NULL) { + TimeSourceKey time_key; + OperationKey obdata_ubereval_key(&ob->id, DEG_NODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_UBEREVAL); + add_relation(time_key, obdata_ubereval_key, "Legacy particle time"); + } break; case OB_MBALL: @@ -1601,10 +1487,10 @@ void DepsgraphRelationBuilder::build_obdata_geom(Main *bmain, Scene *scene, Obje /* motherball - mom depends on children! */ if (mom != ob) { /* non-motherball -> cannot be directly evaluated! */ - ComponentKey mom_key(&mom->id, DEPSNODE_TYPE_GEOMETRY); - ComponentKey transform_key(&ob->id, DEPSNODE_TYPE_TRANSFORM); - add_relation(geom_key, mom_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Metaball Motherball"); - add_relation(transform_key, mom_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Metaball Motherball"); + ComponentKey mom_key(&mom->id, DEG_NODE_TYPE_GEOMETRY); + ComponentKey transform_key(&ob->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(geom_key, mom_key, "Metaball Motherball"); + add_relation(transform_key, mom_key, "Metaball Motherball"); } break; } @@ -1617,20 +1503,20 @@ void DepsgraphRelationBuilder::build_obdata_geom(Main *bmain, Scene *scene, Obje /* curve's dependencies */ // XXX: these needs geom data, but where is geom stored? if (cu->bevobj) { - ComponentKey bevob_key(&cu->bevobj->id, DEPSNODE_TYPE_GEOMETRY); + ComponentKey bevob_key(&cu->bevobj->id, DEG_NODE_TYPE_GEOMETRY); build_object(bmain, scene, cu->bevobj); - add_relation(bevob_key, geom_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Curve Bevel"); + add_relation(bevob_key, geom_key, "Curve Bevel"); } if (cu->taperobj) { - ComponentKey taperob_key(&cu->taperobj->id, DEPSNODE_TYPE_GEOMETRY); + ComponentKey taperob_key(&cu->taperobj->id, DEG_NODE_TYPE_GEOMETRY); build_object(bmain, scene, cu->taperobj); - add_relation(taperob_key, geom_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Curve Taper"); + add_relation(taperob_key, geom_key, "Curve Taper"); } if (ob->type == OB_FONT) { if (cu->textoncurve) { - ComponentKey textoncurve_key(&cu->textoncurve->id, DEPSNODE_TYPE_GEOMETRY); + ComponentKey textoncurve_key(&cu->textoncurve->id, DEG_NODE_TYPE_GEOMETRY); build_object(bmain, scene, cu->textoncurve); - add_relation(textoncurve_key, geom_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Text on Curve"); + add_relation(textoncurve_key, geom_key, "Text on Curve"); } } break; @@ -1654,14 +1540,13 @@ void DepsgraphRelationBuilder::build_obdata_geom(Main *bmain, Scene *scene, Obje } if (needs_animdata_node(obdata)) { - ComponentKey animation_key(obdata, DEPSNODE_TYPE_ANIMATION); - ComponentKey parameters_key(obdata, DEPSNODE_TYPE_PARAMETERS); - add_relation(animation_key, parameters_key, - DEPSREL_TYPE_COMPONENT_ORDER, "Geom Parameters"); + ComponentKey animation_key(obdata, DEG_NODE_TYPE_ANIMATION); + ComponentKey parameters_key(obdata, DEG_NODE_TYPE_PARAMETERS); + add_relation(animation_key, parameters_key, "Geom Parameters"); /* Evaluation usually depends on animation. * TODO(sergey): Need to re-hook it after granular update is implemented.. */ - add_relation(animation_key, obdata_geom_eval_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Animation"); + add_relation(animation_key, obdata_geom_eval_key, "Animation"); } } @@ -1676,19 +1561,18 @@ void DepsgraphRelationBuilder::build_camera(Object *ob) } camera_id->tag |= LIB_TAG_DOIT; - ComponentKey parameters_key(camera_id, DEPSNODE_TYPE_PARAMETERS); + ComponentKey parameters_key(camera_id, DEG_NODE_TYPE_PARAMETERS); if (needs_animdata_node(camera_id)) { - ComponentKey animation_key(camera_id, DEPSNODE_TYPE_ANIMATION); - add_relation(animation_key, parameters_key, - DEPSREL_TYPE_COMPONENT_ORDER, "Camera Parameters"); + ComponentKey animation_key(camera_id, DEG_NODE_TYPE_ANIMATION); + add_relation(animation_key, parameters_key, "Camera Parameters"); } /* DOF */ if (cam->dof_ob) { - ComponentKey ob_param_key(&ob->id, DEPSNODE_TYPE_PARAMETERS); - ComponentKey dof_ob_key(&cam->dof_ob->id, DEPSNODE_TYPE_TRANSFORM); - add_relation(dof_ob_key, ob_param_key, DEPSREL_TYPE_TRANSFORM, "Camera DOF"); + ComponentKey ob_param_key(&ob->id, DEG_NODE_TYPE_PARAMETERS); + ComponentKey dof_ob_key(&cam->dof_ob->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(dof_ob_key, ob_param_key, "Camera DOF"); } } @@ -1702,20 +1586,18 @@ void DepsgraphRelationBuilder::build_lamp(Object *ob) } lamp_id->tag |= LIB_TAG_DOIT; - ComponentKey parameters_key(lamp_id, DEPSNODE_TYPE_PARAMETERS); + ComponentKey parameters_key(lamp_id, DEG_NODE_TYPE_PARAMETERS); if (needs_animdata_node(lamp_id)) { - ComponentKey animation_key(lamp_id, DEPSNODE_TYPE_ANIMATION); - add_relation(animation_key, parameters_key, - DEPSREL_TYPE_COMPONENT_ORDER, "Lamp Parameters"); + ComponentKey animation_key(lamp_id, DEG_NODE_TYPE_ANIMATION); + add_relation(animation_key, parameters_key, "Lamp Parameters"); } /* lamp's nodetree */ if (la->nodetree) { build_nodetree(la->nodetree); - ComponentKey nodetree_key(&la->nodetree->id, DEPSNODE_TYPE_PARAMETERS); - add_relation(nodetree_key, parameters_key, - DEPSREL_TYPE_COMPONENT_ORDER, "NTree->Lamp Parameters"); + ComponentKey nodetree_key(&la->nodetree->id, DEG_NODE_TYPE_PARAMETERS); + add_relation(nodetree_key, parameters_key, "NTree->Lamp Parameters"); } /* textures */ @@ -1732,7 +1614,7 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree) build_animdata(ntree_id); OperationKey parameters_key(ntree_id, - DEPSNODE_TYPE_PARAMETERS, + DEG_NODE_TYPE_PARAMETERS, DEG_OPCODE_PLACEHOLDER, "Parameters Eval"); @@ -1752,19 +1634,17 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree) group_ntree->id.tag |= LIB_TAG_DOIT; } OperationKey group_parameters_key(&group_ntree->id, - DEPSNODE_TYPE_PARAMETERS, + DEG_NODE_TYPE_PARAMETERS, DEG_OPCODE_PLACEHOLDER, "Parameters Eval"); - add_relation(group_parameters_key, parameters_key, - DEPSREL_TYPE_COMPONENT_ORDER, "Group Node"); + add_relation(group_parameters_key, parameters_key, "Group Node"); } } } if (needs_animdata_node(ntree_id)) { - ComponentKey animation_key(ntree_id, DEPSNODE_TYPE_ANIMATION); - add_relation(animation_key, parameters_key, - DEPSREL_TYPE_COMPONENT_ORDER, "NTree Parameters"); + ComponentKey animation_key(ntree_id, DEG_NODE_TYPE_ANIMATION); + add_relation(animation_key, parameters_key, "NTree Parameters"); } } @@ -1787,15 +1667,14 @@ void DepsgraphRelationBuilder::build_material(Material *ma) if (ma->nodetree != NULL) { build_nodetree(ma->nodetree); OperationKey ntree_key(&ma->nodetree->id, - DEPSNODE_TYPE_PARAMETERS, + DEG_NODE_TYPE_PARAMETERS, DEG_OPCODE_PLACEHOLDER, "Parameters Eval"); OperationKey material_key(&ma->id, - DEPSNODE_TYPE_SHADING, + DEG_NODE_TYPE_SHADING, DEG_OPCODE_PLACEHOLDER, "Material Update"); - add_relation(ntree_key, material_key, - DEPSREL_TYPE_UPDATE, "Material's NTree"); + add_relation(ntree_key, material_key, "Material's NTree"); } } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index 4ca95bebe3f..02f8fc69070 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -78,17 +78,12 @@ struct Depsgraph; struct DepsNode; struct DepsNodeHandle; struct RootDepsNode; -struct SubgraphDepsNode; struct IDDepsNode; struct TimeSourceDepsNode; struct ComponentDepsNode; struct OperationDepsNode; struct RootPChanMap; -struct RootKey { - RootKey(); -}; - struct TimeSourceKey { TimeSourceKey(); @@ -177,19 +172,16 @@ struct DepsgraphRelationBuilder template <typename KeyFrom, typename KeyTo> void add_relation(const KeyFrom& key_from, const KeyTo& key_to, - eDepsRelation_Type type, const char *description); template <typename KeyTo> void add_relation(const TimeSourceKey& key_from, const KeyTo& key_to, - eDepsRelation_Type type, const char *description); template <typename KeyType> void add_node_handle_relation(const KeyType& key_from, const DepsNodeHandle *handle, - eDepsRelation_Type type, const char *description); void build_scene(Main *bmain, Scene *scene); @@ -237,8 +229,9 @@ struct DepsgraphRelationBuilder template <typename KeyType> OperationDepsNode *find_operation_node(const KeyType &key); + Depsgraph *getGraph(); + protected: - RootDepsNode *find_node(const RootKey &key) const; TimeSourceDepsNode *find_node(const TimeSourceKey &key) const; ComponentDepsNode *find_node(const ComponentKey &key) const; OperationDepsNode *find_node(const OperationKey &key) const; @@ -250,7 +243,6 @@ protected: const char *description); void add_operation_relation(OperationDepsNode *node_from, OperationDepsNode *node_to, - eDepsRelation_Type type, const char *description); template <typename KeyType> @@ -290,7 +282,6 @@ OperationDepsNode *DepsgraphRelationBuilder::find_operation_node(const KeyType& template <typename KeyFrom, typename KeyTo> void DepsgraphRelationBuilder::add_relation(const KeyFrom &key_from, const KeyTo &key_to, - eDepsRelation_Type type, const char *description) { DepsNode *node_from = find_node(key_from); @@ -298,27 +289,27 @@ void DepsgraphRelationBuilder::add_relation(const KeyFrom &key_from, OperationDepsNode *op_from = node_from ? node_from->get_exit_operation() : NULL; OperationDepsNode *op_to = node_to ? node_to->get_entry_operation() : NULL; if (op_from && op_to) { - add_operation_relation(op_from, op_to, type, description); + add_operation_relation(op_from, op_to, description); } else { if (!op_from) { /* XXX TODO handle as error or report if needed */ node_from = find_node(key_from); - fprintf(stderr, "add_relation(%d, %s) - Could not find op_from (%s)\n", - type, description, key_from.identifier().c_str()); + fprintf(stderr, "add_relation(%s) - Could not find op_from (%s)\n", + description, key_from.identifier().c_str()); } else { - fprintf(stderr, "add_relation(%d, %s) - Failed, but op_from (%s) was ok\n", - type, description, key_from.identifier().c_str()); + fprintf(stderr, "add_relation(%s) - Failed, but op_from (%s) was ok\n", + description, key_from.identifier().c_str()); } if (!op_to) { /* XXX TODO handle as error or report if needed */ - fprintf(stderr, "add_relation(%d, %s) - Could not find op_to (%s)\n", - type, description, key_to.identifier().c_str()); + fprintf(stderr, "add_relation(%s) - Could not find op_to (%s)\n", + description, key_to.identifier().c_str()); } else { - fprintf(stderr, "add_relation(%d, %s) - Failed, but op_to (%s) was ok\n", - type, description, key_to.identifier().c_str()); + fprintf(stderr, "add_relation(%s) - Failed, but op_to (%s) was ok\n", + description, key_to.identifier().c_str()); } } } @@ -326,11 +317,8 @@ void DepsgraphRelationBuilder::add_relation(const KeyFrom &key_from, template <typename KeyTo> void DepsgraphRelationBuilder::add_relation(const TimeSourceKey &key_from, const KeyTo &key_to, - eDepsRelation_Type type, const char *description) { - (void)type; /* Ignored in release builds. */ - BLI_assert(type == DEPSREL_TYPE_TIME); TimeSourceDepsNode *time_from = find_node(key_from); DepsNode *node_to = find_node(key_to); OperationDepsNode *op_to = node_to ? node_to->get_entry_operation() : NULL; @@ -345,23 +333,22 @@ template <typename KeyType> void DepsgraphRelationBuilder::add_node_handle_relation( const KeyType &key_from, const DepsNodeHandle *handle, - eDepsRelation_Type type, const char *description) { DepsNode *node_from = find_node(key_from); OperationDepsNode *op_from = node_from ? node_from->get_exit_operation() : NULL; OperationDepsNode *op_to = handle->node->get_entry_operation(); if (op_from && op_to) { - add_operation_relation(op_from, op_to, type, description); + add_operation_relation(op_from, op_to, description); } else { if (!op_from) { - fprintf(stderr, "add_node_handle_relation(%d, %s) - Could not find op_from (%s)\n", - type, description, key_from.identifier().c_str()); + fprintf(stderr, "add_node_handle_relation(%s) - Could not find op_from (%s)\n", + description, key_from.identifier().c_str()); } if (!op_to) { - fprintf(stderr, "add_node_handle_relation(%d, %s) - Could not find op_to (%s)\n", - type, description, key_from.identifier().c_str()); + fprintf(stderr, "add_node_handle_relation(%s) - Could not find op_to (%s)\n", + description, key_from.identifier().c_str()); } } } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc index feae8bca303..9d6ab3358a7 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc @@ -35,13 +35,6 @@ namespace DEG { ///////////////////////////////////////// -// Root. - -RootKey::RootKey() -{ -} - -///////////////////////////////////////// // Time source. TimeSourceKey::TimeSourceKey() @@ -64,7 +57,7 @@ string TimeSourceKey::identifier() const ComponentKey::ComponentKey() : id(NULL), - type(DEPSNODE_TYPE_UNDEFINED), + type(DEG_NODE_TYPE_UNDEFINED), name("") { } @@ -90,7 +83,7 @@ string ComponentKey::identifier() const OperationKey::OperationKey() : id(NULL), - component_type(DEPSNODE_TYPE_UNDEFINED), + component_type(DEG_NODE_TYPE_UNDEFINED), component_name(""), opcode(DEG_OPCODE_OPERATION), name(""), diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc index 2b4c000f483..be666165a0b 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc @@ -38,10 +38,10 @@ #include "MEM_guardedalloc.h" -extern "C" { -#include "BLI_blenlib.h" #include "BLI_utildefines.h" +#include "BLI_blenlib.h" +extern "C" { #include "DNA_action_types.h" #include "DNA_anim_types.h" #include "DNA_armature_types.h" @@ -51,10 +51,10 @@ extern "C" { #include "BKE_action.h" #include "BKE_armature.h" +} /* extern "C" */ #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" -} /* extern "C" */ #include "intern/builder/deg_builder.h" #include "intern/builder/deg_builder_pchanmap.h" @@ -83,7 +83,7 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *ob, * - see notes on direction of rel below... */ bPoseChannel *rootchan = BKE_armature_ik_solver_find_root(pchan, data); - OperationKey solver_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE, rootchan->name, DEG_OPCODE_POSE_IK_SOLVER); + OperationKey solver_key(&ob->id, DEG_NODE_TYPE_EVAL_POSE, rootchan->name, DEG_OPCODE_POSE_IK_SOLVER); /* IK target */ // XXX: this should get handled as part of the constraint code @@ -96,25 +96,25 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *ob, * testing IK solver. */ // FIXME: geometry targets... - ComponentKey pose_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE); + ComponentKey pose_key(&ob->id, DEG_NODE_TYPE_EVAL_POSE); if ((data->tar->type == OB_ARMATURE) && (data->subtarget[0])) { /* TODO(sergey): This is only for until granular update stores intermediate result. */ if (data->tar != ob) { /* different armature - can just read the results */ - ComponentKey target_key(&data->tar->id, DEPSNODE_TYPE_BONE, data->subtarget); - add_relation(target_key, pose_key, DEPSREL_TYPE_TRANSFORM, con->name); + ComponentKey target_key(&data->tar->id, DEG_NODE_TYPE_BONE, data->subtarget); + add_relation(target_key, pose_key, con->name); } else { /* same armature - we'll use the ready state only, just in case this bone is in the chain we're solving */ - OperationKey target_key(&data->tar->id, DEPSNODE_TYPE_BONE, data->subtarget, DEG_OPCODE_BONE_DONE); - add_relation(target_key, solver_key, DEPSREL_TYPE_TRANSFORM, con->name); + OperationKey target_key(&data->tar->id, DEG_NODE_TYPE_BONE, data->subtarget, DEG_OPCODE_BONE_DONE); + add_relation(target_key, solver_key, con->name); } } else if (ELEM(data->tar->type, OB_MESH, OB_LATTICE) && (data->subtarget[0])) { /* vertex group target */ /* NOTE: for now, we don't need to represent vertex groups separately... */ - ComponentKey target_key(&data->tar->id, DEPSNODE_TYPE_GEOMETRY); - add_relation(target_key, solver_key, DEPSREL_TYPE_GEOMETRY_EVAL, con->name); + ComponentKey target_key(&data->tar->id, DEG_NODE_TYPE_GEOMETRY); + add_relation(target_key, solver_key, con->name); if (data->tar->type == OB_MESH) { OperationDepsNode *node2 = find_operation_node(target_key); @@ -125,8 +125,8 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *ob, } else { /* Standard Object Target */ - ComponentKey target_key(&data->tar->id, DEPSNODE_TYPE_TRANSFORM); - add_relation(target_key, pose_key, DEPSREL_TYPE_TRANSFORM, con->name); + ComponentKey target_key(&data->tar->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(target_key, pose_key, con->name); } if ((data->tar == ob) && (data->subtarget[0])) { @@ -142,14 +142,14 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *ob, if (data->poletar != NULL) { if ((data->poletar->type == OB_ARMATURE) && (data->polesubtarget[0])) { // XXX: same armature issues - ready vs done? - ComponentKey target_key(&data->poletar->id, DEPSNODE_TYPE_BONE, data->polesubtarget); - add_relation(target_key, solver_key, DEPSREL_TYPE_TRANSFORM, con->name); + ComponentKey target_key(&data->poletar->id, DEG_NODE_TYPE_BONE, data->polesubtarget); + add_relation(target_key, solver_key, con->name); } else if (ELEM(data->poletar->type, OB_MESH, OB_LATTICE) && (data->polesubtarget[0])) { /* vertex group target */ /* NOTE: for now, we don't need to represent vertex groups separately... */ - ComponentKey target_key(&data->poletar->id, DEPSNODE_TYPE_GEOMETRY); - add_relation(target_key, solver_key, DEPSREL_TYPE_GEOMETRY_EVAL, con->name); + ComponentKey target_key(&data->poletar->id, DEG_NODE_TYPE_GEOMETRY); + add_relation(target_key, solver_key, con->name); if (data->poletar->type == OB_MESH) { OperationDepsNode *node2 = find_operation_node(target_key); @@ -159,8 +159,8 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *ob, } } else { - ComponentKey target_key(&data->poletar->id, DEPSNODE_TYPE_TRANSFORM); - add_relation(target_key, solver_key, DEPSREL_TYPE_TRANSFORM, con->name); + ComponentKey target_key(&data->poletar->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(target_key, solver_key, con->name); } } @@ -170,19 +170,17 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *ob, bPoseChannel *parchan = pchan; /* exclude tip from chain? */ if (!(data->flag & CONSTRAINT_IK_TIP)) { - OperationKey tip_transforms_key(&ob->id, DEPSNODE_TYPE_BONE, + OperationKey tip_transforms_key(&ob->id, DEG_NODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_LOCAL); - add_relation(solver_key, tip_transforms_key, - DEPSREL_TYPE_TRANSFORM, "IK Solver Result"); + add_relation(solver_key, tip_transforms_key, "IK Solver Result"); parchan = pchan->parent; } root_map->add_bone(parchan->name, rootchan->name); - OperationKey parchan_transforms_key(&ob->id, DEPSNODE_TYPE_BONE, + OperationKey parchan_transforms_key(&ob->id, DEG_NODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_READY); - add_relation(parchan_transforms_key, solver_key, - DEPSREL_TYPE_TRANSFORM, "IK Solver Owner"); + add_relation(parchan_transforms_key, solver_key, "IK Solver Owner"); /* Walk to the chain's root */ //size_t segcount = 0; @@ -196,15 +194,15 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *ob, * grab the result with IK solver results... */ if (parchan != pchan) { - OperationKey parent_key(&ob->id, DEPSNODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_READY); - add_relation(parent_key, solver_key, DEPSREL_TYPE_TRANSFORM, "IK Chain Parent"); + OperationKey parent_key(&ob->id, DEG_NODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_READY); + add_relation(parent_key, solver_key, "IK Chain Parent"); - OperationKey done_key(&ob->id, DEPSNODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_DONE); - add_relation(solver_key, done_key, DEPSREL_TYPE_TRANSFORM, "IK Chain Result"); + OperationKey done_key(&ob->id, DEG_NODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_DONE); + add_relation(solver_key, done_key, "IK Chain Result"); } else { - OperationKey final_transforms_key(&ob->id, DEPSNODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_DONE); - add_relation(solver_key, final_transforms_key, DEPSREL_TYPE_TRANSFORM, "IK Solver Result"); + OperationKey final_transforms_key(&ob->id, DEG_NODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_DONE); + add_relation(solver_key, final_transforms_key, "IK Solver Result"); } parchan->flag |= POSE_DONE; @@ -219,8 +217,8 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *ob, parchan = parchan->parent; } - OperationKey flush_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_DONE); - add_relation(solver_key, flush_key, DEPSREL_TYPE_OPERATION, "PoseEval Result-Bone Link"); + OperationKey flush_key(&ob->id, DEG_NODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_DONE); + add_relation(solver_key, flush_key, "PoseEval Result-Bone Link"); } /* Spline IK Eval Steps */ @@ -231,14 +229,14 @@ void DepsgraphRelationBuilder::build_splineik_pose(Object *ob, { bSplineIKConstraint *data = (bSplineIKConstraint *)con->data; bPoseChannel *rootchan = BKE_armature_splineik_solver_find_root(pchan, data); - OperationKey transforms_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_READY); - OperationKey solver_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE, rootchan->name, DEG_OPCODE_POSE_SPLINE_IK_SOLVER); + OperationKey transforms_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_READY); + OperationKey solver_key(&ob->id, DEG_NODE_TYPE_EVAL_POSE, rootchan->name, DEG_OPCODE_POSE_SPLINE_IK_SOLVER); /* attach owner to IK Solver too * - assume that owner is always part of chain * - see notes on direction of rel below... */ - add_relation(transforms_key, solver_key, DEPSREL_TYPE_TRANSFORM, "Spline IK Solver Owner"); + add_relation(transforms_key, solver_key, "Spline IK Solver Owner"); /* attach path dependency to solver */ if (data->tar) { @@ -247,14 +245,14 @@ void DepsgraphRelationBuilder::build_splineik_pose(Object *ob, * See IK pose for a bit more information. */ // TODO: the bigggest point here is that we need the curve PATH and not just the general geometry... - ComponentKey target_key(&data->tar->id, DEPSNODE_TYPE_GEOMETRY); - ComponentKey pose_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE); - add_relation(target_key, pose_key, DEPSREL_TYPE_TRANSFORM, "[Curve.Path -> Spline IK] DepsRel"); + ComponentKey target_key(&data->tar->id, DEG_NODE_TYPE_GEOMETRY); + ComponentKey pose_key(&ob->id, DEG_NODE_TYPE_EVAL_POSE); + add_relation(target_key, pose_key, "[Curve.Path -> Spline IK] DepsRel"); } pchan->flag |= POSE_DONE; - OperationKey final_transforms_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_DONE); - add_relation(solver_key, final_transforms_key, DEPSREL_TYPE_TRANSFORM, "Spline IK Result"); + OperationKey final_transforms_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_DONE); + add_relation(solver_key, final_transforms_key, "Spline IK Result"); root_map->add_bone(pchan->name, rootchan->name); @@ -270,16 +268,16 @@ void DepsgraphRelationBuilder::build_splineik_pose(Object *ob, * grab the result with IK solver results... */ if (parchan != pchan) { - OperationKey parent_key(&ob->id, DEPSNODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_READY); - add_relation(parent_key, solver_key, DEPSREL_TYPE_TRANSFORM, "Spline IK Solver Update"); + OperationKey parent_key(&ob->id, DEG_NODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_READY); + add_relation(parent_key, solver_key, "Spline IK Solver Update"); - OperationKey done_key(&ob->id, DEPSNODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_DONE); - add_relation(solver_key, done_key, DEPSREL_TYPE_TRANSFORM, "IK Chain Result"); + OperationKey done_key(&ob->id, DEG_NODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_DONE); + add_relation(solver_key, done_key, "IK Chain Result"); } parchan->flag |= POSE_DONE; - OperationKey final_transforms_key(&ob->id, DEPSNODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_DONE); - add_relation(solver_key, final_transforms_key, DEPSREL_TYPE_TRANSFORM, "Spline IK Solver Result"); + OperationKey final_transforms_key(&ob->id, DEG_NODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_DONE); + add_relation(solver_key, final_transforms_key, "Spline IK Solver Result"); root_map->add_bone(parchan->name, rootchan->name); @@ -288,8 +286,8 @@ void DepsgraphRelationBuilder::build_splineik_pose(Object *ob, if ((segcount == data->chainlen) || (segcount > 255)) break; /* 255 is weak */ } - OperationKey flush_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_DONE); - add_relation(solver_key, flush_key, DEPSREL_TYPE_OPERATION, "PoseEval Result-Bone Link"); + OperationKey flush_key(&ob->id, DEG_NODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_DONE); + add_relation(solver_key, flush_key, "PoseEval Result-Bone Link"); } /* Pose/Armature Bones Graph */ @@ -301,21 +299,21 @@ void DepsgraphRelationBuilder::build_rig(Scene *scene, Object *ob) // TODO: selection status? /* attach links between pose operations */ - OperationKey init_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_INIT); - OperationKey flush_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_DONE); + OperationKey init_key(&ob->id, DEG_NODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_INIT); + OperationKey flush_key(&ob->id, DEG_NODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_DONE); - add_relation(init_key, flush_key, DEPSREL_TYPE_COMPONENT_ORDER, "[Pose Init -> Pose Cleanup]"); + add_relation(init_key, flush_key, "[Pose Init -> Pose Cleanup]"); /* Make sure pose is up-to-date with armature updates. */ OperationKey armature_key(&arm->id, - DEPSNODE_TYPE_PARAMETERS, + DEG_NODE_TYPE_PARAMETERS, DEG_OPCODE_PLACEHOLDER, "Armature Eval"); - add_relation(armature_key, init_key, DEPSREL_TYPE_COMPONENT_ORDER, "Data dependency"); + add_relation(armature_key, init_key, "Data dependency"); if (needs_animdata_node(&ob->id)) { - ComponentKey animation_key(&ob->id, DEPSNODE_TYPE_ANIMATION); - add_relation(animation_key, init_key, DEPSREL_TYPE_OPERATION, "Rig Animation"); + ComponentKey animation_key(&ob->id, DEG_NODE_TYPE_ANIMATION); + add_relation(animation_key, init_key, "Rig Animation"); } /* IK Solvers... @@ -370,26 +368,25 @@ void DepsgraphRelationBuilder::build_rig(Scene *scene, Object *ob) /* TODO(sergey): Once partial updates are possible use relation between * object transform and solver itself in it's build function. */ - ComponentKey pose_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE); - ComponentKey local_transform_key(&ob->id, DEPSNODE_TYPE_TRANSFORM); - add_relation(local_transform_key, pose_key, DEPSREL_TYPE_TRANSFORM, "Local Transforms"); + ComponentKey pose_key(&ob->id, DEG_NODE_TYPE_EVAL_POSE); + ComponentKey local_transform_key(&ob->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(local_transform_key, pose_key, "Local Transforms"); } - /* links between operations for each bone */ LINKLIST_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) { - OperationKey bone_local_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL); - OperationKey bone_pose_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_POSE_PARENT); - OperationKey bone_ready_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_READY); - OperationKey bone_done_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_DONE); + OperationKey bone_local_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL); + OperationKey bone_pose_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_POSE_PARENT); + OperationKey bone_ready_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_READY); + OperationKey bone_done_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_DONE); pchan->flag &= ~POSE_DONE; /* pose init to bone local */ - add_relation(init_key, bone_local_key, DEPSREL_TYPE_OPERATION, "PoseEval Source-Bone Link"); + add_relation(init_key, bone_local_key, "PoseEval Source-Bone Link"); /* local to pose parenting operation */ - add_relation(bone_local_key, bone_pose_key, DEPSREL_TYPE_OPERATION, "Bone Local - PoseSpace Link"); + add_relation(bone_local_key, bone_pose_key, "Bone Local - PoseSpace Link"); /* parent relation */ if (pchan->parent != NULL) { @@ -403,26 +400,26 @@ void DepsgraphRelationBuilder::build_rig(Scene *scene, Object *ob) parent_key_opcode = DEG_OPCODE_BONE_DONE; } - OperationKey parent_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->parent->name, parent_key_opcode); - add_relation(parent_key, bone_pose_key, DEPSREL_TYPE_TRANSFORM, "[Parent Bone -> Child Bone]"); + OperationKey parent_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->parent->name, parent_key_opcode); + add_relation(parent_key, bone_pose_key, "[Parent Bone -> Child Bone]"); } /* constraints */ if (pchan->constraints.first != NULL) { /* constraints stack and constraint dependencies */ - build_constraints(scene, &ob->id, DEPSNODE_TYPE_BONE, pchan->name, &pchan->constraints, &root_map); + build_constraints(scene, &ob->id, DEG_NODE_TYPE_BONE, pchan->name, &pchan->constraints, &root_map); /* pose -> constraints */ - OperationKey constraints_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_CONSTRAINTS); - add_relation(bone_pose_key, constraints_key, DEPSREL_TYPE_OPERATION, "Constraints Stack"); + OperationKey constraints_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_CONSTRAINTS); + add_relation(bone_pose_key, constraints_key, "Constraints Stack"); /* constraints -> ready */ // TODO: when constraint stack is exploded, this step should occur before the first IK solver - add_relation(constraints_key, bone_ready_key, DEPSREL_TYPE_OPERATION, "Constraints -> Ready"); + add_relation(constraints_key, bone_ready_key, "Constraints -> Ready"); } else { /* pose -> ready */ - add_relation(bone_pose_key, bone_ready_key, DEPSREL_TYPE_OPERATION, "Pose -> Ready"); + add_relation(bone_pose_key, bone_ready_key, "Pose -> Ready"); } /* bone ready -> done @@ -430,25 +427,25 @@ void DepsgraphRelationBuilder::build_rig(Scene *scene, Object *ob) * For IK chains however, an additional rel is created from IK to done, * with transitive reduction removing this one... */ - add_relation(bone_ready_key, bone_done_key, DEPSREL_TYPE_OPERATION, "Ready -> Done"); + add_relation(bone_ready_key, bone_done_key, "Ready -> Done"); /* assume that all bones must be done for the pose to be ready (for deformers) */ - add_relation(bone_done_key, flush_key, DEPSREL_TYPE_OPERATION, "PoseEval Result-Bone Link"); + add_relation(bone_done_key, flush_key, "PoseEval Result-Bone Link"); } } void DepsgraphRelationBuilder::build_proxy_rig(Object *ob) { - OperationKey pose_init_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_INIT); - OperationKey pose_done_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_DONE); + OperationKey pose_init_key(&ob->id, DEG_NODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_INIT); + OperationKey pose_done_key(&ob->id, DEG_NODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_DONE); LINKLIST_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) { - OperationKey bone_local_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL); - OperationKey bone_ready_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_READY); - OperationKey bone_done_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_DONE); - add_relation(pose_init_key, bone_local_key, DEPSREL_TYPE_OPERATION, "Pose Init -> Bone Local"); - add_relation(bone_local_key, bone_ready_key, DEPSREL_TYPE_OPERATION, "Local -> Ready"); - add_relation(bone_ready_key, bone_done_key, DEPSREL_TYPE_OPERATION, "Ready -> Done"); - add_relation(bone_done_key, pose_done_key, DEPSREL_TYPE_OPERATION, "Bone Done -> Pose Done"); + OperationKey bone_local_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL); + OperationKey bone_ready_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_READY); + OperationKey bone_done_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_DONE); + add_relation(pose_init_key, bone_local_key, "Pose Init -> Bone Local"); + add_relation(bone_local_key, bone_ready_key, "Local -> Ready"); + add_relation(bone_ready_key, bone_done_key, "Ready -> Done"); + add_relation(bone_done_key, pose_done_key, "Bone Done -> Pose Done"); } } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc index 3bf435c37e0..6a9568e7e8d 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc @@ -38,20 +38,20 @@ #include "MEM_guardedalloc.h" -extern "C" { -#include "BLI_blenlib.h" #include "BLI_utildefines.h" +#include "BLI_blenlib.h" +extern "C" { #include "DNA_node_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "BKE_main.h" #include "BKE_node.h" +} /* extern "C" */ #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" -} /* extern "C" */ #include "intern/builder/deg_builder.h" #include "intern/builder/deg_builder_pchanmap.h" diff --git a/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc b/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc index da71db09f3d..b12af21fc8d 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc @@ -30,9 +30,7 @@ #include "intern/builder/deg_builder_transitive.h" -extern "C" { #include "MEM_guardedalloc.h" -} #include "intern/nodes/deg_node.h" #include "intern/nodes/deg_node_component.h" @@ -105,7 +103,7 @@ void deg_graph_transitive_reduction(Depsgraph *graph) /* Increment in advance, so we can safely remove the relation. */ ++it_rel; - if (rel->from->type == DEPSNODE_TYPE_TIMESOURCE) { + if (rel->from->type == DEG_NODE_TYPE_TIMESOURCE) { /* HACK: time source nodes don't get "done" flag set/cleared. */ /* TODO: there will be other types in future, so iterators above * need modifying. diff --git a/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc b/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc index 0d56ce71c7d..51d4ed91419 100644 --- a/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc +++ b/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc @@ -35,10 +35,10 @@ extern "C" { #include "DNA_listBase.h" +} /* extern "C" */ #include "DEG_depsgraph.h" #include "DEG_depsgraph_debug.h" -} /* extern "C" */ #include "intern/depsgraph_intern.h" #include "util/deg_util_foreach.h" @@ -77,20 +77,18 @@ static const char *deg_debug_colors_light[] = { #ifdef COLOR_SCHEME_NODE_TYPE static const int deg_debug_node_type_color_map[][2] = { - {DEPSNODE_TYPE_ROOT, 0}, - {DEPSNODE_TYPE_TIMESOURCE, 1}, - {DEPSNODE_TYPE_ID_REF, 2}, - {DEPSNODE_TYPE_SUBGRAPH, 3}, + {DEG_NODE_TYPE_TIMESOURCE, 0}, + {DEG_NODE_TYPE_ID_REF, 2}, /* Outer Types */ - {DEPSNODE_TYPE_PARAMETERS, 4}, - {DEPSNODE_TYPE_PROXY, 5}, - {DEPSNODE_TYPE_ANIMATION, 6}, - {DEPSNODE_TYPE_TRANSFORM, 7}, - {DEPSNODE_TYPE_GEOMETRY, 8}, - {DEPSNODE_TYPE_SEQUENCER, 9}, - {DEPSNODE_TYPE_SHADING, 10}, - {DEPSNODE_TYPE_CACHE, 11}, + {DEG_NODE_TYPE_PARAMETERS, 2}, + {DEG_NODE_TYPE_PROXY, 3}, + {DEG_NODE_TYPE_ANIMATION, 4}, + {DEG_NODE_TYPE_TRANSFORM, 5}, + {DEG_NODE_TYPE_GEOMETRY, 6}, + {DEG_NODE_TYPE_SEQUENCER, 7}, + {DEG_NODE_TYPE_SHADING, 8}, + {DEG_NODE_TYPE_CACHE, 9}, {-1, 0} }; #endif @@ -100,9 +98,9 @@ static int deg_debug_node_color_index(const DepsNode *node) #ifdef COLOR_SCHEME_NODE_CLASS /* Some special types. */ switch (node->type) { - case DEPSNODE_TYPE_ID_REF: + case DEG_NODE_TYPE_ID_REF: return 5; - case DEPSNODE_TYPE_OPERATION: + case DEG_NODE_TYPE_OPERATION: { OperationDepsNode *op_node = (OperationDepsNode *)node; if (op_node->is_noop()) @@ -115,9 +113,9 @@ static int deg_debug_node_color_index(const DepsNode *node) } /* Do others based on class. */ switch (node->tclass) { - case DEPSNODE_CLASS_OPERATION: + case DEG_NODE_CLASS_OPERATION: return 4; - case DEPSNODE_CLASS_COMPONENT: + case DEG_NODE_CLASS_COMPONENT: return 1; default: return 9; @@ -201,7 +199,7 @@ static void deg_debug_graphviz_node_color(const DebugContext &ctx, const char *color_update = "dodgerblue3"; const char *color = color_default; if (ctx.show_tags) { - if (node->tclass == DEPSNODE_CLASS_OPERATION) { + if (node->tclass == DEG_NODE_CLASS_OPERATION) { OperationDepsNode *op_node = (OperationDepsNode *)node; if (op_node->flag & DEPSOP_FLAG_DIRECTLY_MODIFIED) { color = color_modified; @@ -222,7 +220,7 @@ static void deg_debug_graphviz_node_penwidth(const DebugContext &ctx, float penwidth_update = 4.0f; float penwidth = penwidth_default; if (ctx.show_tags) { - if (node->tclass == DEPSNODE_CLASS_OPERATION) { + if (node->tclass == DEG_NODE_CLASS_OPERATION) { OperationDepsNode *op_node = (OperationDepsNode *)node; if (op_node->flag & DEPSOP_FLAG_DIRECTLY_MODIFIED) { penwidth = penwidth_modified; @@ -260,7 +258,7 @@ static void deg_debug_graphviz_node_style(const DebugContext &ctx, const DepsNod { const char *base_style = "filled"; /* default style */ if (ctx.show_tags) { - if (node->tclass == DEPSNODE_CLASS_OPERATION) { + if (node->tclass == DEG_NODE_CLASS_OPERATION) { OperationDepsNode *op_node = (OperationDepsNode *)node; if (op_node->flag & (DEPSOP_FLAG_DIRECTLY_MODIFIED | DEPSOP_FLAG_NEEDS_UPDATE)) { base_style = "striped"; @@ -268,13 +266,13 @@ static void deg_debug_graphviz_node_style(const DebugContext &ctx, const DepsNod } } switch (node->tclass) { - case DEPSNODE_CLASS_GENERIC: + case DEG_NODE_CLASS_GENERIC: deg_debug_fprintf(ctx, "\"%s\"", base_style); break; - case DEPSNODE_CLASS_COMPONENT: + case DEG_NODE_CLASS_COMPONENT: deg_debug_fprintf(ctx, "\"%s\"", base_style); break; - case DEPSNODE_CLASS_OPERATION: + case DEG_NODE_CLASS_OPERATION: deg_debug_fprintf(ctx, "\"%s,rounded\"", base_style); break; } @@ -286,13 +284,13 @@ static void deg_debug_graphviz_node_single(const DebugContext &ctx, const char *shape = "box"; string name = node->identifier(); float priority = -1.0f; - if (node->type == DEPSNODE_TYPE_ID_REF) { + if (node->type == DEG_NODE_TYPE_ID_REF) { IDDepsNode *id_node = (IDDepsNode *)node; char buf[256]; BLI_snprintf(buf, sizeof(buf), " (Layers: %u)", id_node->layers); name += buf; } - if (ctx.show_eval_priority && node->tclass == DEPSNODE_CLASS_OPERATION) { + if (ctx.show_eval_priority && node->tclass == DEG_NODE_CLASS_OPERATION) { priority = ((OperationDepsNode *)node)->eval_priority; } deg_debug_fprintf(ctx, "// %s\n", name.c_str()); @@ -322,7 +320,7 @@ static void deg_debug_graphviz_node_cluster_begin(const DebugContext &ctx, const DepsNode *node) { string name = node->identifier(); - if (node->type == DEPSNODE_TYPE_ID_REF) { + if (node->type == DEG_NODE_TYPE_ID_REF) { IDDepsNode *id_node = (IDDepsNode *)node; char buf[256]; BLI_snprintf(buf, sizeof(buf), " (Layers: %u)", id_node->layers); @@ -363,7 +361,7 @@ static void deg_debug_graphviz_node(const DebugContext &ctx, const DepsNode *node) { switch (node->type) { - case DEPSNODE_TYPE_ID_REF: + case DEG_NODE_TYPE_ID_REF: { const IDDepsNode *id_node = (const IDDepsNode *)node; if (BLI_ghash_size(id_node->components) == 0) { @@ -380,30 +378,17 @@ static void deg_debug_graphviz_node(const DebugContext &ctx, } break; } - case DEPSNODE_TYPE_SUBGRAPH: - { - SubgraphDepsNode *sub_node = (SubgraphDepsNode *)node; - if (sub_node->graph) { - deg_debug_graphviz_node_cluster_begin(ctx, node); - deg_debug_graphviz_graph_nodes(ctx, sub_node->graph); - deg_debug_graphviz_node_cluster_end(ctx); - } - else { - deg_debug_graphviz_node_single(ctx, node); - } - break; - } - case DEPSNODE_TYPE_PARAMETERS: - case DEPSNODE_TYPE_ANIMATION: - case DEPSNODE_TYPE_TRANSFORM: - case DEPSNODE_TYPE_PROXY: - case DEPSNODE_TYPE_GEOMETRY: - case DEPSNODE_TYPE_SEQUENCER: - case DEPSNODE_TYPE_EVAL_POSE: - case DEPSNODE_TYPE_BONE: - case DEPSNODE_TYPE_SHADING: - case DEPSNODE_TYPE_CACHE: - case DEPSNODE_TYPE_EVAL_PARTICLES: + case DEG_NODE_TYPE_PARAMETERS: + case DEG_NODE_TYPE_ANIMATION: + case DEG_NODE_TYPE_TRANSFORM: + case DEG_NODE_TYPE_PROXY: + case DEG_NODE_TYPE_GEOMETRY: + case DEG_NODE_TYPE_SEQUENCER: + case DEG_NODE_TYPE_EVAL_POSE: + case DEG_NODE_TYPE_BONE: + case DEG_NODE_TYPE_SHADING: + case DEG_NODE_TYPE_CACHE: + case DEG_NODE_TYPE_EVAL_PARTICLES: { ComponentDepsNode *comp_node = (ComponentDepsNode *)node; if (!comp_node->operations.empty()) { @@ -427,24 +412,19 @@ static void deg_debug_graphviz_node(const DebugContext &ctx, static bool deg_debug_graphviz_is_cluster(const DepsNode *node) { switch (node->type) { - case DEPSNODE_TYPE_ID_REF: + case DEG_NODE_TYPE_ID_REF: { const IDDepsNode *id_node = (const IDDepsNode *)node; return BLI_ghash_size(id_node->components) > 0; } - case DEPSNODE_TYPE_SUBGRAPH: - { - SubgraphDepsNode *sub_node = (SubgraphDepsNode *)node; - return sub_node->graph != NULL; - } - case DEPSNODE_TYPE_PARAMETERS: - case DEPSNODE_TYPE_ANIMATION: - case DEPSNODE_TYPE_TRANSFORM: - case DEPSNODE_TYPE_PROXY: - case DEPSNODE_TYPE_GEOMETRY: - case DEPSNODE_TYPE_SEQUENCER: - case DEPSNODE_TYPE_EVAL_POSE: - case DEPSNODE_TYPE_BONE: + case DEG_NODE_TYPE_PARAMETERS: + case DEG_NODE_TYPE_ANIMATION: + case DEG_NODE_TYPE_TRANSFORM: + case DEG_NODE_TYPE_PROXY: + case DEG_NODE_TYPE_GEOMETRY: + case DEG_NODE_TYPE_SEQUENCER: + case DEG_NODE_TYPE_EVAL_POSE: + case DEG_NODE_TYPE_BONE: { ComponentDepsNode *comp_node = (ComponentDepsNode *)node; return !comp_node->operations.empty(); @@ -458,14 +438,14 @@ static bool deg_debug_graphviz_is_owner(const DepsNode *node, const DepsNode *other) { switch (node->tclass) { - case DEPSNODE_CLASS_COMPONENT: + case DEG_NODE_CLASS_COMPONENT: { ComponentDepsNode *comp_node = (ComponentDepsNode *)node; if (comp_node->owner == other) return true; break; } - case DEPSNODE_CLASS_OPERATION: + case DEG_NODE_CLASS_OPERATION: { OperationDepsNode *op_node = (OperationDepsNode *)node; if (op_node->owner == other) @@ -517,15 +497,12 @@ static void deg_debug_graphviz_node_relations(const DebugContext &ctx, static void deg_debug_graphviz_graph_nodes(const DebugContext &ctx, const Depsgraph *graph) { - if (graph->root_node) { - deg_debug_graphviz_node(ctx, graph->root_node); - } GHASH_FOREACH_BEGIN (DepsNode *, node, graph->id_hash) { deg_debug_graphviz_node(ctx, node); } GHASH_FOREACH_END(); - TimeSourceDepsNode *time_source = graph->find_time_source(NULL); + TimeSourceDepsNode *time_source = graph->find_time_source(); if (time_source != NULL) { deg_debug_graphviz_node(ctx, time_source); } @@ -546,7 +523,7 @@ static void deg_debug_graphviz_graph_relations(const DebugContext &ctx, } GHASH_FOREACH_END(); - TimeSourceDepsNode *time_source = graph->find_time_source(NULL); + TimeSourceDepsNode *time_source = graph->find_time_source(); if (time_source != NULL) { deg_debug_graphviz_node_relations(ctx, time_source); } diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index 5604044e123..aa21f0995be 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -69,26 +69,22 @@ static DEG_EditorUpdateSceneCb deg_editor_update_scene_cb = NULL; static DEG_EditorUpdateScenePreCb deg_editor_update_scene_pre_cb = NULL; Depsgraph::Depsgraph() - : root_node(NULL), + : time_source(NULL), need_update(false), layers(0) { BLI_spin_init(&lock); id_hash = BLI_ghash_ptr_new("Depsgraph id hash"); - subgraphs = BLI_gset_ptr_new("Depsgraph subgraphs"); entry_tags = BLI_gset_ptr_new("Depsgraph entry_tags"); } Depsgraph::~Depsgraph() { - /* Free root node - it won't have been freed yet... */ clear_id_nodes(); - clear_subgraph_nodes(); BLI_ghash_free(id_hash, NULL, NULL); - BLI_gset_free(subgraphs, NULL); BLI_gset_free(entry_tags, NULL); - if (this->root_node != NULL) { - OBJECT_GUARDED_DELETE(this->root_node, RootDepsNode); + if (time_source != NULL) { + OBJECT_GUARDED_DELETE(time_source, TimeSourceDepsNode); } BLI_spin_end(&lock); } @@ -131,7 +127,7 @@ static bool pointer_to_component_node_criteria(const PointerRNA *ptr, bPoseChannel *pchan = (bPoseChannel *)ptr->data; /* Bone - generally, we just want the bone component... */ - *type = DEPSNODE_TYPE_BONE; + *type = DEG_NODE_TYPE_BONE; *subdata = pchan->name; return true; @@ -141,7 +137,7 @@ static bool pointer_to_component_node_criteria(const PointerRNA *ptr, /* armature-level bone, but it ends up going to bone component anyway */ // TODO: the ID in thise case will end up being bArmature, not Object as needed! - *type = DEPSNODE_TYPE_BONE; + *type = DEG_NODE_TYPE_BONE; *subdata = bone->name; //*id = ... @@ -155,7 +151,7 @@ static bool pointer_to_component_node_criteria(const PointerRNA *ptr, if (BLI_findindex(&ob->constraints, con) != -1) { /* object transform */ // XXX: for now, we can't address the specific constraint or the constraint stack... - *type = DEPSNODE_TYPE_TRANSFORM; + *type = DEG_NODE_TYPE_TRANSFORM; return true; } else if (ob->pose) { @@ -163,7 +159,7 @@ static bool pointer_to_component_node_criteria(const PointerRNA *ptr, for (pchan = (bPoseChannel *)ob->pose->chanbase.first; pchan; pchan = pchan->next) { if (BLI_findindex(&pchan->constraints, con) != -1) { /* bone transforms */ - *type = DEPSNODE_TYPE_BONE; + *type = DEG_NODE_TYPE_BONE; *subdata = pchan->name; return true; } @@ -178,7 +174,7 @@ static bool pointer_to_component_node_criteria(const PointerRNA *ptr, * so although we have unique ops for modifiers, * we can't lump them together */ - *type = DEPSNODE_TYPE_BONE; + *type = DEG_NODE_TYPE_BONE; //*subdata = md->name; return true; @@ -195,14 +191,14 @@ static bool pointer_to_component_node_criteria(const PointerRNA *ptr, strstr(prop_identifier, "scale") || strstr(prop_identifier, "matrix_")) { - *type = DEPSNODE_TYPE_TRANSFORM; + *type = DEG_NODE_TYPE_TRANSFORM; return true; } else if (strstr(prop_identifier, "data")) { /* We access object.data, most likely a geometry. * Might be a bone tho.. */ - *type = DEPSNODE_TYPE_GEOMETRY; + *type = DEG_NODE_TYPE_GEOMETRY; return true; } } @@ -212,21 +208,21 @@ static bool pointer_to_component_node_criteria(const PointerRNA *ptr, /* ShapeKeys are currently handled as geometry on the geometry that owns it */ *id = key->from; // XXX - *type = DEPSNODE_TYPE_PARAMETERS; + *type = DEG_NODE_TYPE_PARAMETERS; return true; } else if (RNA_struct_is_a(ptr->type, &RNA_Sequence)) { Sequence *seq = (Sequence *)ptr->data; /* Sequencer strip */ - *type = DEPSNODE_TYPE_SEQUENCER; + *type = DEG_NODE_TYPE_SEQUENCER; *subdata = seq->name; // xxx? return true; } if (prop) { /* All unknown data effectively falls under "parameter evaluation" */ - *type = DEPSNODE_TYPE_PARAMETERS; + *type = DEG_NODE_TYPE_PARAMETERS; return true; } @@ -263,72 +259,18 @@ static void id_node_deleter(void *value) OBJECT_GUARDED_DELETE(id_node, IDDepsNode); } -RootDepsNode *Depsgraph::add_root_node() +TimeSourceDepsNode *Depsgraph::add_time_source() { - if (!root_node) { - DepsNodeFactory *factory = deg_get_node_factory(DEPSNODE_TYPE_ROOT); - root_node = (RootDepsNode *)factory->create_node(NULL, "", "Root (Scene)"); + if (time_source == NULL) { + DepsNodeFactory *factory = deg_get_node_factory(DEG_NODE_TYPE_TIMESOURCE); + time_source = (TimeSourceDepsNode *)factory->create_node(NULL, "", "Time Source"); } - return root_node; + return time_source; } -TimeSourceDepsNode *Depsgraph::find_time_source(const ID *id) const +TimeSourceDepsNode *Depsgraph::find_time_source() const { - /* Search for one attached to a particular ID? */ - if (id) { - /* Check if it was added as a component - * (as may be done for subgraphs needing timeoffset). - */ - IDDepsNode *id_node = find_id_node(id); - if (id_node) { - // XXX: review this -// return id_node->find_component(DEPSNODE_TYPE_TIMESOURCE); - } - BLI_assert(!"Not implemented yet"); - } - else { - /* Use "official" timesource. */ - return root_node->time_source; - } - return NULL; -} - -SubgraphDepsNode *Depsgraph::add_subgraph_node(const ID *id) -{ - DepsNodeFactory *factory = deg_get_node_factory(DEPSNODE_TYPE_SUBGRAPH); - SubgraphDepsNode *subgraph_node = - (SubgraphDepsNode *)factory->create_node(id, "", id->name + 2); - - /* Add to subnodes list. */ - BLI_gset_insert(subgraphs, subgraph_node); - - /* if there's an ID associated, add to ID-nodes lookup too */ - if (id) { -#if 0 - /* XXX subgraph node is NOT a true IDDepsNode - what is this supposed to do? */ - // TODO: what to do if subgraph's ID has already been added? - BLI_assert(!graph->find_id_node(id)); - graph->id_hash[id] = this; -#endif - } - - return subgraph_node; -} - -void Depsgraph::remove_subgraph_node(SubgraphDepsNode *subgraph_node) -{ - BLI_gset_remove(subgraphs, subgraph_node, NULL); - OBJECT_GUARDED_DELETE(subgraph_node, SubgraphDepsNode); -} - -void Depsgraph::clear_subgraph_nodes() -{ - GSET_FOREACH_BEGIN(SubgraphDepsNode *, subgraph_node, subgraphs) - { - OBJECT_GUARDED_DELETE(subgraph_node, SubgraphDepsNode); - } - GSET_FOREACH_END(); - BLI_gset_clear(subgraphs, NULL); + return time_source; } IDDepsNode *Depsgraph::find_id_node(const ID *id) const @@ -340,7 +282,7 @@ IDDepsNode *Depsgraph::add_id_node(ID *id, const char *name) { IDDepsNode *id_node = find_id_node(id); if (!id_node) { - DepsNodeFactory *factory = deg_get_node_factory(DEPSNODE_TYPE_ID_REF); + DepsNodeFactory *factory = deg_get_node_factory(DEG_NODE_TYPE_ID_REF); id_node = (IDDepsNode *)factory->create_node(id, "", name); id->tag |= LIB_TAG_DOIT; /* register */ @@ -349,16 +291,6 @@ IDDepsNode *Depsgraph::add_id_node(ID *id, const char *name) return id_node; } -void Depsgraph::remove_id_node(const ID *id) -{ - IDDepsNode *id_node = find_id_node(id); - if (id_node) { - /* unregister */ - BLI_ghash_remove(id_hash, id, NULL, NULL); - OBJECT_GUARDED_DELETE(id_node, IDDepsNode); - } -} - void Depsgraph::clear_id_nodes() { BLI_ghash_clear(id_hash, NULL, id_node_deleter); @@ -367,15 +299,14 @@ void Depsgraph::clear_id_nodes() /* Add new relationship between two nodes. */ DepsRelation *Depsgraph::add_new_relation(OperationDepsNode *from, OperationDepsNode *to, - eDepsRelation_Type type, const char *description) { /* Create new relation, and add it to the graph. */ - DepsRelation *rel = OBJECT_GUARDED_NEW(DepsRelation, from, to, type, description); + DepsRelation *rel = OBJECT_GUARDED_NEW(DepsRelation, from, to, description); /* TODO(sergey): Find a better place for this. */ #ifdef WITH_OPENSUBDIV ComponentDepsNode *comp_node = from->owner; - if (comp_node->type == DEPSNODE_TYPE_GEOMETRY) { + if (comp_node->type == DEG_NODE_TYPE_GEOMETRY) { IDDepsNode *id_to = to->owner->owner; IDDepsNode *id_from = from->owner->owner; if (id_to != id_from && (id_to->id->tag & LIB_TAG_ID_RECALC_ALL)) { @@ -391,11 +322,10 @@ DepsRelation *Depsgraph::add_new_relation(OperationDepsNode *from, /* Add new relation between two nodes */ DepsRelation *Depsgraph::add_new_relation(DepsNode *from, DepsNode *to, - eDepsRelation_Type type, const char *description) { /* Create new relation, and add it to the graph. */ - DepsRelation *rel = OBJECT_GUARDED_NEW(DepsRelation, from, to, type, description); + DepsRelation *rel = OBJECT_GUARDED_NEW(DepsRelation, from, to, description); return rel; } @@ -404,12 +334,10 @@ DepsRelation *Depsgraph::add_new_relation(DepsNode *from, DepsNode *to, DepsRelation::DepsRelation(DepsNode *from, DepsNode *to, - eDepsRelation_Type type, const char *description) : from(from), to(to), name(description), - type(type), flag(0) { #ifndef NDEBUG @@ -472,11 +400,10 @@ void Depsgraph::add_entry_tag(OperationDepsNode *node) void Depsgraph::clear_all_nodes() { clear_id_nodes(); - clear_subgraph_nodes(); BLI_ghash_clear(id_hash, NULL, NULL); - if (this->root_node) { - OBJECT_GUARDED_DELETE(this->root_node, RootDepsNode); - root_node = NULL; + if (time_source != NULL) { + OBJECT_GUARDED_DELETE(time_source, TimeSourceDepsNode); + time_source = NULL; } } diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h index e668facd645..f72f8dd9311 100644 --- a/source/blender/depsgraph/intern/depsgraph.h +++ b/source/blender/depsgraph/intern/depsgraph.h @@ -49,10 +49,8 @@ struct PropertyRNA; namespace DEG { struct DepsNode; -struct RootDepsNode; struct TimeSourceDepsNode; struct IDDepsNode; -struct SubgraphDepsNode; struct ComponentDepsNode; struct OperationDepsNode; @@ -79,12 +77,10 @@ struct DepsRelation { /* relationship attributes */ const char *name; /* label for debugging */ - eDepsRelation_Type type; /* type */ int flag; /* (eDepsRelation_Flag) */ DepsRelation(DepsNode *from, DepsNode *to, - eDepsRelation_Type type, const char *description); ~DepsRelation(); @@ -111,28 +107,20 @@ struct Depsgraph { */ DepsNode *find_node_from_pointer(const PointerRNA *ptr, const PropertyRNA *prop) const; - RootDepsNode *add_root_node(); - - TimeSourceDepsNode *find_time_source(const ID *id = NULL) const; - - SubgraphDepsNode *add_subgraph_node(const ID *id); - void remove_subgraph_node(SubgraphDepsNode *subgraph_node); - void clear_subgraph_nodes(); + TimeSourceDepsNode *add_time_source(); + TimeSourceDepsNode *find_time_source() const; IDDepsNode *find_id_node(const ID *id) const; IDDepsNode *add_id_node(ID *id, const char *name = ""); - void remove_id_node(const ID *id); void clear_id_nodes(); /* Add new relationship between two nodes. */ DepsRelation *add_new_relation(OperationDepsNode *from, OperationDepsNode *to, - eDepsRelation_Type type, const char *description); DepsRelation *add_new_relation(DepsNode *from, DepsNode *to, - eDepsRelation_Type type, const char *description); /* Tag a specific node as needing updates. */ @@ -147,11 +135,8 @@ struct Depsgraph { * (for quick lookups). */ GHash *id_hash; - /* "root" node - the one where all evaluation enters from. */ - RootDepsNode *root_node; - - /* Subgraphs referenced in tree. */ - GSet *subgraphs; + /* Top-level time source node. */ + TimeSourceDepsNode *time_source; /* Indicates whether relations needs to be updated. */ bool need_update; diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc index 3a69469053c..47bf5e7ecbb 100644 --- a/source/blender/depsgraph/intern/depsgraph_build.cc +++ b/source/blender/depsgraph/intern/depsgraph_build.cc @@ -34,12 +34,6 @@ // #define DEBUG_TIME -extern "C" { -#include "DNA_cachefile_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "DNA_object_force.h" - #include "BLI_utildefines.h" #include "BLI_ghash.h" @@ -48,17 +42,22 @@ extern "C" { # include "PIL_time_utildefines.h" #endif +extern "C" { +#include "DNA_cachefile_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_force.h" + #include "BKE_main.h" #include "BKE_collision.h" #include "BKE_effect.h" #include "BKE_modifier.h" +} /* extern "C" */ #include "DEG_depsgraph.h" #include "DEG_depsgraph_debug.h" #include "DEG_depsgraph_build.h" -} /* extern "C" */ - #include "builder/deg_builder.h" #include "builder/deg_builder_cycle.h" #include "builder/deg_builder_nodes.h" @@ -81,29 +80,29 @@ static DEG::eDepsNode_Type deg_build_scene_component_type( eDepsSceneComponentType component) { switch (component) { - case DEG_SCENE_COMP_PARAMETERS: return DEG::DEPSNODE_TYPE_PARAMETERS; - case DEG_SCENE_COMP_ANIMATION: return DEG::DEPSNODE_TYPE_ANIMATION; - case DEG_SCENE_COMP_SEQUENCER: return DEG::DEPSNODE_TYPE_SEQUENCER; + case DEG_SCENE_COMP_PARAMETERS: return DEG::DEG_NODE_TYPE_PARAMETERS; + case DEG_SCENE_COMP_ANIMATION: return DEG::DEG_NODE_TYPE_ANIMATION; + case DEG_SCENE_COMP_SEQUENCER: return DEG::DEG_NODE_TYPE_SEQUENCER; } - return DEG::DEPSNODE_TYPE_UNDEFINED; + return DEG::DEG_NODE_TYPE_UNDEFINED; } static DEG::eDepsNode_Type deg_build_object_component_type( eDepsObjectComponentType component) { switch (component) { - case DEG_OB_COMP_PARAMETERS: return DEG::DEPSNODE_TYPE_PARAMETERS; - case DEG_OB_COMP_PROXY: return DEG::DEPSNODE_TYPE_PROXY; - case DEG_OB_COMP_ANIMATION: return DEG::DEPSNODE_TYPE_ANIMATION; - case DEG_OB_COMP_TRANSFORM: return DEG::DEPSNODE_TYPE_TRANSFORM; - case DEG_OB_COMP_GEOMETRY: return DEG::DEPSNODE_TYPE_GEOMETRY; - case DEG_OB_COMP_EVAL_POSE: return DEG::DEPSNODE_TYPE_EVAL_POSE; - case DEG_OB_COMP_BONE: return DEG::DEPSNODE_TYPE_BONE; - case DEG_OB_COMP_EVAL_PARTICLES: return DEG::DEPSNODE_TYPE_EVAL_PARTICLES; - case DEG_OB_COMP_SHADING: return DEG::DEPSNODE_TYPE_SHADING; - case DEG_OB_COMP_CACHE: return DEG::DEPSNODE_TYPE_CACHE; + case DEG_OB_COMP_PARAMETERS: return DEG::DEG_NODE_TYPE_PARAMETERS; + case DEG_OB_COMP_PROXY: return DEG::DEG_NODE_TYPE_PROXY; + case DEG_OB_COMP_ANIMATION: return DEG::DEG_NODE_TYPE_ANIMATION; + case DEG_OB_COMP_TRANSFORM: return DEG::DEG_NODE_TYPE_TRANSFORM; + case DEG_OB_COMP_GEOMETRY: return DEG::DEG_NODE_TYPE_GEOMETRY; + case DEG_OB_COMP_EVAL_POSE: return DEG::DEG_NODE_TYPE_EVAL_POSE; + case DEG_OB_COMP_BONE: return DEG::DEG_NODE_TYPE_BONE; + case DEG_OB_COMP_EVAL_PARTICLES: return DEG::DEG_NODE_TYPE_EVAL_PARTICLES; + case DEG_OB_COMP_SHADING: return DEG::DEG_NODE_TYPE_SHADING; + case DEG_OB_COMP_CACHE: return DEG::DEG_NODE_TYPE_CACHE; } - return DEG::DEPSNODE_TYPE_UNDEFINED; + return DEG::DEG_NODE_TYPE_UNDEFINED; } static DEG::DepsNodeHandle *get_handle(DepsNodeHandle *handle) @@ -121,7 +120,6 @@ void DEG_add_scene_relation(DepsNodeHandle *handle, DEG::DepsNodeHandle *deg_handle = get_handle(handle); deg_handle->builder->add_node_handle_relation(comp_key, deg_handle, - DEG::DEPSREL_TYPE_GEOMETRY_EVAL, description); } @@ -135,7 +133,6 @@ void DEG_add_object_relation(DepsNodeHandle *handle, DEG::DepsNodeHandle *deg_handle = get_handle(handle); deg_handle->builder->add_node_handle_relation(comp_key, deg_handle, - DEG::DEPSREL_TYPE_GEOMETRY_EVAL, description); } @@ -149,7 +146,6 @@ void DEG_add_object_cache_relation(DepsNodeHandle *handle, DEG::DepsNodeHandle *deg_handle = get_handle(handle); deg_handle->builder->add_node_handle_relation(comp_key, deg_handle, - DEG::DEPSREL_TYPE_CACHE, description); } @@ -167,10 +163,16 @@ void DEG_add_bone_relation(DepsNodeHandle *handle, */ deg_handle->builder->add_node_handle_relation(comp_key, deg_handle, - DEG::DEPSREL_TYPE_GEOMETRY_EVAL, description); } +struct Depsgraph *DEG_get_graph_from_handle(struct DepsNodeHandle *handle) +{ + DEG::DepsNodeHandle *deg_handle = get_handle(handle); + DEG::DepsgraphRelationBuilder *relation_builder = deg_handle->builder; + return reinterpret_cast<Depsgraph *>(relation_builder->getGraph()); +} + void DEG_add_special_eval_flag(Depsgraph *graph, ID *id, short flag) { DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph); @@ -205,30 +207,14 @@ void DEG_graph_build_from_scene(Depsgraph *graph, Main *bmain, Scene *scene) /* 1) Generate all the nodes in the graph first */ DEG::DepsgraphNodeBuilder node_builder(bmain, deg_graph); - /* create root node for scene first - * - this way it should be the first in the graph, - * reflecting its role as the entrypoint - */ node_builder.begin_build(bmain); - node_builder.add_root_node(); node_builder.build_scene(bmain, scene); /* 2) Hook up relationships between operations - to determine evaluation * order. */ DEG::DepsgraphRelationBuilder relation_builder(deg_graph); - /* Hook scene up to the root node as entrypoint to graph. */ - /* XXX what does this relation actually mean? - * it doesnt add any operations anyway and is not clear what part of the - * scene is to be connected. - */ relation_builder.begin_build(bmain); -#if 0 - relation_builder.add_relation(RootKey(), - IDKey(scene), - DEPSREL_TYPE_ROOT_TO_ACTIVE, - "Root to Active Scene"); -#endif relation_builder.build_scene(bmain, scene); /* Detect and solve cycles. */ diff --git a/source/blender/depsgraph/intern/depsgraph_debug.cc b/source/blender/depsgraph/intern/depsgraph_debug.cc index d3b48930779..388b692d742 100644 --- a/source/blender/depsgraph/intern/depsgraph_debug.cc +++ b/source/blender/depsgraph/intern/depsgraph_debug.cc @@ -35,11 +35,11 @@ extern "C" { #include "DNA_scene_types.h" +} /* extern "C" */ #include "DEG_depsgraph.h" #include "DEG_depsgraph_debug.h" #include "DEG_depsgraph_build.h" -} /* extern "C" */ #include "intern/eval/deg_eval_debug.h" #include "intern/depsgraph_intern.h" @@ -165,7 +165,7 @@ bool DEG_debug_consistency_check(Depsgraph *graph) return false; } foreach (DEG::DepsRelation *rel, node->outlinks) { - if (rel->to->type == DEG::DEPSNODE_TYPE_OPERATION) { + if (rel->to->type == DEG::DEG_NODE_TYPE_OPERATION) { DEG::OperationDepsNode *to = (DEG::OperationDepsNode *)rel->to; BLI_assert(to->num_links_pending < to->inlinks.size()); ++to->num_links_pending; @@ -177,7 +177,7 @@ bool DEG_debug_consistency_check(Depsgraph *graph) foreach (DEG::OperationDepsNode *node, deg_graph->operations) { int num_links_pending = 0; foreach (DEG::DepsRelation *rel, node->inlinks) { - if (rel->from->type == DEG::DEPSNODE_TYPE_OPERATION) { + if (rel->from->type == DEG::DEG_NODE_TYPE_OPERATION) { ++num_links_pending; } } @@ -232,7 +232,7 @@ void DEG_stats_simple(const Depsgraph *graph, size_t *r_outer, } GHASH_FOREACH_END(); - DEG::TimeSourceDepsNode *time_source = deg_graph->find_time_source(NULL); + DEG::TimeSourceDepsNode *time_source = deg_graph->find_time_source(); if (time_source != NULL) { tot_rels += time_source->inlinks.size(); } diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cc b/source/blender/depsgraph/intern/depsgraph_eval.cc index c41f28b07e8..85a0d336d28 100644 --- a/source/blender/depsgraph/intern/depsgraph_eval.cc +++ b/source/blender/depsgraph/intern/depsgraph_eval.cc @@ -32,17 +32,17 @@ #include "MEM_guardedalloc.h" -extern "C" { -#include "DNA_scene_types.h" - #include "BLI_utildefines.h" #include "BLI_ghash.h" +extern "C" { +#include "DNA_scene_types.h" + #include "BKE_depsgraph.h" #include "BKE_scene.h" +} /* extern "C" */ #include "DEG_depsgraph.h" -} /* extern "C" */ #include "intern/eval/deg_eval.h" #include "intern/eval/deg_eval_flush.h" diff --git a/source/blender/depsgraph/intern/depsgraph_query.cc b/source/blender/depsgraph/intern/depsgraph_query.cc index 7f2f6a65f5e..e58a7a32407 100644 --- a/source/blender/depsgraph/intern/depsgraph_query.cc +++ b/source/blender/depsgraph/intern/depsgraph_query.cc @@ -35,9 +35,9 @@ extern "C" { #include "BKE_idcode.h" #include "BKE_main.h" +} /* extern "C" */ #include "DEG_depsgraph_query.h" -} /* extern "C" */ #include "intern/depsgraph_intern.h" diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc index 8c4c0b8c8a5..31b4bbc7950 100644 --- a/source/blender/depsgraph/intern/depsgraph_tag.cc +++ b/source/blender/depsgraph/intern/depsgraph_tag.cc @@ -34,16 +34,16 @@ #include <cstring> /* required for memset */ #include <queue> -extern "C" { #include "BLI_utildefines.h" +#include "BLI_task.h" +#include "BLI_listbase.h" +extern "C" { #include "DNA_object_types.h" #include "DNA_particle_types.h" #include "DNA_screen_types.h" #include "DNA_windowmanager_types.h" -#include "BLI_task.h" -#include "BLI_listbase.h" #include "BKE_idcode.h" #include "BKE_library.h" @@ -53,9 +53,9 @@ extern "C" { #define new new_ #include "BKE_screen.h" #undef new +} /* extern "C" */ #include "DEG_depsgraph.h" -} /* extern "C" */ #include "intern/builder/deg_builder.h" #include "intern/eval/deg_eval_flush.h" @@ -337,7 +337,7 @@ void DEG_graph_on_visible_update(Main *bmain, Scene *scene) { id_node->tag_update(graph); DEG::ComponentDepsNode *anim_comp = - id_node->find_component(DEG::DEPSNODE_TYPE_ANIMATION); + id_node->find_component(DEG::DEG_NODE_TYPE_ANIMATION); if (anim_comp != NULL && object->recalc & OB_RECALC_TIME) { anim_comp->tag_update(graph); } diff --git a/source/blender/depsgraph/intern/depsgraph_type_defines.cc b/source/blender/depsgraph/intern/depsgraph_type_defines.cc index 39c189629f2..77454cd85ec 100644 --- a/source/blender/depsgraph/intern/depsgraph_type_defines.cc +++ b/source/blender/depsgraph/intern/depsgraph_type_defines.cc @@ -32,12 +32,11 @@ #include <cstdlib> // for BLI_assert() -extern "C" { + #include "BLI_utildefines.h" #include "BLI_ghash.h" #include "DEG_depsgraph.h" -} /* extern "C" */ #include "intern/nodes/deg_node.h" #include "intern/nodes/deg_node_component.h" @@ -98,23 +97,17 @@ static const char *stringify_opcode(eDepsOperation_Code opcode) #define STRINGIFY_OPCODE(name) case DEG_OPCODE_##name: return #name STRINGIFY_OPCODE(OPERATION); STRINGIFY_OPCODE(PLACEHOLDER); - STRINGIFY_OPCODE(NOOP); STRINGIFY_OPCODE(ANIMATION); STRINGIFY_OPCODE(DRIVER); - //STRINGIFY_OPCODE(PROXY); STRINGIFY_OPCODE(TRANSFORM_LOCAL); STRINGIFY_OPCODE(TRANSFORM_PARENT); STRINGIFY_OPCODE(TRANSFORM_CONSTRAINTS); - //STRINGIFY_OPCODE(TRANSFORM_CONSTRAINTS_INIT); - //STRINGIFY_OPCODE(TRANSFORM_CONSTRAINT); - //STRINGIFY_OPCODE(TRANSFORM_CONSTRAINTS_DONE); STRINGIFY_OPCODE(RIGIDBODY_REBUILD); STRINGIFY_OPCODE(RIGIDBODY_SIM); STRINGIFY_OPCODE(TRANSFORM_RIGIDBODY); STRINGIFY_OPCODE(TRANSFORM_FINAL); STRINGIFY_OPCODE(OBJECT_UBEREVAL); STRINGIFY_OPCODE(GEOMETRY_UBEREVAL); - STRINGIFY_OPCODE(GEOMETRY_MODIFIER); STRINGIFY_OPCODE(GEOMETRY_PATH); STRINGIFY_OPCODE(POSE_INIT); STRINGIFY_OPCODE(POSE_DONE); @@ -123,9 +116,6 @@ static const char *stringify_opcode(eDepsOperation_Code opcode) STRINGIFY_OPCODE(BONE_LOCAL); STRINGIFY_OPCODE(BONE_POSE_PARENT); STRINGIFY_OPCODE(BONE_CONSTRAINTS); - //STRINGIFY_OPCODE(BONE_CONSTRAINTS_INIT); - //STRINGIFY_OPCODE(BONE_CONSTRAINT); - //STRINGIFY_OPCODE(BONE_CONSTRAINTS_DONE); STRINGIFY_OPCODE(BONE_READY); STRINGIFY_OPCODE(BONE_DONE); STRINGIFY_OPCODE(PSYS_EVAL); diff --git a/source/blender/depsgraph/intern/depsgraph_types.h b/source/blender/depsgraph/intern/depsgraph_types.h index c9c4329769d..c1a42941a7d 100644 --- a/source/blender/depsgraph/intern/depsgraph_types.h +++ b/source/blender/depsgraph/intern/depsgraph_types.h @@ -67,74 +67,66 @@ typedef enum eDepsNode_Class { /* Types generally unassociated with user-visible entities, * but needed for graph functioning. */ - DEPSNODE_CLASS_GENERIC = 0, + DEG_NODE_CLASS_GENERIC = 0, /* [Outer Node] An "aspect" of evaluating/updating an ID-Block, requiring * certain types of evaluation behavior. */ - DEPSNODE_CLASS_COMPONENT = 1, + DEG_NODE_CLASS_COMPONENT = 1, /* [Inner Node] A glorified function-pointer/callback for scheduling up * evaluation operations for components, subject to relationship * requirements. */ - DEPSNODE_CLASS_OPERATION = 2, + DEG_NODE_CLASS_OPERATION = 2, } eDepsNode_Class; /* Types of Nodes */ typedef enum eDepsNode_Type { /* Fallback type for invalid return value */ - DEPSNODE_TYPE_UNDEFINED = -1, + DEG_NODE_TYPE_UNDEFINED = -1, /* Inner Node (Operation) */ - DEPSNODE_TYPE_OPERATION = 0, + DEG_NODE_TYPE_OPERATION = 0, /* **** Generic Types **** */ - /* "Current Scene" - basically whatever kicks off the evaluation process. */ - DEPSNODE_TYPE_ROOT, /* Time-Source */ - DEPSNODE_TYPE_TIMESOURCE, + DEG_NODE_TYPE_TIMESOURCE, /* ID-Block reference - used as landmarks/collection point for components, * but not usually part of main graph. */ - DEPSNODE_TYPE_ID_REF, - /* Isolated sub-graph - used for keeping instanced data separate from - * instances using them. - */ - DEPSNODE_TYPE_SUBGRAPH, + DEG_NODE_TYPE_ID_REF, /* **** Outer Types **** */ /* Parameters Component - Default when nothing else fits * (i.e. just SDNA property setting). */ - DEPSNODE_TYPE_PARAMETERS, - /* Generic "Proxy-Inherit" Component - * XXX: Also for instancing of subgraphs? - */ - DEPSNODE_TYPE_PROXY, + DEG_NODE_TYPE_PARAMETERS, + /* Generic "Proxy-Inherit" Component. */ + DEG_NODE_TYPE_PROXY, /* Animation Component * * XXX: merge in with parameters? */ - DEPSNODE_TYPE_ANIMATION, + DEG_NODE_TYPE_ANIMATION, /* Transform Component (Parenting/Constraints) */ - DEPSNODE_TYPE_TRANSFORM, + DEG_NODE_TYPE_TRANSFORM, /* Geometry Component (DerivedMesh/Displist) */ - DEPSNODE_TYPE_GEOMETRY, + DEG_NODE_TYPE_GEOMETRY, /* Sequencer Component (Scene Only) */ - DEPSNODE_TYPE_SEQUENCER, + DEG_NODE_TYPE_SEQUENCER, /* **** Evaluation-Related Outer Types (with Subdata) **** */ /* Pose Component - Owner/Container of Bones Eval */ - DEPSNODE_TYPE_EVAL_POSE, + DEG_NODE_TYPE_EVAL_POSE, /* Bone Component - Child/Subcomponent of Pose */ - DEPSNODE_TYPE_BONE, + DEG_NODE_TYPE_BONE, /* Particle Systems Component */ - DEPSNODE_TYPE_EVAL_PARTICLES, + DEG_NODE_TYPE_EVAL_PARTICLES, /* Material Shading Component */ - DEPSNODE_TYPE_SHADING, + DEG_NODE_TYPE_SHADING, /* Cache Component */ - DEPSNODE_TYPE_CACHE, + DEG_NODE_TYPE_CACHE, } eDepsNode_Type; /* Identifiers for common operations (as an enum). */ @@ -147,8 +139,6 @@ typedef enum eDepsOperation_Code { // XXX: Placeholder while porting depsgraph code DEG_OPCODE_PLACEHOLDER, - DEG_OPCODE_NOOP, - /* Animation, Drivers, etc. ------------------------ */ /* NLA + Action */ @@ -157,9 +147,6 @@ typedef enum eDepsOperation_Code { /* Driver */ DEG_OPCODE_DRIVER, - /* Proxy Inherit? */ - //DEG_OPCODE_PROXY, - /* Transform --------------------------------------- */ /* Transform entry point - local transforms only */ @@ -170,9 +157,6 @@ typedef enum eDepsOperation_Code { /* Constraints */ DEG_OPCODE_TRANSFORM_CONSTRAINTS, - //DEG_OPCODE_TRANSFORM_CONSTRAINTS_INIT, - //DEG_OPCODE_TRANSFORM_CONSTRAINT, - //DEG_OPCODE_TRANSFORM_CONSTRAINTS_DONE, /* Rigidbody Sim - Perform Sim */ DEG_OPCODE_RIGIDBODY_REBUILD, @@ -192,9 +176,6 @@ typedef enum eDepsOperation_Code { /* XXX: Placeholder - UberEval */ DEG_OPCODE_GEOMETRY_UBEREVAL, - /* Modifier */ - DEG_OPCODE_GEOMETRY_MODIFIER, - /* Curve Objects - Path Calculation (used for path-following tools, */ DEG_OPCODE_GEOMETRY_PATH, @@ -220,9 +201,6 @@ typedef enum eDepsOperation_Code { /* Constraints */ DEG_OPCODE_BONE_CONSTRAINTS, - //DEG_OPCODE_BONE_CONSTRAINTS_INIT, - //DEG_OPCODE_BONE_CONSTRAINT, - //DEG_OPCODE_BONE_CONSTRAINTS_DONE, /* Bone transforms are ready * @@ -258,83 +236,4 @@ protected: /* String defines for these opcodes, defined in depsgraph_type_defines.cpp */ extern DepsOperationStringifier DEG_OPNAMES; -/* Type of operation */ -typedef enum eDepsOperation_Type { - /* **** Primary operation types **** */ - - /* Initialise evaluation data */ - DEPSOP_TYPE_INIT = 0, - /* Standard evaluation step */ - DEPSOP_TYPE_EXEC = 1, - /* Cleanup evaluation data + flush results */ - DEPSOP_TYPE_POST = 2, - - /* **** Additional operation types **** */ - /* Indicator for outputting a temporary result that other components - * can use. // XXX? - */ - DEPSOP_TYPE_OUT = 3, - /* Indicator for things like IK Solvers and Rigidbody Sim steps which - * modify final results of separate entities at once. - */ - DEPSOP_TYPE_SIM = 4, - /* Rebuild internal evaluation data - used for Rigidbody Reset and - * Armature Rebuild-On-Load. - */ - DEPSOP_TYPE_REBUILD = 5, -} eDepsOperation_Type; - -/* Types of relationships between nodes - * - * This is used to provide additional hints to use when filtering - * the graph, so that we can go without doing more extensive - * data-level checks... - */ -typedef enum eDepsRelation_Type { - /* relationship type unknown/irrelevant */ - DEPSREL_TYPE_STANDARD = 0, - - /* root -> active scene or entity (screen, image, etc.) */ - DEPSREL_TYPE_ROOT_TO_ACTIVE, - - /* general datablock dependency */ - DEPSREL_TYPE_DATABLOCK, - - /* time dependency */ - DEPSREL_TYPE_TIME, - - /* component depends on results of another */ - DEPSREL_TYPE_COMPONENT_ORDER, - - /* relationship is just used to enforce ordering of operations - * (e.g. "init()" callback done before "exec() and "cleanup()") - */ - DEPSREL_TYPE_OPERATION, - - /* relationship results from a property driver affecting property */ - DEPSREL_TYPE_DRIVER, - - /* relationship is something driver depends on */ - DEPSREL_TYPE_DRIVER_TARGET, - - /* relationship is used for transform stack - * (e.g. parenting, user transforms, constraints) - */ - DEPSREL_TYPE_TRANSFORM, - - /* relationship is used for geometry evaluation - * (e.g. metaball "motherball" or modifiers) - */ - DEPSREL_TYPE_GEOMETRY_EVAL, - - /* relationship is used to trigger a post-change validity updates */ - DEPSREL_TYPE_UPDATE, - - /* relationship is used to trigger editor/screen updates */ - DEPSREL_TYPE_UPDATE_UI, - - /* cache dependency */ - DEPSREL_TYPE_CACHE, -} eDepsRelation_Type; - } // namespace DEG diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc index e739bc9dbb5..98b10718404 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval.cc @@ -34,16 +34,16 @@ #include "PIL_time.h" -extern "C" { #include "BLI_utildefines.h" #include "BLI_task.h" #include "BLI_ghash.h" +extern "C" { #include "BKE_depsgraph.h" #include "BKE_global.h" +} /* extern "C" */ #include "DEG_depsgraph.h" -} /* extern "C" */ #include "atomic_ops.h" @@ -126,7 +126,9 @@ static void deg_task_run_func(TaskPool *pool, #endif } + BLI_task_pool_delayed_push_begin(pool, thread_id); schedule_children(pool, state->graph, node, state->layers, thread_id); + BLI_task_pool_delayed_push_end(pool, thread_id); } typedef struct CalculatePengindData { @@ -150,7 +152,7 @@ static void calculate_pending_func(void *data_v, int i) (node->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0) { foreach (DepsRelation *rel, node->inlinks) { - if (rel->from->type == DEPSNODE_TYPE_OPERATION && + if (rel->from->type == DEG_NODE_TYPE_OPERATION && (rel->flag & DEPSREL_FLAG_CYCLIC) == 0) { OperationDepsNode *from = (OperationDepsNode *)rel->from; @@ -195,7 +197,7 @@ static void calculate_eval_priority(OperationDepsNode *node) foreach (DepsRelation *rel, node->outlinks) { OperationDepsNode *to = (OperationDepsNode *)rel->to; - BLI_assert(to->type == DEPSNODE_TYPE_OPERATION); + BLI_assert(to->type == DEG_NODE_TYPE_OPERATION); calculate_eval_priority(to); node->eval_priority += to->eval_priority; } @@ -263,7 +265,7 @@ static void schedule_children(TaskPool *pool, { foreach (DepsRelation *rel, node->outlinks) { OperationDepsNode *child = (OperationDepsNode *)rel->to; - BLI_assert(child->type == DEPSNODE_TYPE_OPERATION); + BLI_assert(child->type == DEG_NODE_TYPE_OPERATION); if (child->scheduled) { /* Happens when having cyclic dependencies. */ continue; diff --git a/source/blender/depsgraph/intern/eval/deg_eval_debug.cc b/source/blender/depsgraph/intern/eval/deg_eval_debug.cc index 060544a4407..23f4adbaacd 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_debug.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_debug.cc @@ -34,16 +34,16 @@ #include <cstring> /* required for STREQ later on. */ -extern "C" { #include "BLI_listbase.h" #include "BLI_ghash.h" -#include "DEG_depsgraph_debug.h" - +extern "C" { #include "WM_api.h" #include "WM_types.h" } /* extern "C" */ +#include "DEG_depsgraph_debug.h" + #include "intern/nodes/deg_node.h" #include "intern/nodes/deg_node_component.h" #include "intern/nodes/deg_node_operation.h" diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc index d64fdd83d39..c230ab4c8fd 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc @@ -35,16 +35,16 @@ // TODO(sergey): Use some sort of wrapper. #include <deque> -extern "C" { -#include "DNA_object_types.h" - #include "BLI_utildefines.h" #include "BLI_task.h" #include "BLI_ghash.h" -#include "DEG_depsgraph.h" +extern "C" { +#include "DNA_object_types.h" } /* extern "C" */ +#include "DEG_depsgraph.h" + #include "intern/nodes/deg_node.h" #include "intern/nodes/deg_node_component.h" #include "intern/nodes/deg_node_operation.h" @@ -139,18 +139,18 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph) IDDepsNode *id_node = comp_node->owner; ID *id = id_node->id; - if(id_node->done == 0) { + if (id_node->done == 0) { deg_editors_id_update(bmain, id); lib_id_recalc_tag(bmain, id); /* TODO(sergey): For until we've got proper data nodes in the graph. */ lib_id_recalc_data_tag(bmain, id); } - if(comp_node->done == 0) { + if (comp_node->done == 0) { Object *object = NULL; if (GS(id->name) == ID_OB) { object = (Object *)id; - if(id_node->done == 0) { + if (id_node->done == 0) { ++num_flushed_objects; } } @@ -165,29 +165,27 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph) * layers visibility update has proper flags to work with. */ switch (comp_node->type) { - case DEPSNODE_TYPE_UNDEFINED: - case DEPSNODE_TYPE_OPERATION: - case DEPSNODE_TYPE_ROOT: - case DEPSNODE_TYPE_TIMESOURCE: - case DEPSNODE_TYPE_ID_REF: - case DEPSNODE_TYPE_SUBGRAPH: - case DEPSNODE_TYPE_PARAMETERS: - case DEPSNODE_TYPE_SEQUENCER: + case DEG_NODE_TYPE_UNDEFINED: + case DEG_NODE_TYPE_OPERATION: + case DEG_NODE_TYPE_TIMESOURCE: + case DEG_NODE_TYPE_ID_REF: + case DEG_NODE_TYPE_PARAMETERS: + case DEG_NODE_TYPE_SEQUENCER: /* Ignore, does not translate to object component. */ break; - case DEPSNODE_TYPE_ANIMATION: + case DEG_NODE_TYPE_ANIMATION: object->recalc |= OB_RECALC_TIME; break; - case DEPSNODE_TYPE_TRANSFORM: + case DEG_NODE_TYPE_TRANSFORM: object->recalc |= OB_RECALC_OB; break; - case DEPSNODE_TYPE_GEOMETRY: - case DEPSNODE_TYPE_EVAL_POSE: - case DEPSNODE_TYPE_BONE: - case DEPSNODE_TYPE_EVAL_PARTICLES: - case DEPSNODE_TYPE_SHADING: - case DEPSNODE_TYPE_CACHE: - case DEPSNODE_TYPE_PROXY: + case DEG_NODE_TYPE_GEOMETRY: + case DEG_NODE_TYPE_EVAL_POSE: + case DEG_NODE_TYPE_BONE: + case DEG_NODE_TYPE_EVAL_PARTICLES: + case DEG_NODE_TYPE_SHADING: + case DEG_NODE_TYPE_CACHE: + case DEG_NODE_TYPE_PROXY: object->recalc |= OB_RECALC_DATA; break; } diff --git a/source/blender/depsgraph/intern/nodes/deg_node.cc b/source/blender/depsgraph/intern/nodes/deg_node.cc index b1d5b538e25..a15317586c1 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node.cc @@ -41,9 +41,9 @@ extern "C" { #include "DNA_anim_types.h" #include "BKE_animsys.h" +} #include "DEG_depsgraph.h" -} #include "intern/nodes/deg_node_component.h" #include "intern/nodes/deg_node_operation.h" @@ -60,12 +60,12 @@ namespace DEG { DepsNode::TypeInfo::TypeInfo(eDepsNode_Type type, const char *tname) { this->type = type; - if (type == DEPSNODE_TYPE_OPERATION) - this->tclass = DEPSNODE_CLASS_OPERATION; - else if (type < DEPSNODE_TYPE_PARAMETERS) - this->tclass = DEPSNODE_CLASS_GENERIC; + if (type == DEG_NODE_TYPE_OPERATION) + this->tclass = DEG_NODE_CLASS_OPERATION; + else if (type < DEG_NODE_TYPE_PARAMETERS) + this->tclass = DEG_NODE_CLASS_GENERIC; else - this->tclass = DEPSNODE_CLASS_COMPONENT; + this->tclass = DEG_NODE_CLASS_COMPONENT; this->tname = tname; } @@ -109,34 +109,9 @@ void TimeSourceDepsNode::tag_update(Depsgraph *graph) } } - -/* Root Node ============================================== */ - -RootDepsNode::RootDepsNode() : scene(NULL), time_source(NULL) -{ -} - -RootDepsNode::~RootDepsNode() -{ - OBJECT_GUARDED_DELETE(time_source, TimeSourceDepsNode); -} - -TimeSourceDepsNode *RootDepsNode::add_time_source(const char *name) -{ - if (!time_source) { - DepsNodeFactory *factory = deg_get_node_factory(DEPSNODE_TYPE_TIMESOURCE); - time_source = (TimeSourceDepsNode *)factory->create_node(NULL, "", name); - /*time_source->owner = this;*/ // XXX - } - return time_source; -} - -DEG_DEPSNODE_DEFINE(RootDepsNode, DEPSNODE_TYPE_ROOT, "Root DepsNode"); -static DepsNodeFactoryImpl<RootDepsNode> DNTI_ROOT; - /* Time Source Node ======================================= */ -DEG_DEPSNODE_DEFINE(TimeSourceDepsNode, DEPSNODE_TYPE_TIMESOURCE, "Time Source"); +DEG_DEPSNODE_DEFINE(TimeSourceDepsNode, DEG_NODE_TYPE_TIMESOURCE, "Time Source"); static DepsNodeFactoryImpl<TimeSourceDepsNode> DNTI_TIMESOURCE; /* ID Node ================================================ */ @@ -210,8 +185,9 @@ void IDDepsNode::init(const ID *id, const char *UNUSED(subdata)) /* Free 'id' node. */ IDDepsNode::~IDDepsNode() { - clear_components(); - BLI_ghash_free(components, id_deps_node_hash_key_free, NULL); + BLI_ghash_free(components, + id_deps_node_hash_key_free, + id_deps_node_hash_value_free); } ComponentDepsNode *IDDepsNode::find_component(eDepsNode_Type type, @@ -237,33 +213,13 @@ ComponentDepsNode *IDDepsNode::add_component(eDepsNode_Type type, return comp_node; } -void IDDepsNode::remove_component(eDepsNode_Type type, const char *name) -{ - ComponentDepsNode *comp_node = find_component(type, name); - if (comp_node) { - /* Unregister. */ - ComponentIDKey key(type, name); - BLI_ghash_remove(components, - &key, - id_deps_node_hash_key_free, - id_deps_node_hash_value_free); - } -} - -void IDDepsNode::clear_components() -{ - BLI_ghash_clear(components, - id_deps_node_hash_key_free, - id_deps_node_hash_value_free); -} - void IDDepsNode::tag_update(Depsgraph *graph) { GHASH_FOREACH_BEGIN(ComponentDepsNode *, comp_node, components) { /* TODO(sergey): What about drievrs? */ - bool do_component_tag = comp_node->type != DEPSNODE_TYPE_ANIMATION; - if (comp_node->type == DEPSNODE_TYPE_ANIMATION) { + bool do_component_tag = comp_node->type != DEG_NODE_TYPE_ANIMATION; + if (comp_node->type == DEG_NODE_TYPE_ANIMATION) { AnimData *adt = BKE_animdata_from_id(id); /* Animation data might be null if relations are tagged for update. */ if (adt != NULL && (adt->recalc & ADT_RECALC_ANIM)) { @@ -286,46 +242,13 @@ void IDDepsNode::finalize_build() GHASH_FOREACH_END(); } -DEG_DEPSNODE_DEFINE(IDDepsNode, DEPSNODE_TYPE_ID_REF, "ID Node"); +DEG_DEPSNODE_DEFINE(IDDepsNode, DEG_NODE_TYPE_ID_REF, "ID Node"); static DepsNodeFactoryImpl<IDDepsNode> DNTI_ID_REF; -/* Subgraph Node ========================================== */ - -/* Initialize 'subgraph' node - from pointer data given. */ -void SubgraphDepsNode::init(const ID *id, const char *UNUSED(subdata)) -{ - /* Store ID-ref if provided. */ - this->root_id = (ID *)id; - - /* NOTE: graph will need to be added manually, - * as we don't have any way of passing this down. - */ -} - -/* Free 'subgraph' node */ -SubgraphDepsNode::~SubgraphDepsNode() -{ - /* Only free if graph not shared, of if this node is the first - * reference to it... - */ - // XXX: prune these flags a bit... - if ((this->flag & SUBGRAPH_FLAG_FIRSTREF) || !(this->flag & SUBGRAPH_FLAG_SHARED)) { - /* Free the referenced graph. */ - DEG_graph_free(reinterpret_cast< ::Depsgraph* >(graph)); - graph = NULL; - } -} - -DEG_DEPSNODE_DEFINE(SubgraphDepsNode, DEPSNODE_TYPE_SUBGRAPH, "Subgraph Node"); -static DepsNodeFactoryImpl<SubgraphDepsNode> DNTI_SUBGRAPH; - void deg_register_base_depsnodes() { - deg_register_node_typeinfo(&DNTI_ROOT); deg_register_node_typeinfo(&DNTI_TIMESOURCE); - deg_register_node_typeinfo(&DNTI_ID_REF); - deg_register_node_typeinfo(&DNTI_SUBGRAPH); } } // namespace DEG diff --git a/source/blender/depsgraph/intern/nodes/deg_node.h b/source/blender/depsgraph/intern/nodes/deg_node.h index 7c2f53840b6..9f1b61faf24 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node.h +++ b/source/blender/depsgraph/intern/nodes/deg_node.h @@ -127,22 +127,6 @@ struct TimeSourceDepsNode : public DepsNode { DEG_DEPSNODE_DECLARE; }; -/* Root Node. */ -struct RootDepsNode : public DepsNode { - RootDepsNode(); - ~RootDepsNode(); - - TimeSourceDepsNode *add_time_source(const char *name = ""); - - /* scene that this corresponds to */ - Scene *scene; - - /* Entrypoint node for time-changed. */ - TimeSourceDepsNode *time_source; - - DEG_DEPSNODE_DECLARE; -}; - /* ID-Block Reference */ struct IDDepsNode : public DepsNode { struct ComponentIDKey { @@ -160,8 +144,6 @@ struct IDDepsNode : public DepsNode { const char *name = "") const; ComponentDepsNode *add_component(eDepsNode_Type type, const char *name = ""); - void remove_component(eDepsNode_Type type, const char *name = ""); - void clear_components(); void tag_update(Depsgraph *graph); @@ -185,41 +167,6 @@ struct IDDepsNode : public DepsNode { DEG_DEPSNODE_DECLARE; }; -/* Subgraph Reference. */ -struct SubgraphDepsNode : public DepsNode { - void init(const ID *id, const char *subdata); - ~SubgraphDepsNode(); - - /* Instanced graph. */ - Depsgraph *graph; - - /* ID-block at root of subgraph (if applicable). */ - ID *root_id; - - /* Number of nodes which use/reference this subgraph - if just 1, it may be - * possible to merge into main, - */ - size_t num_users; - - /* (eSubgraphRef_Flag) assorted settings for subgraph node. */ - int flag; - - DEG_DEPSNODE_DECLARE; -}; - -/* Flags for subgraph node */ -typedef enum eSubgraphRef_Flag { - /* Subgraph referenced is shared with another reference, so shouldn't - * free on exit. - */ - SUBGRAPH_FLAG_SHARED = (1 << 0), - - /* Node is first reference to subgraph, so it can be freed when we are - * removed. - */ - SUBGRAPH_FLAG_FIRSTREF = (1 << 1), -} eSubgraphRef_Flag; - void deg_register_base_depsnodes(); } // namespace DEG diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.cc b/source/blender/depsgraph/intern/nodes/deg_node_component.cc index 136c66b9516..e87c87813e3 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_component.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node_component.cc @@ -33,10 +33,10 @@ #include <stdio.h> #include <cstring> /* required for STREQ later on. */ -extern "C" { #include "BLI_utildefines.h" #include "BLI_ghash.h" +extern "C" { #include "DNA_object_types.h" #include "BKE_action.h" @@ -198,32 +198,20 @@ OperationDepsNode *ComponentDepsNode::has_operation(eDepsOperation_Code opcode, return has_operation(key); } -OperationDepsNode *ComponentDepsNode::add_operation(eDepsOperation_Type optype, - DepsEvalOperationCb op, +OperationDepsNode *ComponentDepsNode::add_operation(const DepsEvalOperationCb& op, eDepsOperation_Code opcode, const char *name, int name_tag) { OperationDepsNode *op_node = has_operation(opcode, name, name_tag); if (!op_node) { - DepsNodeFactory *factory = deg_get_node_factory(DEPSNODE_TYPE_OPERATION); + DepsNodeFactory *factory = deg_get_node_factory(DEG_NODE_TYPE_OPERATION); op_node = (OperationDepsNode *)factory->create_node(this->owner->id, "", name); /* register opnode in this component's operation set */ OperationIDKey *key = OBJECT_GUARDED_NEW(OperationIDKey, opcode, name, name_tag); BLI_ghash_insert(operations_map, key, op_node); - /* set as entry/exit node of component (if appropriate) */ - if (optype == DEPSOP_TYPE_INIT) { - BLI_assert(this->entry_operation == NULL); - this->entry_operation = op_node; - } - else if (optype == DEPSOP_TYPE_POST) { - // XXX: review whether DEPSOP_TYPE_OUT is better than DEPSOP_TYPE_POST, or maybe have both? - BLI_assert(this->exit_operation == NULL); - this->exit_operation = op_node; - } - /* set backlink */ op_node->owner = this; } @@ -235,13 +223,24 @@ OperationDepsNode *ComponentDepsNode::add_operation(eDepsOperation_Type optype, /* attach extra data */ op_node->evaluate = op; - op_node->optype = optype; op_node->opcode = opcode; op_node->name = name; return op_node; } +void ComponentDepsNode::set_entry_operation(OperationDepsNode *op_node) +{ + BLI_assert(entry_operation == NULL); + entry_operation = op_node; +} + +void ComponentDepsNode::set_exit_operation(OperationDepsNode *op_node) +{ + BLI_assert(exit_operation == NULL); + exit_operation = op_node; +} + void ComponentDepsNode::clear_operations() { if (operations_map != NULL) { @@ -336,37 +335,37 @@ void ComponentDepsNode::finalize_build() /* Parameter Component Defines ============================ */ -DEG_DEPSNODE_DEFINE(ParametersComponentDepsNode, DEPSNODE_TYPE_PARAMETERS, "Parameters Component"); +DEG_DEPSNODE_DEFINE(ParametersComponentDepsNode, DEG_NODE_TYPE_PARAMETERS, "Parameters Component"); static DepsNodeFactoryImpl<ParametersComponentDepsNode> DNTI_PARAMETERS; /* Animation Component Defines ============================ */ -DEG_DEPSNODE_DEFINE(AnimationComponentDepsNode, DEPSNODE_TYPE_ANIMATION, "Animation Component"); +DEG_DEPSNODE_DEFINE(AnimationComponentDepsNode, DEG_NODE_TYPE_ANIMATION, "Animation Component"); static DepsNodeFactoryImpl<AnimationComponentDepsNode> DNTI_ANIMATION; /* Transform Component Defines ============================ */ -DEG_DEPSNODE_DEFINE(TransformComponentDepsNode, DEPSNODE_TYPE_TRANSFORM, "Transform Component"); +DEG_DEPSNODE_DEFINE(TransformComponentDepsNode, DEG_NODE_TYPE_TRANSFORM, "Transform Component"); static DepsNodeFactoryImpl<TransformComponentDepsNode> DNTI_TRANSFORM; /* Proxy Component Defines ================================ */ -DEG_DEPSNODE_DEFINE(ProxyComponentDepsNode, DEPSNODE_TYPE_PROXY, "Proxy Component"); +DEG_DEPSNODE_DEFINE(ProxyComponentDepsNode, DEG_NODE_TYPE_PROXY, "Proxy Component"); static DepsNodeFactoryImpl<ProxyComponentDepsNode> DNTI_PROXY; /* Geometry Component Defines ============================= */ -DEG_DEPSNODE_DEFINE(GeometryComponentDepsNode, DEPSNODE_TYPE_GEOMETRY, "Geometry Component"); +DEG_DEPSNODE_DEFINE(GeometryComponentDepsNode, DEG_NODE_TYPE_GEOMETRY, "Geometry Component"); static DepsNodeFactoryImpl<GeometryComponentDepsNode> DNTI_GEOMETRY; /* Sequencer Component Defines ============================ */ -DEG_DEPSNODE_DEFINE(SequencerComponentDepsNode, DEPSNODE_TYPE_SEQUENCER, "Sequencer Component"); +DEG_DEPSNODE_DEFINE(SequencerComponentDepsNode, DEG_NODE_TYPE_SEQUENCER, "Sequencer Component"); static DepsNodeFactoryImpl<SequencerComponentDepsNode> DNTI_SEQUENCER; /* Pose Component ========================================= */ -DEG_DEPSNODE_DEFINE(PoseComponentDepsNode, DEPSNODE_TYPE_EVAL_POSE, "Pose Eval Component"); +DEG_DEPSNODE_DEFINE(PoseComponentDepsNode, DEG_NODE_TYPE_EVAL_POSE, "Pose Eval Component"); static DepsNodeFactoryImpl<PoseComponentDepsNode> DNTI_EVAL_POSE; /* Bone Component ========================================= */ @@ -388,22 +387,22 @@ void BoneComponentDepsNode::init(const ID *id, const char *subdata) this->pchan = BKE_pose_channel_find_name(ob->pose, subdata); } -DEG_DEPSNODE_DEFINE(BoneComponentDepsNode, DEPSNODE_TYPE_BONE, "Bone Component"); +DEG_DEPSNODE_DEFINE(BoneComponentDepsNode, DEG_NODE_TYPE_BONE, "Bone Component"); static DepsNodeFactoryImpl<BoneComponentDepsNode> DNTI_BONE; /* Particles Component Defines ============================ */ -DEG_DEPSNODE_DEFINE(ParticlesComponentDepsNode, DEPSNODE_TYPE_EVAL_PARTICLES, "Particles Component"); +DEG_DEPSNODE_DEFINE(ParticlesComponentDepsNode, DEG_NODE_TYPE_EVAL_PARTICLES, "Particles Component"); static DepsNodeFactoryImpl<ParticlesComponentDepsNode> DNTI_EVAL_PARTICLES; /* Shading Component Defines ============================ */ -DEG_DEPSNODE_DEFINE(ShadingComponentDepsNode, DEPSNODE_TYPE_SHADING, "Shading Component"); +DEG_DEPSNODE_DEFINE(ShadingComponentDepsNode, DEG_NODE_TYPE_SHADING, "Shading Component"); static DepsNodeFactoryImpl<ShadingComponentDepsNode> DNTI_SHADING; /* Cache Component Defines ============================ */ -DEG_DEPSNODE_DEFINE(CacheComponentDepsNode, DEPSNODE_TYPE_CACHE, "Cache Component"); +DEG_DEPSNODE_DEFINE(CacheComponentDepsNode, DEG_NODE_TYPE_CACHE, "Cache Component"); static DepsNodeFactoryImpl<CacheComponentDepsNode> DNTI_CACHE; diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.h b/source/blender/depsgraph/intern/nodes/deg_node_component.h index 969771a29c9..4ef7dad3ac6 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_component.h +++ b/source/blender/depsgraph/intern/nodes/deg_node_component.h @@ -99,12 +99,18 @@ struct ComponentDepsNode : public DepsNode { * \param op: The operation to perform * \param name: Identifier for operation - used to find/locate it again */ - OperationDepsNode *add_operation(eDepsOperation_Type optype, - DepsEvalOperationCb op, + OperationDepsNode *add_operation(const DepsEvalOperationCb& op, eDepsOperation_Code opcode, const char *name, int name_tag); + /* Entry/exit operations management. + * + * Use those instead of direct set since this will perform sanity checks. + */ + void set_entry_operation(OperationDepsNode *op_node); + void set_exit_operation(OperationDepsNode *op_node); + void clear_operations(); void tag_update(Depsgraph *graph); diff --git a/source/blender/depsgraph/intern/nodes/deg_node_operation.cc b/source/blender/depsgraph/intern/nodes/deg_node_operation.cc index cbf397bc7a9..7467264f612 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_operation.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node_operation.cc @@ -65,7 +65,7 @@ string OperationDepsNode::identifier() const string OperationDepsNode::full_identifier() const { string owner_str = ""; - if (owner->type == DEPSNODE_TYPE_BONE) { + if (owner->type == DEG_NODE_TYPE_BONE) { owner_str = string(owner->owner->name) + "." + owner->name; } else { @@ -84,7 +84,19 @@ void OperationDepsNode::tag_update(Depsgraph *graph) graph->add_entry_tag(this); } -DEG_DEPSNODE_DEFINE(OperationDepsNode, DEPSNODE_TYPE_OPERATION, "Operation"); +void OperationDepsNode::set_as_entry() +{ + BLI_assert(owner != NULL); + owner->set_entry_operation(this); +} + +void OperationDepsNode::set_as_exit() +{ + BLI_assert(owner != NULL); + owner->set_exit_operation(this); +} + +DEG_DEPSNODE_DEFINE(OperationDepsNode, DEG_NODE_TYPE_OPERATION, "Operation"); static DepsNodeFactoryImpl<OperationDepsNode> DNTI_OPERATION; void deg_register_operation_depsnodes() diff --git a/source/blender/depsgraph/intern/nodes/deg_node_operation.h b/source/blender/depsgraph/intern/nodes/deg_node_operation.h index 598393054db..1e5c3832d03 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_operation.h +++ b/source/blender/depsgraph/intern/nodes/deg_node_operation.h @@ -44,9 +44,6 @@ typedef enum eDepsOperation_Flag { DEPSOP_FLAG_NEEDS_UPDATE = (1 << 0), /* node was directly modified, causing need for update */ - /* XXX: intention is to make it easier to tell when we just need to - * take subgraphs. - */ DEPSOP_FLAG_DIRECTLY_MODIFIED = (1 << 1), /* Operation is evaluated using CPython; has GIL and security @@ -57,8 +54,6 @@ typedef enum eDepsOperation_Flag { /* Atomic Operation - Base type for all operations */ struct OperationDepsNode : public DepsNode { - - OperationDepsNode(); ~OperationDepsNode(); @@ -72,21 +67,21 @@ struct OperationDepsNode : public DepsNode { OperationDepsNode *get_entry_operation() { return this; } OperationDepsNode *get_exit_operation() { return this; } + /* Set this operation as compoonent's entry/exit operation. */ + void set_as_entry(); + void set_as_exit(); + /* Component that contains the operation. */ ComponentDepsNode *owner; /* Callback for operation. */ DepsEvalOperationCb evaluate; - /* How many inlinks are we still waiting on before we can be evaluated. */ uint32_t num_links_pending; float eval_priority; bool scheduled; - /* Stage of evaluation */ - eDepsOperation_Type optype; - /* Identifier for the operation being performed. */ eDepsOperation_Code opcode; diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c index 4571df0f077..9d25fc9e1a3 100644 --- a/source/blender/editors/animation/keyframes_edit.c +++ b/source/blender/editors/animation/keyframes_edit.c @@ -452,7 +452,7 @@ void ANIM_editkeyframes_refresh(bAnimContext *ac) ok |= KEYFRAME_OK_H2; \ } \ } (void)0 - + /* ------------------------ */ static short ok_bezier_frame(KeyframeEditData *ked, BezTriple *bezt) diff --git a/source/blender/editors/armature/armature_naming.c b/source/blender/editors/armature/armature_naming.c index c928508237d..db4b642fe91 100644 --- a/source/blender/editors/armature/armature_naming.c +++ b/source/blender/editors/armature/armature_naming.c @@ -311,8 +311,8 @@ typedef struct BoneFlipNameData { * This way if we are flipping related bones (e.g., Bone.L, Bone.R) at the same time * all the bones are safely renamed, without conflicting with each other. * - * \param arm Armature the bones belong to - * \param bones ListBase of BoneConflict elems, populated via ED_armature_bones_flip_names_add + * \param arm: Armature the bones belong to + * \param bones_names: List of BoneConflict elems. */ void ED_armature_bones_flip_names(bArmature *arm, ListBase *bones_names) { diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index a69264cd012..8a366ce6a81 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -4160,7 +4160,7 @@ static int make_segment_exec(bContext *C, wmOperator *op) */ bp = nu->bp; - if (bp[nu->pntsu - 1].f1 & SELECT) { + if (bp[nu->pntsu - 1].f1 & SELECT) { if (nu2 == NULL) { nu2 = nu; } diff --git a/source/blender/editors/gpencil/gpencil_brush.c b/source/blender/editors/gpencil/gpencil_brush.c index 8ddf3a22517..5332bec0c64 100644 --- a/source/blender/editors/gpencil/gpencil_brush.c +++ b/source/blender/editors/gpencil/gpencil_brush.c @@ -773,6 +773,9 @@ typedef struct tGPSB_CloneBrushData { /* for "stamp" mode, the currently pasted brushes */ bGPDstroke **new_strokes; + + /* mapping from colors referenced per stroke, to the new colours in the "pasted" strokes */ + GHash *new_colors; } tGPSB_CloneBrushData; /* Initialise "clone" brush data */ @@ -816,6 +819,11 @@ static void gp_brush_clone_init(bContext *C, tGP_BrushEditData *gso) if (1 /*gso->brush->mode == GP_EDITBRUSH_CLONE_MODE_STAMP*/) { data->new_strokes = MEM_callocN(sizeof(bGPDstroke *) * data->totitems, "cloned strokes ptr array"); } + + /* Init colormap for mapping between the pasted stroke's source colour(names) + * and the final colours that will be used here instead... + */ + data->new_colors = gp_copybuf_validate_colormap(gso->gpd); } /* Free custom data used for "clone" brush */ @@ -829,6 +837,12 @@ static void gp_brush_clone_free(tGP_BrushEditData *gso) data->new_strokes = NULL; } + /* free copybuf colormap */ + if (data->new_colors) { + BLI_ghash_free(data->new_colors, NULL, NULL); + data->new_colors = NULL; + } + /* free the customdata itself */ MEM_freeN(data); gso->customdata = NULL; @@ -869,6 +883,13 @@ static void gp_brush_clone_add(bContext *C, tGP_BrushEditData *gso) new_stroke->next = new_stroke->prev = NULL; BLI_addtail(&gpf->strokes, new_stroke); + /* Fix color references */ + BLI_assert(new_stroke->colorname[0] != '\0'); + new_stroke->palcolor = BLI_ghash_lookup(data->new_colors, new_stroke->colorname); + + BLI_assert(new_stroke->palcolor != NULL); + BLI_strncpy(new_stroke->colorname, new_stroke->palcolor->info, sizeof(new_stroke->colorname)); + /* Adjust all the stroke's points, so that the strokes * get pasted relative to where the cursor is now */ diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 2df4b2cae54..fc6df49cf6c 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -38,8 +38,11 @@ #include "MEM_guardedalloc.h" -#include "BLI_math.h" #include "BLI_blenlib.h" +#include "BLI_ghash.h" +#include "BLI_math.h" +#include "BLI_string.h" +#include "BLI_string_utils.h" #include "BLI_utildefines.h" #include "BLT_translation.h" @@ -335,11 +338,27 @@ void GPENCIL_OT_duplicate(wmOperatorType *ot) /* NOTE: is exposed within the editors/gpencil module so that other tools can use it too */ ListBase gp_strokes_copypastebuf = {NULL, NULL}; +/* Hash for hanging on to all the palette colors used by strokes in the buffer + * + * This is needed to prevent dangling and unsafe pointers when pasting across datablocks, + * or after a color used by a stroke in the buffer gets deleted (via user action or undo). + */ +GHash *gp_strokes_copypastebuf_colors = NULL; + /* Free copy/paste buffer data */ void ED_gpencil_strokes_copybuf_free(void) { bGPDstroke *gps, *gpsn; + /* Free the palettes buffer + * NOTE: This is done before the strokes so that the name ptrs (keys) are still safe + */ + if (gp_strokes_copypastebuf_colors) { + BLI_ghash_free(gp_strokes_copypastebuf_colors, NULL, MEM_freeN); + gp_strokes_copypastebuf_colors = NULL; + } + + /* Free the stroke buffer */ for (gps = gp_strokes_copypastebuf.first; gps; gps = gpsn) { gpsn = gps->next; @@ -352,6 +371,46 @@ void ED_gpencil_strokes_copybuf_free(void) gp_strokes_copypastebuf.first = gp_strokes_copypastebuf.last = NULL; } +/* Ensure that destination datablock has all the colours the pasted strokes need + * Helper function for copy-pasting strokes + */ +GHash *gp_copybuf_validate_colormap(bGPdata *gpd) +{ + GHash *new_colors = BLI_ghash_str_new("GPencil Paste Dst Colors"); + GHashIterator gh_iter; + + /* If there's no active palette yet (i.e. new datablock), add one */ + bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd); + if (palette == NULL) { + palette = BKE_gpencil_palette_addnew(gpd, "Pasted Palette", true); + } + + /* For each color, figure out what to map to... */ + GHASH_ITER(gh_iter, gp_strokes_copypastebuf_colors) { + bGPDpalettecolor *palcolor; + char *name = BLI_ghashIterator_getKey(&gh_iter); + + /* Look for existing color to map to */ + /* XXX: What to do if same name but different color? Behaviour here should depend on a property? */ + palcolor = BKE_gpencil_palettecolor_getbyname(palette, name); + if (palcolor == NULL) { + /* Doesn't Exist - Create new matching color for this palette */ + /* XXX: This still doesn't fix the pasting across file boundaries problem... */ + bGPDpalettecolor *src_color = BLI_ghashIterator_getValue(&gh_iter); + + palcolor = MEM_dupallocN(src_color); + BLI_addtail(&palette->colors, palcolor); + + BLI_uniquename(&palette->colors, palcolor, DATA_("GP Color"), '.', offsetof(bGPDpalettecolor, info), sizeof(palcolor->info)); + } + + /* Store this mapping (for use later when pasting) */ + BLI_ghash_insert(new_colors, name, palcolor); + } + + return new_colors; +} + /* --------------------- */ /* Copy selected strokes */ @@ -413,7 +472,26 @@ static int gp_strokes_copy_exec(bContext *C, wmOperator *op) } CTX_DATA_END; - /* done - no updates needed */ + /* Build up hash of colors used in these strokes, making copies of these to protect against dangling pointers */ + if (gp_strokes_copypastebuf.first) { + gp_strokes_copypastebuf_colors = BLI_ghash_str_new("GPencil CopyBuf Colors"); + + for (bGPDstroke *gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) { + if (ED_gpencil_stroke_can_use(C, gps)) { + if (BLI_ghash_haskey(gp_strokes_copypastebuf_colors, gps->colorname) == false) { + bGPDpalettecolor *color = MEM_dupallocN(gps->palcolor); + + BLI_ghash_insert(gp_strokes_copypastebuf_colors, gps->colorname, color); + gps->palcolor = color; + } + } + } + } + + /* updates (to ensure operator buttons are refreshed, when used via hotkeys) */ + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, NULL); // XXX? + + /* done */ return OPERATOR_FINISHED; } @@ -458,6 +536,7 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op) bGPDframe *gpf; eGP_PasteMode type = RNA_enum_get(op->ptr, "type"); + GHash *new_colors; /* check for various error conditions */ if (gpd == NULL) { @@ -515,6 +594,10 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op) } CTX_DATA_END; + /* Ensure that all the necessary colors exist */ + new_colors = gp_copybuf_validate_colormap(gpd); + + /* Copy over the strokes from the buffer (and adjust the colors) */ for (bGPDstroke *gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) { if (ED_gpencil_stroke_can_use(C, gps)) { /* Need to verify if layer exists */ @@ -533,6 +616,7 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op) */ gpf = BKE_gpencil_layer_getframe(gpl, CFRA, true); if (gpf) { + /* Create new stroke */ bGPDstroke *new_stroke = MEM_dupallocN(gps); new_stroke->tmp_layerinfo[0] = '\0'; @@ -543,10 +627,22 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op) new_stroke->next = new_stroke->prev = NULL; BLI_addtail(&gpf->strokes, new_stroke); + + /* Fix color references */ + BLI_assert(new_stroke->colorname[0] != '\0'); + new_stroke->palcolor = BLI_ghash_lookup(new_colors, new_stroke->colorname); + + BLI_assert(new_stroke->palcolor != NULL); + BLI_strncpy(new_stroke->colorname, new_stroke->palcolor->info, sizeof(new_stroke->colorname)); + + /*new_stroke->flag |= GP_STROKE_RECALC_COLOR; */ } } } + /* free temp data */ + BLI_ghash_free(new_colors, NULL, NULL); + /* updates */ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); @@ -750,7 +846,7 @@ void GPENCIL_OT_blank_frame_add(wmOperatorType *ot) /* identifiers */ ot->name = "Insert Blank Frame"; ot->idname = "GPENCIL_OT_blank_frame_add"; - ot->description = "Inserts a blank frame on the current frame " + ot->description = "Insert a blank frame on the current frame " "(all subsequently existing frames, if any, are shifted right by one frame)"; /* callbacks */ diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h index 5c7c9b84adb..a3734c56c59 100644 --- a/source/blender/editors/gpencil/gpencil_intern.h +++ b/source/blender/editors/gpencil/gpencil_intern.h @@ -40,6 +40,8 @@ struct bGPdata; struct bGPDstroke; struct bGPDspoint; +struct GHash; + struct ARegion; struct View2D; struct wmOperatorType; @@ -69,75 +71,23 @@ typedef struct GP_SpaceConversion { float mat[4][4]; /* transform matrix on the strokes (introduced in [b770964]) */ } GP_SpaceConversion; - -/** - * Check whether a given stroke segment is inside a circular brush - * - * \param mval The current screen-space coordinates (midpoint) of the brush - * \param mvalo The previous screen-space coordinates (midpoint) of the brush (NOT CURRENTLY USED) - * \param rad The radius of the brush - * - * \param x0, y0 The screen-space x and y coordinates of the start of the stroke segment - * \param x1, y1 The screen-space x and y coordinates of the end of the stroke segment - */ bool gp_stroke_inside_circle(const int mval[2], const int UNUSED(mvalo[2]), int rad, int x0, int y0, int x1, int y1); - -/** - * Init settings for stroke point space conversions - * - * \param[out] r_gsc The space conversion settings struct, populated with necessary params - */ void gp_point_conversion_init(struct bContext *C, GP_SpaceConversion *r_gsc); -/** - * Convert a Grease Pencil coordinate (i.e. can be 2D or 3D) to screenspace (2D) - * - * \param[out] r_x The screen-space x-coordinate of the point - * \param[out] r_y The screen-space y-coordinate of the point - */ void gp_point_to_xy(GP_SpaceConversion *settings, struct bGPDstroke *gps, struct bGPDspoint *pt, int *r_x, int *r_y); -/** - * Convert a Grease Pencil coordinate (i.e. can be 2D or 3D) to screenspace (2D) - * - * Just like gp_point_to_xy(), except the resulting coordinates are floats not ints. - * Use this version to solve "stair-step" artifacts which may arise when roundtripping the calculations. - * - * \param[out] r_x The screen-space x-coordinate of the point - * \param[out] r_y The screen-space y-coordinate of the point - */ void gp_point_to_xy_fl(GP_SpaceConversion *gsc, bGPDstroke *gps, bGPDspoint *pt, float *r_x, float *r_y); -/** - * Convert point to parent space - * - * \param pt Original point - * \param diff_mat Matrix with the difference between original parent matrix - * \param[out] r_pt Pointer to new point after apply matrix - */ void gp_point_to_parent_space(bGPDspoint *pt, float diff_mat[4][4], bGPDspoint *r_pt); -/** - * Change points position relative to parent object - */ + void gp_apply_parent(bGPDlayer *gpl, bGPDstroke *gps); -/** - * Change point position relative to parent object - */ + void gp_apply_parent_point(bGPDlayer *gpl, bGPDspoint *pt); -/** - * Convert a screenspace point to a 3D Grease Pencil coordinate. - * - * For use with editing tools where it is easier to perform the operations in 2D, - * and then later convert the transformed points back to 3D. - * - * \param screeN_co The screenspace 2D coordinates to convert to - * \param[out] r_out The resulting 3D coordinates of the input point - */ bool gp_point_xy_to_3d(GP_SpaceConversion *gsc, struct Scene *scene, const float screen_co[2], float r_out[3]); /* Poll Callbacks ------------------------------------ */ @@ -155,48 +105,18 @@ int gp_brush_crt_presets_poll(bContext *C); extern ListBase gp_strokes_copypastebuf; +/* Build a map for converting between old colornames and destination-color-refs */ +struct GHash *gp_copybuf_validate_colormap(bGPdata *gpd); + /* Stroke Editing ------------------------------------ */ void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke *next_stroke, int tag_flags); -/** - * Apply smooth to stroke point - * \param gps Stroke to smooth - * \param i Point index - * \param inf Amount of smoothing to apply - * \param affect_pressure Apply smoothing to pressure values too? - */ bool gp_smooth_stroke(bGPDstroke *gps, int i, float inf, bool affect_pressure); - -/** -* Apply smooth for strength to stroke point -* \param gps Stroke to smooth -* \param i Point index -* \param inf Amount of smoothing to apply -*/ bool gp_smooth_stroke_strength(bGPDstroke *gps, int i, float inf); - -/** -* Apply smooth for thickness to stroke point (use pressure) -* \param gps Stroke to smooth -* \param i Point index -* \param inf Amount of smoothing to apply -*/ bool gp_smooth_stroke_thickness(bGPDstroke *gps, int i, float inf); - -/** - * Subdivide a stroke once, by adding points at the midpoint between each pair of points - * \param gps Stroke data - * \param new_totpoints Total number of points (after subdividing) - */ void gp_subdivide_stroke(bGPDstroke *gps, const int new_totpoints); - -/** -* Add randomness to stroke -* \param gps Stroke data -* \param brush Brush data -*/ void gp_randomize_stroke(bGPDstroke *gps, bGPDbrush *brush); /* Layers Enums -------------------------------------- */ diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 5eacbf6f807..eb49060b629 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -162,6 +162,8 @@ typedef struct tGPsdata { bGPDbrush *brush; /* current drawing brush */ short straight[2]; /* 1: line horizontal, 2: line vertical, other: not defined, second element position */ int lock_axis; /* lock drawing to one axis */ + + short keymodifier; /* key used for invoking the operator */ } tGPsdata; /* ------ */ @@ -1940,7 +1942,7 @@ static void gpencil_draw_cancel(bContext *C, wmOperator *op) /* ------------------------------- */ -static int gpencil_draw_init(bContext *C, wmOperator *op) +static int gpencil_draw_init(bContext *C, wmOperator *op, const wmEvent *event) { tGPsdata *p; eGPencil_PaintModes paintmode = RNA_enum_get(op->ptr, "mode"); @@ -1959,6 +1961,13 @@ static int gpencil_draw_init(bContext *C, wmOperator *op) gpencil_draw_exit(C, op); return 0; } + + if (event != NULL) { + p->keymodifier = event->keymodifier; + } + else { + p->keymodifier = -1; + } /* everything is now setup ok */ return 1; @@ -2200,7 +2209,7 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op) /* printf("GPencil - Starting Re-Drawing\n"); */ /* try to initialize context data needed while drawing */ - if (!gpencil_draw_init(C, op)) { + if (!gpencil_draw_init(C, op, NULL)) { if (op->customdata) MEM_freeN(op->customdata); /* printf("\tGP - no valid data\n"); */ return OPERATOR_CANCELLED; @@ -2275,7 +2284,7 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event printf("GPencil - Starting Drawing\n"); /* try to initialize context data needed while drawing */ - if (!gpencil_draw_init(C, op)) { + if (!gpencil_draw_init(C, op, event)) { if (op->customdata) MEM_freeN(op->customdata); if (G.debug & G_DEBUG) @@ -2438,7 +2447,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event) * is essential for ensuring that they can quickly return to that view */ } - else if ((ELEM(event->type, DKEY)) && (event->val == KM_RELEASE)) { + else if ((ELEM(event->type, p->keymodifier)) && (event->val == KM_RELEASE)) { /* enable continuous if release D key in mid drawing */ p->scene->toolsettings->gpencil_flags |= GP_TOOL_FLAG_PAINTSESSIONS_ON; } diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index 2b662d04f03..ed05b8be9ca 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -391,7 +391,16 @@ EnumPropertyItem *ED_gpencil_layers_with_new_enum_itemf(bContext *C, PointerRNA /* ******************************************************** */ /* Brush Tool Core */ -/* Check if part of stroke occurs within last segment drawn by eraser */ +/** + * Check whether a given stroke segment is inside a circular brush + * + * \param mval The current screen-space coordinates (midpoint) of the brush + * \param mvalo The previous screen-space coordinates (midpoint) of the brush (NOT CURRENTLY USED) + * \param rad The radius of the brush + * + * \param x0, y0 The screen-space x and y coordinates of the start of the stroke segment + * \param x1, y1 The screen-space x and y coordinates of the end of the stroke segment + */ bool gp_stroke_inside_circle(const int mval[2], const int UNUSED(mvalo[2]), int rad, int x0, int y0, int x1, int y1) { @@ -502,7 +511,11 @@ bGPDpalettecolor *ED_gpencil_stroke_getcolor(bGPdata *gpd, bGPDstroke *gps) /* ******************************************************** */ /* Space Conversion */ -/* Init handling for space-conversion function (from passed-in parameters) */ +/** + * Init settings for stroke point space conversions + * + * \param r_gsc: [out] The space conversion settings struct, populated with necessary params + */ void gp_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc) { ScrArea *sa = CTX_wm_area(C); @@ -538,7 +551,13 @@ void gp_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc) } } -/* convert point to parent space */ +/** + * Convert point to parent space + * + * \param pt Original point + * \param diff_mat Matrix with the difference between original parent matrix + * \param[out] r_pt Pointer to new point after apply matrix + */ void gp_point_to_parent_space(bGPDspoint *pt, float diff_mat[4][4], bGPDspoint *r_pt) { float fpt[3]; @@ -547,7 +566,9 @@ void gp_point_to_parent_space(bGPDspoint *pt, float diff_mat[4][4], bGPDspoint * copy_v3_v3(&r_pt->x, fpt); } -/* Change position relative to parent object */ +/** + * Change points position relative to parent object + */ void gp_apply_parent(bGPDlayer *gpl, bGPDstroke *gps) { bGPDspoint *pt; @@ -568,7 +589,9 @@ void gp_apply_parent(bGPDlayer *gpl, bGPDstroke *gps) } } -/* Change point position relative to parent object */ +/** + * Change point position relative to parent object + */ void gp_apply_parent_point(bGPDlayer *gpl, bGPDspoint *pt) { /* undo matrix */ @@ -583,8 +606,13 @@ void gp_apply_parent_point(bGPDlayer *gpl, bGPDspoint *pt) copy_v3_v3(&pt->x, fpt); } -/* Convert Grease Pencil points to screen-space values - * WARNING: This assumes that the caller has already checked whether the stroke in question can be drawn +/** + * Convert a Grease Pencil coordinate (i.e. can be 2D or 3D) to screenspace (2D) + * + * \param[out] r_x The screen-space x-coordinate of the point + * \param[out] r_y The screen-space y-coordinate of the point + * + * \warning This assumes that the caller has already checked whether the stroke in question can be drawn. */ void gp_point_to_xy(GP_SpaceConversion *gsc, bGPDstroke *gps, bGPDspoint *pt, int *r_x, int *r_y) @@ -628,8 +656,16 @@ void gp_point_to_xy(GP_SpaceConversion *gsc, bGPDstroke *gps, bGPDspoint *pt, } } -/* Convert Grease Pencil points to screen-space values (as floats) - * WARNING: This assumes that the caller has already checked whether the stroke in question can be drawn +/** + * Convert a Grease Pencil coordinate (i.e. can be 2D or 3D) to screenspace (2D) + * + * Just like gp_point_to_xy(), except the resulting coordinates are floats not ints. + * Use this version to solve "stair-step" artifacts which may arise when roundtripping the calculations. + * + * \param r_x: [out] The screen-space x-coordinate of the point + * \param r_y: [out] The screen-space y-coordinate of the point + * + * \warning This assumes that the caller has already checked whether the stroke in question can be drawn */ void gp_point_to_xy_fl(GP_SpaceConversion *gsc, bGPDstroke *gps, bGPDspoint *pt, float *r_x, float *r_y) @@ -688,6 +724,12 @@ void gp_point_to_xy_fl(GP_SpaceConversion *gsc, bGPDstroke *gps, bGPDspoint *pt, /** * Project screenspace coordinates to 3D-space * + * For use with editing tools where it is easier to perform the operations in 2D, + * and then later convert the transformed points back to 3D. + * + * \param screen_co: The screenspace 2D coordinates to convert to + * \param r_out: The resulting 3D coordinates of the input point + * * \note We include this as a utility function, since the standard method * involves quite a few steps, which are invariably always the same * for all GPencil operations. So, it's nicer to just centralize these. @@ -722,7 +764,7 @@ bool gp_point_xy_to_3d(GP_SpaceConversion *gsc, Scene *scene, const float screen } /** - * Apply smooth to stroke point + * Apply smooth to stroke point * \param gps Stroke to smooth * \param i Point index * \param inf Amount of smoothing to apply diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h index 8c604208041..d395cb3e16d 100644 --- a/source/blender/editors/include/UI_icons.h +++ b/source/blender/editors/include/UI_icons.h @@ -313,9 +313,9 @@ DEF_ICON(OUTLINER_OB_ARMATURE) DEF_ICON(OUTLINER_OB_FONT) DEF_ICON(OUTLINER_OB_SURFACE) DEF_ICON(OUTLINER_OB_SPEAKER) +DEF_ICON(OUTLINER_OB_FORCE_FIELD) +DEF_ICON(OUTLINER_OB_GROUP_INSTANCE) #ifndef DEF_ICON_BLANK_SKIP - DEF_ICON(BLANK120) - DEF_ICON(BLANK121) DEF_ICON(BLANK122) DEF_ICON(BLANK123) DEF_ICON(BLANK124) diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 7180e18ab92..bcb1e3e648a 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -1337,7 +1337,7 @@ static void ui_but_to_pixelrect(rcti *rect, const ARegion *ar, uiBlock *block, u rctf rectf; ui_block_to_window_rctf(ar, block, &rectf, (but) ? &but->rect : &block->rect); - BLI_rcti_rctf_copy(rect, &rectf); + BLI_rcti_rctf_copy_round(rect, &rectf); BLI_rcti_translate(rect, -ar->winrct.xmin, -ar->winrct.ymin); } @@ -2335,11 +2335,10 @@ bool ui_but_string_set_eval_num(bContext *C, uiBut *but, const char *str, double #else /* WITH_PYTHON */ - *value = atof(str); + *r_value = atof(str); ok = true; - (void)C; - (void)but; + UNUSED_VARS(C, but); #endif /* WITH_PYTHON */ @@ -3168,7 +3167,9 @@ static uiBut *ui_def_but( } if (block->flag & UI_BLOCK_RADIAL) { - but->drawflag |= (UI_BUT_TEXT_LEFT | UI_BUT_ICON_LEFT); + but->drawflag |= UI_BUT_TEXT_LEFT; + if (but->str && but->str[0]) + but->drawflag |= UI_BUT_ICON_LEFT; } else if ((block->flag & UI_BLOCK_LOOP) || ELEM(but->type, diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 30a2094fee7..da43a58bc74 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -2396,8 +2396,10 @@ static void ui_litem_layout_radial(uiLayout *litem) /* add a little bit more here to include number */ bitem->but->rect.xmax += 1.5f * UI_UNIT_X; /* enable drawing as pie item if supported by widget */ - if (ui_item_is_radial_drawable(bitem)) + if (ui_item_is_radial_drawable(bitem)) { bitem->but->dt = UI_EMBOSS_RADIAL; + bitem->but->drawflag |= UI_BUT_ICON_LEFT; + } } ui_item_size(item, &itemw, &itemh); diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 534bd4278ca..5ed94474726 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -2099,9 +2099,11 @@ static void ui_update_color_picker_buts_rgb(uiBlock *block, ColorPicker *cpicker continue; if (bt->rnaprop) { - ui_but_v3_set(bt, rgb); + /* original button that created the color picker already does undo + * push, so disable it on RNA buttons in the color picker block */ + UI_but_flag_disable(bt, UI_BUT_UNDO); } else if (STREQ(bt->str, "Hex: ")) { float rgb_gamma[3]; diff --git a/source/blender/editors/io/io_alembic.c b/source/blender/editors/io/io_alembic.c index ba8792d12ff..ca4ab30a08d 100644 --- a/source/blender/editors/io/io_alembic.c +++ b/source/blender/editors/io/io_alembic.c @@ -31,6 +31,9 @@ # include "BLI_winstuff.h" #endif +#include <string.h> +#include <errno.h> + #include "MEM_guardedalloc.h" #include "DNA_mesh_types.h" @@ -383,8 +386,8 @@ void WM_OT_alembic_export(wmOperatorType *ot) "Enable this to run the import in the background, disable to block Blender while importing"); /* This dummy prop is used to check whether we need to init the start and - * end frame values to that of the scene's, otherwise they are reset at - * every change, draw update. */ + * end frame values to that of the scene's, otherwise they are reset at + * every change, draw update. */ RNA_def_boolean(ot->srna, "init_scene_frame_range", false, "", ""); } @@ -417,9 +420,20 @@ static int get_sequence_len(char *filename, int *ofs) } char path[FILE_MAX]; + BLI_path_abs(filename, G.main->name); BLI_split_dir_part(filename, path, FILE_MAX); + if (path[0] == '\0') { + /* The filename had no path, so just use the blend file path. */ + BLI_split_dir_part(G.main->name, path, FILE_MAX); + } + DIR *dir = opendir(path); + if (dir == NULL) { + fprintf(stderr, "Error opening directory '%s': %s\n", + path, errno ? strerror(errno) : "unknown error"); + return -1; + } const char *ext = ".abc"; const char *basename = BLI_path_basename(filename); @@ -523,6 +537,10 @@ static int wm_alembic_import_exec(bContext *C, wmOperator *op) if (is_sequence) { sequence_len = get_sequence_len(filename, &offset); + if (sequence_len < 0) { + BKE_report(op->reports, RPT_ERROR, "Unable to determine ABC sequence length"); + return OPERATOR_CANCELLED; + } } bool ok = ABC_import(C, filename, scale, is_sequence, set_frame_range, diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c index 139c9817437..cead08afd61 100644 --- a/source/blender/editors/io/io_collada.c +++ b/source/blender/editors/io/io_collada.c @@ -87,8 +87,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) int include_shapekeys; int deform_bones_only; - int include_uv_textures; - int include_material_textures; + int export_texture_type; int use_texture_copies; int active_uv_only; @@ -139,8 +138,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) 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"); - include_material_textures = RNA_boolean_get(op->ptr, "include_material_textures"); + export_texture_type = RNA_enum_get(op->ptr, "export_texture_type_selection"); use_texture_copies = RNA_boolean_get(op->ptr, "use_texture_copies"); active_uv_only = RNA_boolean_get(op->ptr, "active_uv_only"); @@ -169,8 +167,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) deform_bones_only, active_uv_only, - include_uv_textures, - include_material_textures, + export_texture_type, use_texture_copies, triangulate, @@ -241,10 +238,7 @@ static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr) uiItemR(row, imfptr, "active_uv_only", 0, NULL, ICON_NONE); row = uiLayoutRow(box, false); - uiItemR(row, imfptr, "include_uv_textures", 0, NULL, ICON_NONE); - - row = uiLayoutRow(box, false); - uiItemR(row, imfptr, "include_material_textures", 0, NULL, ICON_NONE); + uiItemR(row, imfptr, "export_texture_type_selection", 0, "", ICON_NONE); row = uiLayoutRow(box, false); uiItemR(row, imfptr, "use_texture_copies", 1, NULL, ICON_NONE); @@ -321,9 +315,15 @@ void WM_OT_collada_export(wmOperatorType *ot) }; static EnumPropertyItem prop_bc_export_transformation_type[] = { - {BC_TRANSFORMATION_TYPE_MATRIX, "matrix", 0, "Matrix", "Use <matrix> to specify transformations"}, - {BC_TRANSFORMATION_TYPE_TRANSROTLOC, "transrotloc", 0, "TransRotLoc", "Use <translate>, <rotate>, <scale> to specify transformations"}, - {0, NULL, 0, NULL, NULL} + { BC_TRANSFORMATION_TYPE_MATRIX, "matrix", 0, "Matrix", "Use <matrix> to specify transformations" }, + { BC_TRANSFORMATION_TYPE_TRANSROTLOC, "transrotloc", 0, "TransRotLoc", "Use <translate>, <rotate>, <scale> to specify transformations" }, + { 0, NULL, 0, NULL, NULL } + }; + + static EnumPropertyItem prop_bc_export_texture_type[] = { + { BC_TEXTURE_TYPE_MAT, "mat", 0, "Materials", "Export Materials" }, + { BC_TEXTURE_TYPE_UV, "uv", 0, "UV Textures", "Export UV Textures (Face textures) as materials" }, + { 0, NULL, 0, NULL, NULL } }; ot->name = "Export COLLADA"; @@ -368,16 +368,9 @@ void WM_OT_collada_export(wmOperatorType *ot) RNA_def_boolean(func, "deform_bones_only", 0, "Deform Bones only", "Only export deforming bones with armatures"); - RNA_def_boolean(func, "active_uv_only", 0, "Only Selected UV Map", "Export only the selected UV Map"); - RNA_def_boolean(func, "include_uv_textures", 0, "Include UV Textures", - "Export textures assigned to the object UV Maps"); - - RNA_def_boolean(func, "include_material_textures", 0, "Include Material Textures", - "Export textures assigned to the object Materials"); - RNA_def_boolean(func, "use_texture_copies", 1, "Copy", "Copy textures to same folder where the .dae file is exported"); @@ -394,11 +387,20 @@ void WM_OT_collada_export(wmOperatorType *ot) RNA_def_boolean(func, "sort_by_name", 0, "Sort by Object name", "Sort exported data by Object name"); + RNA_def_int(func, "export_transformation_type", 0, INT_MIN, INT_MAX, - "Transform", "Transformation type for translation, scale and rotation", INT_MIN, INT_MAX); + "Transform", "Transformation type for translation, scale and rotation", INT_MIN, INT_MAX); RNA_def_enum(func, "export_transformation_type_selection", prop_bc_export_transformation_type, 0, - "Transform", "Transformation type for translation, scale and rotation"); + "Transform", "Transformation type for translation, scale and rotation"); + + + RNA_def_int(func, "export_texture_type", 0, INT_MIN, INT_MAX, + "Texture Type", "Type for exported Textures (UV or MAT)", INT_MIN, INT_MAX); + + RNA_def_enum(func, "export_texture_type_selection", prop_bc_export_texture_type, 0, + "Texture Type", "Type for exported Textures (UV or MAT)"); + RNA_def_boolean(func, "open_sim", 0, "Export to SL/OpenSim", "Compatibility mode for SL, OpenSim and other compatible online worlds"); diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index 3725590c188..07fedffaf80 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -384,7 +384,7 @@ void MESH_OT_primitive_cone_add(wmOperatorType *ot) /* props */ RNA_def_int(ot->srna, "vertices", 32, 3, MESH_ADD_VERTS_MAXI, "Vertices", "", 3, 500); RNA_def_float_distance(ot->srna, "radius1", 1.0f, 0.0, OBJECT_ADD_SIZE_MAXF, "Radius 1", "", 0.001, 100.00); - RNA_def_float_distance(ot->srna, "radius2", 0.0f, 0.0, OBJECT_ADD_SIZE_MAXF, "Radius 2", "", 0.001, 100.00); + RNA_def_float_distance(ot->srna, "radius2", 0.0f, 0.0, OBJECT_ADD_SIZE_MAXF, "Radius 2", "", 0.0, 100.00); RNA_def_float_distance(ot->srna, "depth", 2.0f, 0.0, OBJECT_ADD_SIZE_MAXF, "Depth", "", 0.001, 100.00); RNA_def_enum(ot->srna, "end_fill_type", fill_type_items, 1, "Base Fill Type", ""); diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index bf59693b856..5e44509e10a 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -1472,7 +1472,7 @@ static void clip_to_ortho_planes(float v1[3], float v2[3], const float center[3] /* could be v1 or v2 */ sub_v3_v3(v1, center); - project_plane_v3_v3v3(closest, v1, dir); + project_plane_normalized_v3_v3v3(closest, v1, dir); add_v3_v3(closest, center); madd_v3_v3v3fl(v1, closest, dir, d); diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index b278d6e1e87..b5a9c4e9e5b 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1464,8 +1464,6 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, } if (ob_dst->parent) { - invert_m4_m4(ob_dst->parentinv, dob->mat); - /* note, this may be the parent of other objects, but it should * still work out ok */ BKE_object_apply_mat4(ob_dst, dob->mat, false, true); @@ -1486,7 +1484,6 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, ob_dst->partype = PAROBJECT; /* similer to the code above, see comments */ - invert_m4_m4(ob_dst->parentinv, dob->mat); BKE_object_apply_mat4(ob_dst, dob->mat, false, true); DAG_id_tag_update(&ob_dst->id, OB_RECALC_OB); } @@ -1640,7 +1637,7 @@ static int convert_exec(bContext *C, wmOperator *op) MetaBall *mb; Mesh *me; const short target = RNA_enum_get(op->ptr, "target"); - const bool keep_original = RNA_boolean_get(op->ptr, "keep_original"); + bool keep_original = RNA_boolean_get(op->ptr, "keep_original"); int a, mballConverted = 0; /* don't forget multiple users! */ @@ -1678,6 +1675,19 @@ static int convert_exec(bContext *C, wmOperator *op) { for (CollectionPointerLink *link = selected_editable_bases.first; link; link = link->next) { Base *base = link->ptr.data; + ob = base->object; + + /* The way object type conversion works currently (enforcing conversion of *all* objetcs using converted + * obdata, even some un-selected/hidden/inother scene ones, sounds totally bad to me. + * However, changing this is more design than bugfix, not to mention convoluted code below, + * so that will be for later. + * But at the very least, do not do that with linked IDs! */ + if ((ID_IS_LINKED_DATABLOCK(ob) || ID_IS_LINKED_DATABLOCK(ob->data)) && !keep_original) { + keep_original = true; + BKE_reportf(op->reports, RPT_INFO, + "Converting some linked object/object data, enforcing 'Keep Original' option to True"); + } + DAG_id_tag_update(&base->object->id, OB_RECALC_DATA); } diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c index 0fe43c44d7d..568778c0a86 100644 --- a/source/blender/editors/object/object_group.c +++ b/source/blender/editors/object/object_group.c @@ -528,8 +528,7 @@ static int group_unlink_exec(bContext *C, wmOperator *UNUSED(op)) if (!group) return OPERATOR_CANCELLED; - BKE_libblock_unlink(bmain, group, false, false); - BKE_libblock_free(bmain, group); + BKE_libblock_delete(bmain, group); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 7ec43b02b38..3284af2df69 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -2149,24 +2149,6 @@ void ED_object_single_users(Main *bmain, Scene *scene, const bool full, const bo /******************************* Make Local ***********************************/ -/* helper for below, ma was checked to be not NULL */ -static void make_local_makelocalmaterial(Material *ma) -{ - AnimData *adt; - int b; - - id_make_local(G.main, &ma->id, false, false); - - for (b = 0; b < MAX_MTEX; b++) - if (ma->mtex[b] && ma->mtex[b]->tex) - id_make_local(G.main, &ma->mtex[b]->tex->id, false, false); - - adt = BKE_animdata_from_id(&ma->id); - if (adt) BKE_animdata_make_local(adt); - - /* nodetree? XXX */ -} - enum { MAKE_LOCAL_SELECT_OB = 1, MAKE_LOCAL_SELECT_OBDATA = 2, @@ -2252,123 +2234,142 @@ static bool make_local_all__instance_indirect_unused(Main *bmain, Scene *scene) return changed; } -static int make_local_exec(bContext *C, wmOperator *op) +static void make_local_animdata_tag_strips(ListBase *strips) { - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - AnimData *adt; - ParticleSystem *psys; - Material *ma, ***matarar; - Lamp *la; - ID *id; - const int mode = RNA_enum_get(op->ptr, "type"); - int a, b; + NlaStrip *strip; - if (mode == MAKE_LOCAL_ALL) { - /* de-select so the user can differentiate newly instanced from existing objects */ - BKE_scene_base_deselect_all(scene); - - if (make_local_all__instance_indirect_unused(bmain, scene)) { - BKE_report(op->reports, RPT_INFO, - "Orphan library objects added to the current scene to avoid loss"); + for (strip = strips->first; strip; strip = strip->next) { + if (strip->act) { + strip->act->id.tag &= ~LIB_TAG_PRE_EXISTING; + } + if (strip->remap && strip->remap->target) { + strip->remap->target->id.tag &= ~LIB_TAG_PRE_EXISTING; } - BKE_library_make_local(bmain, NULL, NULL, false, false); /* NULL is all libs */ - WM_event_add_notifier(C, NC_WINDOW, NULL); - return OPERATOR_FINISHED; + make_local_animdata_tag_strips(&strip->strips); } +} - tag_localizable_objects(C, mode); - - CTX_DATA_BEGIN (C, Object *, ob, selected_objects) - { - if ((ob->id.tag & LIB_TAG_DOIT) == 0) { - continue; +/* Tag all actions used by given animdata to be made local. */ +static void make_local_animdata_tag(AnimData *adt) +{ + if (adt) { + /* Actions - Active and Temp */ + if (adt->action) { + adt->action->id.tag &= ~LIB_TAG_PRE_EXISTING; + } + if (adt->tmpact) { + adt->tmpact->id.tag &= ~LIB_TAG_PRE_EXISTING; + } + /* Remaps */ + if (adt->remap && adt->remap->target) { + adt->remap->target->id.tag &= ~LIB_TAG_PRE_EXISTING; } - if (ob->id.lib) - id_make_local(bmain, &ob->id, false, false); - } - CTX_DATA_END; + /* Drivers */ + /* TODO: need to handle the ID-targets too? */ - /* maybe object pointers */ - CTX_DATA_BEGIN (C, Object *, ob, selected_objects) - { - if (ob->id.lib == NULL) { - ID_NEW_REMAP(ob->parent); + /* NLA Data */ + for (NlaTrack *nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) { + make_local_animdata_tag_strips(&nlt->strips); } } - CTX_DATA_END; - - CTX_DATA_BEGIN (C, Object *, ob, selected_objects) - { - if ((ob->id.tag & LIB_TAG_DOIT) == 0) { - continue; - } +} - id = ob->data; +static void make_local_material_tag(Material *ma) +{ + if (ma) { + ma->id.tag &= ~LIB_TAG_PRE_EXISTING; + make_local_animdata_tag(BKE_animdata_from_id(&ma->id)); - if (id && (ELEM(mode, MAKE_LOCAL_SELECT_OBDATA, MAKE_LOCAL_SELECT_OBDATA_MATERIAL))) { - id_make_local(bmain, id, false, false); - adt = BKE_animdata_from_id(id); - if (adt) BKE_animdata_make_local(adt); + /* About nodetrees: root one is made local together with material, others we keep linked for now... */ - /* tag indirect data direct */ - matarar = give_matarar(ob); - if (matarar) { - for (a = 0; a < ob->totcol; a++) { - ma = (*matarar)[a]; - if (ma) - id_lib_extern(&ma->id); - } + for (int a = 0; a < MAX_MTEX; a++) { + if (ma->mtex[a] && ma->mtex[a]->tex) { + ma->mtex[a]->tex->id.tag &= ~LIB_TAG_PRE_EXISTING; } } + } +} - for (psys = ob->particlesystem.first; psys; psys = psys->next) - id_make_local(bmain, &psys->part->id, false, false); +static int make_local_exec(bContext *C, wmOperator *op) +{ + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + ParticleSystem *psys; + Material *ma, ***matarar; + Lamp *la; + const int mode = RNA_enum_get(op->ptr, "type"); + int a; + + /* Note: we (ab)use LIB_TAG_PRE_EXISTING to cherry pick which ID to make local... */ + if (mode == MAKE_LOCAL_ALL) { + BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false); + + /* de-select so the user can differentiate newly instanced from existing objects */ + BKE_scene_base_deselect_all(scene); - adt = BKE_animdata_from_id(&ob->id); - if (adt) BKE_animdata_make_local(adt); + if (make_local_all__instance_indirect_unused(bmain, scene)) { + BKE_report(op->reports, RPT_INFO, "Orphan library objects added to the current scene to avoid loss"); + } } - CTX_DATA_END; + else { + BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, true); + tag_localizable_objects(C, mode); - if (mode == MAKE_LOCAL_SELECT_OBDATA_MATERIAL) { CTX_DATA_BEGIN (C, Object *, ob, selected_objects) { if ((ob->id.tag & LIB_TAG_DOIT) == 0) { continue; } - if (ob->type == OB_LAMP) { - la = ob->data; - - for (b = 0; b < MAX_MTEX; b++) - if (la->mtex[b] && la->mtex[b]->tex) - id_make_local(bmain, &la->mtex[b]->tex->id, false, false); + ob->id.tag &= ~LIB_TAG_PRE_EXISTING; + make_local_animdata_tag(BKE_animdata_from_id(&ob->id)); + for (psys = ob->particlesystem.first; psys; psys = psys->next) { + psys->part->id.tag &= ~LIB_TAG_PRE_EXISTING; } - else { + + if (mode == MAKE_LOCAL_SELECT_OBDATA_MATERIAL) { for (a = 0; a < ob->totcol; a++) { ma = ob->mat[a]; - if (ma) - make_local_makelocalmaterial(ma); + if (ma) { + make_local_material_tag(ma); + } } matarar = (Material ***)give_matarar(ob); if (matarar) { for (a = 0; a < ob->totcol; a++) { ma = (*matarar)[a]; - if (ma) - make_local_makelocalmaterial(ma); + if (ma) { + make_local_material_tag(ma); + } + } + } + + if (ob->type == OB_LAMP) { + BLI_assert(ob->data != NULL); + la = ob->data; + for (a = 0; a < MAX_MTEX; a++) { + if (la->mtex[a] && la->mtex[a]->tex) { + la->id.tag &= ~LIB_TAG_PRE_EXISTING; + } } } } + + if (ELEM(mode, MAKE_LOCAL_SELECT_OBDATA, MAKE_LOCAL_SELECT_OBDATA_MATERIAL) && ob->data != NULL) { + ID *ob_data = ob->data; + ob_data->tag &= ~LIB_TAG_PRE_EXISTING; + make_local_animdata_tag(BKE_animdata_from_id(ob_data)); + } } CTX_DATA_END; } - BKE_main_id_clear_newpoins(bmain); - WM_event_add_notifier(C, NC_WINDOW, NULL); + BKE_library_make_local(bmain, NULL, NULL, true, false); /* NULL is all libs */ + WM_event_add_notifier(C, NC_WINDOW, NULL); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c index 3d7a45843cc..edc3f6c784c 100644 --- a/source/blender/editors/physics/dynamicpaint_ops.c +++ b/source/blender/editors/physics/dynamicpaint_ops.c @@ -279,10 +279,10 @@ void DPAINT_OT_output_toggle(wmOperatorType *ot) /***************************** Image Sequence Baking ******************************/ typedef struct DynamicPaintBakeJob { - /* from wmJob */ - void *owner; - short *stop, *do_update; - float *progress; + /* from wmJob */ + void *owner; + short *stop, *do_update; + float *progress; struct Main *bmain; Scene *scene; @@ -297,13 +297,13 @@ typedef struct DynamicPaintBakeJob { static void dpaint_bake_free(void *customdata) { - DynamicPaintBakeJob *job = customdata; - MEM_freeN(job); + DynamicPaintBakeJob *job = customdata; + MEM_freeN(job); } static void dpaint_bake_endjob(void *customdata) { - DynamicPaintBakeJob *job = customdata; + DynamicPaintBakeJob *job = customdata; DynamicPaintCanvasSettings *canvas = job->canvas; canvas->flags &= ~MOD_DPAINT_BAKING; @@ -311,7 +311,7 @@ static void dpaint_bake_endjob(void *customdata) dynamicPaint_freeSurfaceData(job->surface); G.is_rendering = false; - BKE_spacedata_draw_locks(false); + BKE_spacedata_draw_locks(false); WM_set_locked_interface(G.main->wm.first, false); @@ -421,26 +421,26 @@ static void dynamicPaint_bakeImageSequence(DynamicPaintBakeJob *job) static void dpaint_bake_startjob(void *customdata, short *stop, short *do_update, float *progress) { - DynamicPaintBakeJob *job = customdata; + DynamicPaintBakeJob *job = customdata; - job->stop = stop; - job->do_update = do_update; - job->progress = progress; + job->stop = stop; + job->do_update = do_update; + job->progress = progress; job->start = PIL_check_seconds_timer(); job->success = 1; - G.is_break = false; /* reset BKE_blender_test_break*/ + G.is_break = false; /* reset BKE_blender_test_break*/ /* XXX annoying hack: needed to prevent data corruption when changing * scene frame in separate threads - */ - G.is_rendering = true; - BKE_spacedata_draw_locks(true); + */ + G.is_rendering = true; + BKE_spacedata_draw_locks(true); dynamicPaint_bakeImageSequence(job); - *do_update = true; - *stop = 0; + *do_update = true; + *stop = 0; } /* diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index e22a145b3a6..2541aaa4b11 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -4419,7 +4419,7 @@ void PE_undo_push(Scene *scene, const char *str) undo= undo->prev; } if (undo) { - while (edit->undo.first!=undo) { + while (edit->undo.first != undo) { PTCacheUndo *first= edit->undo.first; BLI_remlink(&edit->undo, first); free_PTCacheUndo(first); diff --git a/source/blender/editors/physics/physics_pointcache.c b/source/blender/editors/physics/physics_pointcache.c index e81aa584586..f36ebb3715e 100644 --- a/source/blender/editors/physics/physics_pointcache.c +++ b/source/blender/editors/physics/physics_pointcache.c @@ -99,45 +99,45 @@ static int ptcache_job_break(void *customdata) static void ptcache_job_update(void *customdata, float progress, int *cancel) { - PointCacheJob *job = customdata; + PointCacheJob *job = customdata; - if (ptcache_job_break(job)) { - *cancel = 1; - } + if (ptcache_job_break(job)) { + *cancel = 1; + } - *(job->do_update) = true; - *(job->progress) = progress; + *(job->do_update) = true; + *(job->progress) = progress; } static void ptcache_job_startjob(void *customdata, short *stop, short *do_update, float *progress) { - PointCacheJob *job = customdata; + PointCacheJob *job = customdata; - job->stop = stop; - job->do_update = do_update; - job->progress = progress; + job->stop = stop; + job->do_update = do_update; + job->progress = progress; - G.is_break = false; + G.is_break = false; - /* XXX annoying hack: needed to prevent data corruption when changing - * scene frame in separate threads - */ - G.is_rendering = true; - BKE_spacedata_draw_locks(true); + /* XXX annoying hack: needed to prevent data corruption when changing + * scene frame in separate threads + */ + G.is_rendering = true; + BKE_spacedata_draw_locks(true); BKE_ptcache_bake(job->baker); - *do_update = true; - *stop = 0; + *do_update = true; + *stop = 0; } static void ptcache_job_endjob(void *customdata) { - PointCacheJob *job = customdata; + PointCacheJob *job = customdata; Scene *scene = job->baker->scene; - G.is_rendering = false; - BKE_spacedata_draw_locks(false); + G.is_rendering = false; + BKE_spacedata_draw_locks(false); WM_set_locked_interface(G.main->wm.first, false); diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index fa18b82507e..35d772afae7 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -1180,7 +1180,7 @@ void ED_preview_icon_render(Main *bmain, Scene *scene, ID *id, unsigned int *rec ip.bmain = bmain; ip.scene = scene; - ip.owner = id; + ip.owner = BKE_previewimg_id_ensure(id); ip.id = id; icon_preview_add_size(&ip, rect, sizex, sizey); diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 7d2b77028fc..f469686b0b2 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1228,6 +1228,7 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win) winrct.ymax = winsize_y - 1; /* header size depends on DPI, let's verify */ + WM_window_set_dpi(win); screen_refresh_headersizes(); screen_test_scale(win->screen, winsize_x, winsize_y); @@ -1762,7 +1763,7 @@ bool ED_screen_delete_scene(bContext *C, Scene *scene) BKE_libblock_remap(bmain, scene, newscene, ID_REMAP_SKIP_INDIRECT_USAGE | ID_REMAP_SKIP_NEVER_NULL_USAGE); - BKE_libblock_free(bmain, scene); + BKE_libblock_free_us(bmain, scene); return true; } @@ -1926,7 +1927,6 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const s ED_screen_set(C, sc); - BKE_screen_free(oldscreen); BKE_libblock_free(CTX_data_main(C), oldscreen); /* After we've restored back to SCREENNORMAL, we have to wait with diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 9dbc082c119..c99d9add432 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -3756,7 +3756,7 @@ static int screen_animation_cancel_exec(bContext *C, wmOperator *op) bScreen *screen = ED_screen_animation_playing(CTX_wm_manager(C)); if (screen) { - if (RNA_boolean_get(op->ptr, "restore_frame")) { + if (RNA_boolean_get(op->ptr, "restore_frame") && screen->animtimer) { ScreenAnimData *sad = screen->animtimer->customdata; Scene *scene = CTX_data_scene(C); diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c index 72de7e5c81c..1d67ac620b0 100644 --- a/source/blender/editors/space_buttons/buttons_texture.c +++ b/source/blender/editors/space_buttons/buttons_texture.c @@ -470,7 +470,7 @@ void buttons_texture_context_compute(const bContext *C, SpaceButs *sbuts) } else { /* set one user as active based on active index */ - if (ct->index == BLI_listbase_count_ex(&ct->users, ct->index + 1)) + if (ct->index >= BLI_listbase_count_ex(&ct->users, ct->index + 1)) ct->index = 0; ct->user = BLI_findlink(&ct->users, ct->index); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index c2cfca295a4..772d87a9bf4 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -1067,6 +1067,7 @@ typedef struct ImageOpenData { typedef struct ImageFrameRange { struct ImageFrameRange *next, *prev; ListBase frames; + /** The full path of the first file in the list of image files */ char filepath[FILE_MAX]; } ImageFrameRange; @@ -1092,12 +1093,12 @@ static void image_open_cancel(bContext *UNUSED(C), wmOperator *op) /** * \brief Get a list of frames from the list of image files matching the first file name sequence pattern * \param ptr [in] the RNA pointer containing the "directory" entry and "files" collection - * \param frames [out] the list of frame numbers found in the files matching the first one by name - * \param path [out] the full path of the first file in the list of image files + * \param frames_all [out] the list of frame numbers found in the files matching the first one by name */ static void image_sequence_get_frame_ranges(PointerRNA *ptr, ListBase *frames_all) { char dir[FILE_MAXDIR]; + const bool do_frame_range = RNA_boolean_get(ptr, "use_sequence_detection"); ImageFrameRange *frame_range = NULL; RNA_string_get(ptr, "directory", dir); @@ -1113,7 +1114,8 @@ static void image_sequence_get_frame_ranges(PointerRNA *ptr, ListBase *frames_al frame->framenr = BLI_stringdec(filename, head, tail, &digits); /* still in the same sequence */ - if ((frame_range != NULL) && + if (do_frame_range && + (frame_range != NULL) && (STREQLEN(base_head, head, FILE_MAX)) && (STREQLEN(base_tail, tail, FILE_MAX))) { @@ -1448,6 +1450,9 @@ void IMAGE_OT_open(wmOperatorType *ot) ot, FILE_TYPE_FOLDER | FILE_TYPE_IMAGE | FILE_TYPE_MOVIE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILES | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA); + + RNA_def_boolean(ot->srna, "use_sequence_detection", true, "Detect Sequences", + "Automatically detect animated sequences in selected images (based on file names)"); } /******************** Match movie length operator ********************/ diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c index 0e427623840..b87a0de23b9 100644 --- a/source/blender/editors/space_info/info_ops.c +++ b/source/blender/editors/space_info/info_ops.c @@ -162,7 +162,6 @@ static int pack_all_exec(bContext *C, wmOperator *op) Main *bmain = CTX_data_main(C); packAll(bmain, op->reports, true); - G.fileflags |= G_AUTOPACK; return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c index 5355b8012db..c774b99629c 100644 --- a/source/blender/editors/space_nla/nla_buttons.c +++ b/source/blender/editors/space_nla/nla_buttons.c @@ -552,7 +552,7 @@ void nla_buttons_register(ARegionType *art) pt = MEM_callocN(sizeof(PanelType), "spacetype nla panel modifiers"); strcpy(pt->idname, "NLA_PT_modifiers"); strcpy(pt->label, N_("Modifiers")); - strcpy(pt->category, "Modifiers"); + strcpy(pt->category, "Modifiers"); strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA); pt->draw = nla_panel_modifiers; pt->poll = nla_strip_eval_panel_poll; diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 9dc39b1839b..5f8f839025f 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -2086,7 +2086,7 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op) /* make sure all clipboard nodes would be valid in the target tree */ all_nodes_valid = true; for (node = clipboard_nodes_lb->first; node; node = node->next) { - if (!node->typeinfo->poll_instance(node, ntree)) { + if (!node->typeinfo->poll_instance || !node->typeinfo->poll_instance(node, ntree)) { all_nodes_valid = false; BKE_reportf(op->reports, RPT_ERROR, "Cannot add node %s into node tree %s", node->name, ntree->id.name + 2); } diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index bbdf6feef01..2267316d257 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -753,6 +753,10 @@ static void node_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegi break; } break; + case NC_WM: + if (wmn->data == ND_JOB) + ED_region_tag_redraw(ar); + break; case NC_SCENE: case NC_MATERIAL: case NC_TEXTURE: diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index 335eb95da0e..265a19b9e7e 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -1944,7 +1944,7 @@ static int outliner_orphans_purge_invoke(bContext *C, wmOperator *op, const wmEv { /* present a prompt to informing users that this change is irreversible */ return WM_operator_confirm_message(C, op, - "Purging unused data-blocks cannot be undone. " + "Purging unused data-blocks cannot be undone and saves to current .blend file. " "Click here to proceed..."); } @@ -1966,7 +1966,8 @@ void OUTLINER_OT_orphans_purge(wmOperatorType *ot) /* identifiers */ ot->idname = "OUTLINER_OT_orphans_purge"; ot->name = "Purge All"; - ot->description = "Clear all orphaned data-blocks without any users from the file (cannot be undone)"; + ot->description = "Clear all orphaned data-blocks without any users from the file " + "(cannot be undone, saves to current .blend file)"; /* callbacks */ ot->invoke = outliner_orphans_purge_invoke; diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 7e05c76b35b..18cc2a015e6 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -707,7 +707,12 @@ static eOLDrawState tree_element_active_pose( { Object *ob = (Object *)tselem->id; Base *base = BKE_scene_base_find(scene, ob); - + + if (base == NULL) { + /* Armature not instantiated in current scene (e.g. inside an appended group...). */ + return OL_DRAWSEL_NONE; + } + if (set != OL_SETSEL_NONE) { if (scene->obedit) ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO); diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index cdb3df0fae9..29dcf73109c 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -235,8 +235,7 @@ static void unlink_group_cb( } else { Main *bmain = CTX_data_main(C); - BKE_libblock_unlink(bmain, group, false, false); - BKE_libblock_free(bmain, group); + BKE_libblock_delete(bmain, group); } } @@ -399,7 +398,7 @@ static void object_deselect_cb( static void object_delete_cb( bContext *C, ReportList *reports, Scene *scene, TreeElement *te, - TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data)) + TreeStoreElem *tsep, TreeStoreElem *tselem, void *user_data) { Base *base = (Base *)te->directdata; @@ -436,7 +435,7 @@ static void object_delete_cb( * Should not happen ideally, but does happens, see T51625. * Rather than twisting in all kind of ways to address all possible cases leading to that situation, simpler * to allow deleting such object as a mere generic data-block. */ - WM_operator_name_call(C, "OUTLINER_OT_id_delete", WM_OP_INVOKE_REGION_WIN, NULL); + id_delete_cb(C, reports, scene, te, tsep, tselem, user_data); } } @@ -1058,7 +1057,7 @@ static EnumPropertyItem prop_group_op_types[] = { {OL_GROUPOP_UNLINK, "UNLINK", 0, "Unlink Group", ""}, {OL_GROUPOP_LOCAL, "LOCAL", 0, "Make Local Group", ""}, {OL_GROUPOP_LINK, "LINK", 0, "Link Group Objects to Scene", ""}, - {OL_GROUPOP_DELETE, "DELETE", 0, "Delete Group", "WARNING: no undo"}, + {OL_GROUPOP_DELETE, "DELETE", 0, "Delete Group", ""}, {OL_GROUPOP_REMAP, "REMAP", 0, "Remap Users", "Make all users of selected data-blocks to use instead current (clicked) one"}, {OL_GROUPOP_INSTANCE, "INSTANCE", 0, "Instance Groups in Scene", ""}, @@ -1097,7 +1096,7 @@ static int outliner_group_operation_exec(bContext *C, wmOperator *op) DAG_relations_tag_update(CTX_data_main(C)); break; case OL_GROUPOP_DELETE: - WM_operator_name_call(C, "OUTLINER_OT_id_delete", WM_OP_INVOKE_REGION_WIN, NULL); + outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_delete_cb, NULL); break; case OL_GROUPOP_REMAP: outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_remap_cb, NULL); diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index ec46c5df9a0..09a49f201d4 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -1080,6 +1080,12 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i PointerRNA pptr, propptr, *ptr = (PointerRNA *)idv; PropertyRNA *prop, *iterprop; PropertyType proptype; + + /* Don't display arrays larger, weak but index is stored as a short, + * also the outliner isn't intended for editing such large data-sets. */ + BLI_STATIC_ASSERT(sizeof(te->index) == 2, "Index is no longer short!"); + const int tot_limit = SHRT_MAX; + int a, tot; /* we do lazy build, for speed and to avoid infinite recusion */ @@ -1101,6 +1107,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i iterprop = RNA_struct_iterator_property(ptr->type); tot = RNA_property_collection_length(ptr, iterprop); + CLAMP_MAX(tot, tot_limit); /* auto open these cases */ if (!parent || (RNA_property_type(parent->directdata)) == PROP_POINTER) @@ -1147,6 +1154,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i } else if (proptype == PROP_COLLECTION) { tot = RNA_property_collection_length(ptr, prop); + CLAMP_MAX(tot, tot_limit); if (TSELEM_OPEN(tselem, soops)) { for (a = 0; a < tot; a++) { @@ -1159,6 +1167,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i } else if (ELEM(proptype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) { tot = RNA_property_array_length(ptr, prop); + CLAMP_MAX(tot, tot_limit); if (TSELEM_OPEN(tselem, soops)) { for (a = 0; a < tot; a++) diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 2d6892c1091..3ae4a233353 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -3352,6 +3352,9 @@ static int sequencer_swap_data_exec(bContext *C, wmOperator *op) if (seq_act->sound) BKE_sound_add_scene_sound_defaults(scene, seq_act); if (seq_other->sound) BKE_sound_add_scene_sound_defaults(scene, seq_other); + BKE_sequence_invalidate_cache(scene, seq_act); + BKE_sequence_invalidate_cache(scene, seq_other); + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index 48c49f36471..d88ed36e392 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -683,7 +683,7 @@ static int sequencer_select_less_exec(bContext *C, wmOperator *UNUSED(op)) if (!select_more_less_seq__internal(scene, false, false)) return OPERATOR_CANCELLED; - + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene); return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_text/text_autocomplete.c b/source/blender/editors/space_text/text_autocomplete.c index 9b0bd30ff11..da5fa9da046 100644 --- a/source/blender/editors/space_text/text_autocomplete.c +++ b/source/blender/editors/space_text/text_autocomplete.c @@ -328,7 +328,7 @@ static int text_autocomplete_modal(bContext *C, wmOperator *op, const wmEvent *e if (tools & TOOL_SUGG_LIST) { texttool_suggest_clear(); } - if (tools & TOOL_DOCUMENT) { + if (tools & TOOL_DOCUMENT) { texttool_docs_clear(); doc_scroll = 0; } diff --git a/source/blender/editors/space_text/text_format_pov.c b/source/blender/editors/space_text/text_format_pov.c index eb6877d297d..0d19c503798 100644 --- a/source/blender/editors/space_text/text_format_pov.c +++ b/source/blender/editors/space_text/text_format_pov.c @@ -100,6 +100,7 @@ static int txtfmt_pov_find_reserved_keywords(const char *string) else if (STR_LITERAL_STARTSWITH(string, "adc_bailout", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "albedo", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "all_intersections", len)) i = len; + else if (STR_LITERAL_STARTSWITH(string, "translucency", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "all", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "alpha", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "altitude", len)) i = len; @@ -149,7 +150,6 @@ static int txtfmt_pov_find_reserved_keywords(const char *string) else if (STR_LITERAL_STARTSWITH(string, "falloff_angle", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "falloff", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "file_gamma", len)) i = len; - else if (STR_LITERAL_STARTSWITH(string, "finish", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "flatness", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "flip", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "focal_point", len)) i = len; @@ -372,6 +372,7 @@ static int txtfmt_pov_find_reserved_builtins(const char *string) else if (STR_LITERAL_STARTSWITH(string, "mesh", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "object", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "ovus", len)) i = len; + else if (STR_LITERAL_STARTSWITH(string, "lemon", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "parametric", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "plane", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "poly", len)) i = len; @@ -383,6 +384,7 @@ static int txtfmt_pov_find_reserved_builtins(const char *string) else if (STR_LITERAL_STARTSWITH(string, "rainbow", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "sky_sphere", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "smooth_triangle", len)) i = len; + else if (STR_LITERAL_STARTSWITH(string, "cubic_spline", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "sphere_sweep", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "sphere", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "spline", len)) i = len; @@ -463,7 +465,12 @@ static int txtfmt_pov_find_specialvar(const char *string) { int i, len; /* Modifiers */ - if (STR_LITERAL_STARTSWITH(string, "adaptive", len)) i = len; + if (STR_LITERAL_STARTSWITH(string, "interior_texture", len)) i = len; + else if (STR_LITERAL_STARTSWITH(string, "double_illuminate", len)) i = len; + else if (STR_LITERAL_STARTSWITH(string, "media_interaction", len)) i = len; + else if (STR_LITERAL_STARTSWITH(string, "media_attenuation", len)) i = len; + else if (STR_LITERAL_STARTSWITH(string, "projected_through", len)) i = len; + else if (STR_LITERAL_STARTSWITH(string, "noise_generator", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "agate_turb", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "bounded_by", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "brick_size", len)) i = len; @@ -481,7 +488,6 @@ static int txtfmt_pov_find_specialvar(const char *string) else if (STR_LITERAL_STARTSWITH(string, "cubic_wave", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "density_map", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "density", len)) i = len; - else if (STR_LITERAL_STARTSWITH(string, "double_illuminate", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "fade_color", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "fade_colour", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "fade_distance", len)) i = len; @@ -490,7 +496,7 @@ static int txtfmt_pov_find_specialvar(const char *string) else if (STR_LITERAL_STARTSWITH(string, "global_lights", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "hollow", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "image_map", len)) i = len; - else if (STR_LITERAL_STARTSWITH(string, "interior_texture", len)) i = len; + else if (STR_LITERAL_STARTSWITH(string, "adaptive", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "interior", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "interpolate", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "inverse", len)) i = len; @@ -501,8 +507,6 @@ static int txtfmt_pov_find_specialvar(const char *string) else if (STR_LITERAL_STARTSWITH(string, "material", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "matrix", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "media", len)) i = len; - else if (STR_LITERAL_STARTSWITH(string, "media_attenuation", len)) i = len; - else if (STR_LITERAL_STARTSWITH(string, "media_interaction", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "mm_per_unit", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "mortar", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "no_bump_scale", len)) i = len; @@ -510,7 +514,6 @@ static int txtfmt_pov_find_specialvar(const char *string) else if (STR_LITERAL_STARTSWITH(string, "no_radiosity", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "no_reflection", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "no_shadow", len)) i = len; - else if (STR_LITERAL_STARTSWITH(string, "noise_generator", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "normal_map", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "normal", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "octaves", len)) i = len; @@ -522,8 +525,8 @@ static int txtfmt_pov_find_specialvar(const char *string) else if (STR_LITERAL_STARTSWITH(string, "photons", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "pigment_map", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "pigment", len)) i = len; + else if (STR_LITERAL_STARTSWITH(string, "finish", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "poly_wave", len)) i = len; - else if (STR_LITERAL_STARTSWITH(string, "projected_through", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "quick_color", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "quick_colour", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "ramp_wave", len)) i = len; @@ -693,9 +696,9 @@ static void txtfmt_pov_format_line(SpaceText *st, TextLine *line, const bool do_ } /* Handle continuations */ else if (cont) { - /* Multi-line comments */ + /* C-Style comments */ if (cont & FMT_CONT_COMMENT_C) { - if (*str == ']' && *(str + 1) == ']') { + if (*str == '*' && *(str + 1) == '/') { *fmt = FMT_TYPE_COMMENT; fmt++; str++; *fmt = FMT_TYPE_COMMENT; cont = FMT_CONT_NOP; @@ -752,7 +755,7 @@ static void txtfmt_pov_format_line(SpaceText *st, TextLine *line, const bool do_ } } /* Punctuation */ - else if ((*str != '#') && text_check_delim(*str)) { + else if (text_check_delim(*str)) { *fmt = FMT_TYPE_SYMBOL; } /* Identifiers and other text (no previous ws. or delims. so text continues) */ diff --git a/source/blender/editors/space_text/text_format_pov_ini.c b/source/blender/editors/space_text/text_format_pov_ini.c index 5c20a1c5f00..719f4e3c036 100644 --- a/source/blender/editors/space_text/text_format_pov_ini.c +++ b/source/blender/editors/space_text/text_format_pov_ini.c @@ -104,7 +104,11 @@ static int txtfmt_ini_find_reserved(const char *string) * list is from... * http://www.povray.org/documentation/view/3.7.0/212/ */ - if (STR_LITERAL_STARTSWITH(string, "clock_delta", len)) i = len; + if (STR_LITERAL_STARTSWITH(string, "Antialias_Threshold", len)) i = len; + else if (STR_LITERAL_STARTSWITH(string, "Bounding_Method", len)) i = len; + else if (STR_LITERAL_STARTSWITH(string, "Antialias_Gamma", len)) i = len; + else if (STR_LITERAL_STARTSWITH(string, "Antialias_Depth", len)) i = len; + else if (STR_LITERAL_STARTSWITH(string, "clock_delta", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "clock_on", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "clock", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "final_clock", len)) i = len; @@ -134,6 +138,7 @@ static int txtfmt_ini_find_reserved(const char *string) else if (STR_LITERAL_STARTSWITH(string, "Create_Ini", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "Display_Gamma", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "Display", len)) i = len; + else if (STR_LITERAL_STARTSWITH(string, "Version", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "Pause_When_Done", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "Verbose", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "Preview_Start_Size", len)) i = len; @@ -183,7 +188,6 @@ static int txtfmt_ini_find_reserved(const char *string) else if (STR_LITERAL_STARTSWITH(string, "Split_Unions", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "Antialias", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "Sampling_Method", len)) i = len; - else if (STR_LITERAL_STARTSWITH(string, "Antialias_Threshold", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "Jitter_Amount", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "Jitter", len)) i = len; else if (STR_LITERAL_STARTSWITH(string, "Antialias_Depth", len)) i = len; diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index 314b7bf3335..5208013b6fe 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -1903,6 +1903,11 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, } } + /* custom bone may draw outline double-width */ + if (arm->flag & ARM_POSEMODE) { + glLineWidth(1.0f); + } + /* draw custom bone shapes as wireframes */ if (!(arm->flag & ARM_NO_CUSTOM) && (draw_wire || (dt <= OB_WIRE)) ) @@ -1968,11 +1973,6 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, index = -1; } } - - /* custom bone may draw outline double-width */ - if (arm->flag & ARM_POSEMODE) { - glLineWidth(1.0f); - } /* wire draw over solid only in posemode */ if ((dt <= OB_WIRE) || (arm->flag & ARM_POSEMODE) || ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) { diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 884bc6b83ba..3f11703973d 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -7347,7 +7347,7 @@ static void draw_object_wire_color(Scene *scene, Base *base, unsigned char r_ob_ theme_id = TH_GROUP_ACTIVE; if (scene->basact != base) { - theme_shade = -16; + theme_shade = -32; } } else { diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index eda4d51e7e8..5c13fd37dda 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -1191,7 +1191,7 @@ int view3d_opengl_select( hits = GPU_select_end(); /* second pass, to get the closest object to camera */ - if (do_passes) { + if (do_passes && (hits > 0)) { GPU_select_begin(buffer, bufsize, &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits); ED_view3d_draw_select_loop(vc, scene, v3d, ar, use_obedit_skip, use_nearest); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index d786c755529..ca6e2267218 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -3051,19 +3051,13 @@ static void Bend(TransInfo *t, const int UNUSED(mval[2])) /** \name Transform Shear * \{ */ -static void postInputShear(TransInfo *UNUSED(t), float values[3]) -{ - mul_v3_fl(values, 0.05f); -} - static void initShear(TransInfo *t) { t->mode = TFM_SHEAR; t->transform = applyShear; t->handleEvent = handleEventShear; - - setInputPostFct(&t->mouse, postInputShear); - initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE); + + initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO); t->idx_max = 0; t->num.idx_max = 0; @@ -3085,24 +3079,24 @@ static eRedrawFlag handleEventShear(TransInfo *t, const wmEvent *event) if (event->type == MIDDLEMOUSE && event->val == KM_PRESS) { /* Use custom.mode.data pointer to signal Shear direction */ if (t->custom.mode.data == NULL) { - initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE); + initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_RATIO); t->custom.mode.data = (void *)1; } else { - initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE); + initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO); t->custom.mode.data = NULL; } status = TREDRAW_HARD; } else if (event->type == XKEY && event->val == KM_PRESS) { - initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE); + initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO); t->custom.mode.data = NULL; status = TREDRAW_HARD; } else if (event->type == YKEY && event->val == KM_PRESS) { - initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE); + initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_RATIO); t->custom.mode.data = (void *)1; status = TREDRAW_HARD; @@ -4073,13 +4067,15 @@ static void initTrackball(TransInfo *t) static void applyTrackballValue(TransInfo *t, const float axis1[3], const float axis2[3], float angles[2]) { TransData *td = t->data; - float mat[3][3], smat[3][3], totmat[3][3]; + float mat[3][3]; + float axis[3]; + float angle; int i; - axis_angle_normalized_to_mat3(smat, axis1, angles[0]); - axis_angle_normalized_to_mat3(totmat, axis2, angles[1]); - - mul_m3_m3m3(mat, smat, totmat); + mul_v3_v3fl(axis, axis1, angles[0]); + madd_v3_v3fl(axis, axis2, angles[1]); + angle = normalize_v3(axis); + axis_angle_normalized_to_mat3(mat, axis, angle); for (i = 0; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) @@ -4089,10 +4085,7 @@ static void applyTrackballValue(TransInfo *t, const float axis1[3], const float continue; if (t->flag & T_PROP_EDIT) { - axis_angle_normalized_to_mat3(smat, axis1, td->factor * angles[0]); - axis_angle_normalized_to_mat3(totmat, axis2, td->factor * angles[1]); - - mul_m3_m3m3(mat, smat, totmat); + axis_angle_normalized_to_mat3(mat, axis, td->factor * angle); } ElementRotation(t, td, mat, t->around); @@ -4278,7 +4271,7 @@ static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_ bUnit_AsString(distvec, sizeof(distvec), dist * t->scene->unit.scale_length, 4, t->scene->unit.system, B_UNIT_LENGTH, do_split, false); } - else if (dist > 1e10f || dist < -1e10f) { + else if (dist > 1e10f || dist < -1e10f) { /* prevent string buffer overflow */ BLI_snprintf(distvec, NUM_STR_REP_LEN, "%.4e", dist); } @@ -5565,7 +5558,7 @@ static void slide_origdata_interp_data_vert( float v_proj[3][3]; if (do_loop_weight || do_loop_mdisps) { - project_plane_v3_v3v3(v_proj[1], sv->co_orig_3d, v_proj_axis); + project_plane_normalized_v3_v3v3(v_proj[1], sv->co_orig_3d, v_proj_axis); } // BM_ITER_ELEM (l, &liter, sv->v, BM_LOOPS_OF_VERT) { @@ -5599,19 +5592,19 @@ static void slide_origdata_interp_data_vert( /* In the unlikely case that we're next to a zero length edge - walk around the to the next. * Since we only need to check if the vertex is in this corner, * its not important _which_ loop - as long as its not overlapping 'sv->co_orig_3d', see: T45096. */ - project_plane_v3_v3v3(v_proj[0], co_prev, v_proj_axis); + project_plane_normalized_v3_v3v3(v_proj[0], co_prev, v_proj_axis); while (UNLIKELY(((co_prev_ok = (len_squared_v3v3(v_proj[1], v_proj[0]) > eps)) == false) && ((l_prev = l_prev->prev) != l->next))) { co_prev = slide_origdata_orig_vert_co(sod, l_prev->v); - project_plane_v3_v3v3(v_proj[0], co_prev, v_proj_axis); + project_plane_normalized_v3_v3v3(v_proj[0], co_prev, v_proj_axis); } - project_plane_v3_v3v3(v_proj[2], co_next, v_proj_axis); + project_plane_normalized_v3_v3v3(v_proj[2], co_next, v_proj_axis); while (UNLIKELY(((co_next_ok = (len_squared_v3v3(v_proj[1], v_proj[2]) > eps)) == false) && ((l_next = l_next->next) != l->prev))) { co_next = slide_origdata_orig_vert_co(sod, l_next->v); - project_plane_v3_v3v3(v_proj[2], co_next, v_proj_axis); + project_plane_normalized_v3_v3v3(v_proj[2], co_next, v_proj_axis); } if (co_prev_ok && co_next_ok) { diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 04b9ae75c8f..b7a42121e92 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -771,34 +771,43 @@ int count_set_pose_transflags(int *out_mode, short around, Object *ob) /* -------- Auto-IK ---------- */ /* adjust pose-channel's auto-ik chainlen */ -static void pchan_autoik_adjust(bPoseChannel *pchan, short chainlen) +static bool pchan_autoik_adjust(bPoseChannel *pchan, short chainlen) { bConstraint *con; + bool changed = false; /* don't bother to search if no valid constraints */ - if ((pchan->constflag & (PCHAN_HAS_IK | PCHAN_HAS_TARGET)) == 0) - return; + if ((pchan->constflag & (PCHAN_HAS_IK | PCHAN_HAS_TARGET)) == 0) { + return changed; + } /* check if pchan has ik-constraint */ for (con = pchan->constraints.first; con; con = con->next) { if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->enforce != 0.0f)) { bKinematicConstraint *data = con->data; - + /* only accept if a temporary one (for auto-ik) */ if (data->flag & CONSTRAINT_IK_TEMP) { /* chainlen is new chainlen, but is limited by maximum chainlen */ - if ((chainlen == 0) || (chainlen > data->max_rootbone)) + const int old_rootbone = data->rootbone; + if ((chainlen == 0) || (chainlen > data->max_rootbone)) { data->rootbone = data->max_rootbone; - else + } + else { data->rootbone = chainlen; + } + changed |= (data->rootbone != old_rootbone); } } } + + return changed; } /* change the chain-length of auto-ik */ void transform_autoik_update(TransInfo *t, short mode) { + const short old_len = t->settings->autoik_chainlen; short *chainlen = &t->settings->autoik_chainlen; bPoseChannel *pchan; @@ -812,13 +821,29 @@ void transform_autoik_update(TransInfo *t, short mode) if (*chainlen > 0) (*chainlen)--; } + /* IK length did not change, skip any updates. */ + if (old_len == *chainlen) { + return; + } + /* sanity checks (don't assume t->poseobj is set, or that it is an armature) */ if (ELEM(NULL, t->poseobj, t->poseobj->pose)) return; /* apply to all pose-channels */ + bool changed = false; for (pchan = t->poseobj->pose->chanbase.first; pchan; pchan = pchan->next) { - pchan_autoik_adjust(pchan, *chainlen); + changed |= pchan_autoik_adjust(pchan, *chainlen); + } + +#ifdef WITH_LEGACY_DEPSGRAPH + if (!DEG_depsgraph_use_legacy()) +#endif + { + if (changed) { + /* TODO(sergey): Consider doing partial update only. */ + DAG_relations_tag_update(G.main); + } } } @@ -2008,9 +2033,9 @@ static bool bmesh_test_dist_add( } /** - * \parm mtx: Measure disatnce in this space. - * \parm dists: Store the closest connected distance to selected vertices. - * \parm index: Optionally store the original index we're measuring the distance to (can be NULL). + * \param mtx: Measure disatnce in this space. + * \param dists: Store the closest connected distance to selected vertices. + * \param index: Optionally store the original index we're measuring the distance to (can be NULL). */ static void editmesh_set_connectivity_distance(BMesh *bm, float mtx[3][3], float *dists, int *index) { @@ -2280,7 +2305,7 @@ static struct TransIslandData *editmesh_islands_info_calc( } if (group_tot_single != 0) { - trans_islands = MEM_reallocN(trans_islands, group_tot + group_tot_single); + trans_islands = MEM_reallocN(trans_islands, sizeof(*trans_islands) * (group_tot + group_tot_single)); BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) { if (BM_elem_flag_test(v, BM_ELEM_SELECT) && (vert_map[i] == -1)) { @@ -2402,7 +2427,8 @@ static void createTransEditVerts(TransInfo *t) int island_info_tot; int *island_vert_map = NULL; - const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS) && (t->mode != TFM_TRANSLATION); + /* Even for translation this is needed because of island-orientation, see: T51651. */ + const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS); /* Original index of our connected vertex when connected distances are calculated. * Optional, allocate if needed. */ int *dists_index = NULL; @@ -2468,11 +2494,6 @@ static void createTransEditVerts(TransInfo *t) editmesh_set_connectivity_distance(em->bm, mtx, dists, dists_index); } - /* Only in case of rotation and resize, we want the elements of the edited - * object to behave as groups whose pivot are the individual origins - * - * TODO: use island_info to detect the closest point when the "Snap Target" - * in Blender UI is "Closest" */ if (is_island_center) { /* In this specific case, near-by vertices will need to know the island of the nearest connected vertex. */ const bool calc_single_islands = ( @@ -5353,7 +5374,8 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) } /* 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); + sub_v3_v3(ob->loc, ob->dloc); + BKE_object_mat3_to_rot(ob, rot, false); /* drot is already corrected here */ } } diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index f78a23be7b8..c23da19f830 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -971,7 +971,7 @@ static void recalcData_sequencer(TransInfo *t) /* force recalculation of triangles during transformation */ static void recalcData_gpencil_strokes(TransInfo *t) - { +{ TransData *td = t->data; for (int i = 0; i < t->total; i++, td++) { bGPDstroke *gps = td->extra; diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c index 22c39d6ed0c..5f2e5a99090 100644 --- a/source/blender/editors/transform/transform_input.c +++ b/source/blender/editors/transform/transform_input.c @@ -86,12 +86,11 @@ static void InputTrackBall(TransInfo *UNUSED(t), MouseInput *mi, const double mv output[1] *= mi->factor; } -static void InputHorizontalRatio(TransInfo *t, MouseInput *UNUSED(mi), const double mval[2], float output[3]) +static void InputHorizontalRatio(TransInfo *t, MouseInput *mi, const double mval[2], float output[3]) { const int winx = t->ar ? t->ar->winx : 1; - const double pad = winx / 10; - output[0] = (mval[0] - pad) / (winx - 2 * pad); + output[0] = ((mval[0] - mi->imval[0]) / winx) * 2.0f; } static void InputHorizontalAbsolute(TransInfo *t, MouseInput *mi, const double mval[2], float output[3]) @@ -104,12 +103,11 @@ static void InputHorizontalAbsolute(TransInfo *t, MouseInput *mi, const double m output[0] = dot_v3v3(t->viewinv[0], vec) * 2.0f; } -static void InputVerticalRatio(TransInfo *t, MouseInput *UNUSED(mi), const double mval[2], float output[3]) +static void InputVerticalRatio(TransInfo *t, MouseInput *mi, const double mval[2], float output[3]) { const int winy = t->ar ? t->ar->winy : 1; - const double pad = winy / 10; - output[0] = (mval[1] - pad) / (winy - 2 * pad); + output[0] = ((mval[1] - mi->imval[1]) / winy) * 2.0f; } static void InputVerticalAbsolute(TransInfo *t, MouseInput *mi, const double mval[2], float output[3]) @@ -314,7 +312,6 @@ void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode) t->helpline = HLP_TRACKBALL; break; case INPUT_HORIZONTAL_RATIO: - mi->factor = (float)(mi->center[0] - mi->imval[0]); mi->apply = InputHorizontalRatio; t->helpline = HLP_HARROW; break; diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index ab2a0225abc..ec066ba91a4 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -1755,7 +1755,7 @@ static int manipulator_selectbuf(Scene *scene, ScrArea *sa, ARegion *ar, const i hits = GPU_select_end(); - if (do_passes) { + if (do_passes && (hits > 0)) { GPU_select_begin(buffer, 64, &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits); /* do the drawing */ diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index b33528b4149..aecd24d4e40 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -234,7 +234,7 @@ static void raycast_all_cb(void *userdata, int index, const BVHTreeRay *ray, BVH /* -------------------------------------------------------------------- */ -/** \Common utilities +/** Common utilities * \{ */ /** @@ -620,7 +620,7 @@ static float dist_aabb_to_plane( /* -------------------------------------------------------------------- */ -/** \Walk DFS +/** Walk DFS * \{ */ typedef void (*Nearest2DGetEdgeVertsCallback)(const int index, const float *v_pair[2], void *data); diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c index 4e021d4833e..419c15bf83f 100644 --- a/source/blender/editors/util/undo.c +++ b/source/blender/editors/util/undo.c @@ -334,6 +334,12 @@ static int ed_undo_redo_exec(bContext *C, wmOperator *UNUSED(op)) return ret ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } +static int ed_undo_redo_poll(bContext *C) +{ + wmOperator *last_op = WM_operator_last_redo(C); + return last_op && ED_operator_screenactive(C) && + WM_operator_check_ui_enabled(C, last_op->type->name); +} /* ********************** */ @@ -385,7 +391,7 @@ void ED_OT_undo_redo(wmOperatorType *ot) /* api callbacks */ ot->exec = ed_undo_redo_exec; - ot->poll = ED_operator_screenactive; + ot->poll = ed_undo_redo_poll; } /* ui callbacks should call this rather than calling WM_operator_repeat() themselves */ diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c index bdfff123aa4..8c76d03035a 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.c +++ b/source/blender/editors/uvedit/uvedit_parametrizer.c @@ -2859,7 +2859,7 @@ static PBool p_chart_symmetry_pins(PChart *chart, PEdge *outer, PVert **pin1, PV PEdge *cure = NULL, *firste1 = NULL, *firste2 = NULL, *nextbe; float maxlen = 0.0f, curlen = 0.0f, totlen = 0.0f, firstlen = 0.0f; float len1, len2; - + /* find longest series of verts split in the chart itself, these are * marked during construction */ be = outer; diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp index f63cf771120..1dbac1848b7 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp @@ -524,7 +524,7 @@ void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const // We'll generate both with tips and without tips // coordinates, on two different UV layers. - if (ma->mtex[a]->texflag & MTEX_TIPS) { + if (ma->mtex[a]->texflag & MTEX_TIPS) { BLI_strncpy(ma->mtex[a]->uvname, uvNames[1], sizeof(ma->mtex[a]->uvname)); } else { diff --git a/source/blender/freestyle/intern/geometry/matrix_util.h b/source/blender/freestyle/intern/geometry/matrix_util.h index d65b0ea803b..444fd7c4785 100644 --- a/source/blender/freestyle/intern/geometry/matrix_util.h +++ b/source/blender/freestyle/intern/geometry/matrix_util.h @@ -50,15 +50,15 @@ namespace MatrixUtil { /** * computes the eigen values and eigen vectors of a semi definite symmetric matrix * - * @param matrix is stored in column symmetric storage, i.e. + * \param mat: The matrix stored in column symmetric storage, i.e. * matrix = { m11, m12, m22, m13, m23, m33, m14, m24, m34, m44 ... } * size = n(n+1)/2 * - * @param eigen_vectors (return) = { v1, v2, v3, ..., vn } + * \param eigen_vec: (return) = { v1, v2, v3, ..., vn } * where vk = vk0, vk1, ..., vkn * size = n^2, must be allocated by caller * - * @param eigen_values (return) are in decreasing order + * \param eigen_val: (return) are in decreasing order * size = n, must be allocated by caller */ void semi_definite_symmetric_eigen(const double *mat, int n, double *eigen_vec, double *eigen_val); diff --git a/source/blender/gpu/intern/gpu_select.c b/source/blender/gpu/intern/gpu_select.c index 9496ff137dc..632b0cfee1b 100644 --- a/source/blender/gpu/intern/gpu_select.c +++ b/source/blender/gpu/intern/gpu_select.c @@ -75,6 +75,12 @@ static GPUSelectState g_select_state = {0}; */ void GPU_select_begin(unsigned int *buffer, unsigned int bufsize, const rcti *input, char mode, int oldhits) { + if (mode == GPU_SELECT_NEAREST_SECOND_PASS) { + /* In the case hits was '-1', don't start the second pass since it's not going to give useful results. + * As well as buffer overflow in 'gpu_select_query_load_id'. */ + BLI_assert(oldhits != -1); + } + g_select_state.select_is_active = true; g_select_state.use_gpu_select = GPU_select_query_check_active(); g_select_state.mode = mode; diff --git a/source/blender/gpu/intern/gpu_select_sample_query.c b/source/blender/gpu/intern/gpu_select_sample_query.c index ba5fefc5227..3d589986281 100644 --- a/source/blender/gpu/intern/gpu_select_sample_query.c +++ b/source/blender/gpu/intern/gpu_select_sample_query.c @@ -142,13 +142,17 @@ bool gpu_select_query_load_id(unsigned int id) g_query_state.active_query++; g_query_state.query_issued = true; - if (g_query_state.mode == GPU_SELECT_NEAREST_SECOND_PASS && g_query_state.index < g_query_state.oldhits) { - if (g_query_state.buffer[g_query_state.index][3] == id) { - g_query_state.index++; - return true; - } - else { - return false; + if (g_query_state.mode == GPU_SELECT_NEAREST_SECOND_PASS) { + /* Second pass should never run if first pass fails, can read past 'bufsize' in this case. */ + BLI_assert(g_query_state.oldhits != -1); + if (g_query_state.index < g_query_state.oldhits) { + if (g_query_state.buffer[g_query_state.index][3] == id) { + g_query_state.index++; + return true; + } + else { + return false; + } } } diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 5c52b7fd153..f14db57a26a 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -2621,29 +2621,26 @@ void node_bsdf_toon(vec4 color, float size, float tsmooth, vec3 N, out vec4 resu void node_bsdf_principled(vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular, float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat, - float clearcoat_gloss, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, out vec4 result) + float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, out vec4 result) { /* ambient light */ // TODO: set ambient light to an appropriate value - vec3 L = vec3(mix(0.1, 0.03, metallic)) * base_color.rgb; + vec3 L = mix(0.1, 0.03, metallic) * mix(base_color.rgb, subsurface_color.rgb, subsurface * (1.0 - metallic)); float eta = (2.0 / (1.0 - sqrt(0.08 * specular))) - 1.0; /* set the viewing vector */ - vec3 V = -normalize(I); + vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ? -normalize(I) : vec3(0.0, 0.0, 1.0); /* get the tangent */ vec3 Tangent = T; if (T == vec3(0.0)) { // if no tangent is set, use a default tangent - Tangent = vec3(1.0, 0.0, 0.0); - if (N.x != 0.0 || N.y != 0.0) { - vec3 N_xz = normalize(vec3(N.x, 0.0, N.z)); - - vec3 axis = normalize(cross(vec3(0.0, 0.0, 1.0), N_xz)); - float angle = acos(dot(vec3(0.0, 0.0, 1.0), N_xz)); - - Tangent = normalize(rotate_vector(vec3(1.0, 0.0, 0.0), axis, angle)); + if(N.x != N.y || N.x != N.z) { + Tangent = vec3(N.z-N.y, N.x-N.z, N.y-N.x); // (1,1,1) x N + } + else { + Tangent = vec3(N.z-N.y, N.x+N.z, -N.y-N.x); // (-1,1,1) x N } } @@ -2663,10 +2660,11 @@ void node_bsdf_principled(vec4 base_color, float subsurface, vec3 subsurface_rad /* directional lights */ for (int i = 0; i < NUM_LIGHTS; i++) { vec3 light_position_world = gl_LightSource[i].position.xyz; - vec3 light_position = normalize(gl_NormalMatrix * light_position_world); + vec3 light_position = normalize(light_position_world); vec3 H = normalize(light_position + V); + vec3 light_diffuse = gl_LightSource[i].diffuse.rgb; vec3 light_specular = gl_LightSource[i].specular.rgb; float NdotL = dot(N, light_position); @@ -2711,8 +2709,9 @@ void node_bsdf_principled(vec4 base_color, float subsurface, vec3 subsurface_rad // sheen vec3 Fsheen = schlick_fresnel(LdotH) * sheen * Csheen; - diffuse_and_specular_bsdf = (M_1_PI * mix(Fd, ss, subsurface) * base_color.rgb + Fsheen) - * (1.0 - metallic) + Gs * Fs * Ds; + vec3 diffuse_bsdf = (mix(Fd * base_color.rgb, ss * subsurface_color.rgb, subsurface) + Fsheen) * light_diffuse; + vec3 specular_bsdf = Gs * Fs * Ds * light_specular; + diffuse_and_specular_bsdf = diffuse_bsdf * (1.0 - metallic) + specular_bsdf; } diffuse_and_specular_bsdf *= max(NdotL, 0.0); @@ -2725,15 +2724,15 @@ void node_bsdf_principled(vec4 base_color, float subsurface, vec3 subsurface_rad //float FH = schlick_fresnel(LdotH); // clearcoat (ior = 1.5 -> F0 = 0.04) - float Dr = GTR1(CNdotH, mix(0.1, 0.001, clearcoat_gloss)); + float Dr = GTR1(CNdotH, sqr(clearcoat_roughness)); float Fr = fresnel_dielectric_cos(LdotH, 1.5); //mix(0.04, 1.0, FH); float Gr = smithG_GGX(CNdotL, 0.25) * smithG_GGX(CNdotV, 0.25); - clearcoat_bsdf = clearcoat * Gr * Fr * Dr * vec3(0.25); + clearcoat_bsdf = clearcoat * Gr * Fr * Dr * vec3(0.25) * light_specular; } clearcoat_bsdf *= max(CNdotL, 0.0); - L += light_specular * (diffuse_and_specular_bsdf + clearcoat_bsdf); + L += diffuse_and_specular_bsdf + clearcoat_bsdf; } result = vec4(L, 1.0); @@ -3032,10 +3031,10 @@ vec2 calc_brick_texture(vec3 p, float mortar_size, float mortar_smooth, float bi float tint = clamp((integer_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias), 0.0, 1.0); float min_dist = min(min(x, y), min(brick_width - x, row_height - y)); - if(min_dist >= mortar_size) { + if (min_dist >= mortar_size) { return vec2(tint, 0.0); } - else if(mortar_smooth == 0.0) { + else if (mortar_smooth == 0.0) { return vec2(tint, 1.0); } else { diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index 93d2b3e0cd0..e7abfdc7d67 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -166,7 +166,7 @@ struct ImBuf *IMB_makeSingleUser(struct ImBuf *ibuf); * * \attention Defined in allocimbuf.c */ -struct ImBuf *IMB_dupImBuf(struct ImBuf *ibuf1); +struct ImBuf *IMB_dupImBuf(const struct ImBuf *ibuf1); /** * diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h index f4b2539d7d7..1701c2ba307 100644 --- a/source/blender/imbuf/IMB_imbuf_types.h +++ b/source/blender/imbuf/IMB_imbuf_types.h @@ -237,9 +237,8 @@ typedef struct ImBuf { /** * \name Imbuf Component flags * \brief These flags determine the components of an ImBuf struct. - */ -/**@{*/ -/** \brief Flag defining the components of the ImBuf struct. */ + * + * \{ */ #define IB_rect (1 << 0) #define IB_test (1 << 1) @@ -259,15 +258,20 @@ typedef struct ImBuf { #define IB_thumbnail (1 << 15) #define IB_multiview (1 << 16) +/** \} */ + /** * \name Imbuf preset profile tags * \brief Some predefined color space profiles that 8 bit imbufs can represent - */ + * + * \{ */ #define IB_PROFILE_NONE 0 #define IB_PROFILE_LINEAR_RGB 1 #define IB_PROFILE_SRGB 2 #define IB_PROFILE_CUSTOM 3 +/** \} */ + /* dds */ #ifdef WITH_DDS #ifndef DDS_MAKEFOURCC @@ -298,8 +302,16 @@ extern const char *imb_ext_audio[]; /* image formats that can only be loaded via filepath */ extern const char *imb_ext_image_filepath_only[]; +/** + * \name Imbuf Color Management Flag + * \brief Used with #ImBuf.colormanage_flag + * + * \{ */ + enum { IMB_COLORMANAGE_IS_DATA = (1 << 0) }; -#endif +/** \} */ + +#endif /* __IMB_IMBUF_TYPES_H__ */ diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c index 33750478bb4..6e9bfa1fc4e 100644 --- a/source/blender/imbuf/intern/allocimbuf.c +++ b/source/blender/imbuf/intern/allocimbuf.c @@ -506,7 +506,7 @@ bool IMB_initImBuf(struct ImBuf *ibuf, } /* does no zbuffers? */ -ImBuf *IMB_dupImBuf(ImBuf *ibuf1) +ImBuf *IMB_dupImBuf(const ImBuf *ibuf1) { ImBuf *ibuf2, tbuf; int flags = 0; diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c index 8b4e95ac452..429a19936a5 100644 --- a/source/blender/imbuf/intern/cineon/dpxlib.c +++ b/source/blender/imbuf/intern/cineon/dpxlib.c @@ -183,7 +183,7 @@ LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t buf if (verbose) printf("DPX: File is LSB.\n"); } else { - if (verbose) { + if (verbose) { printf("DPX: Bad magic number %u in \"%s\".\n", header.fileHeader.magic_num, byteStuff); } diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index 1deb9bf3787..f6bed37dfa2 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -323,7 +323,7 @@ typedef struct ParticleSystem { struct ParticleDrawData *pdd; float dt_frac; /* current time step, as a fraction of a frame */ - float _pad; /* spare capacity */ + float lattice_strength; /* influence of the lattice modifier */ } ParticleSystem; typedef enum eParticleDrawFlag { diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index a299302f04f..5a4db47d281 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -6446,7 +6446,7 @@ static int rna_function_parameter_parse(PointerRNA *ptr, PropertyRNA *prop, Prop tid, fid, pid, RNA_struct_identifier(ptype), RNA_struct_identifier(srna)); return -1; } - + *((void **)dest) = *((void **)src); break; diff --git a/source/blender/makesrna/intern/rna_linestyle.c b/source/blender/makesrna/intern/rna_linestyle.c index 1199cccc4e6..a163d9764c1 100644 --- a/source/blender/makesrna/intern/rna_linestyle.c +++ b/source/blender/makesrna/intern/rna_linestyle.c @@ -1620,6 +1620,7 @@ static void rna_def_linestyle(BlenderRNA *brna) prop = RNA_def_property(srna, "panel", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "panel"); RNA_def_property_enum_items(prop, panel_items); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Panel", "Select the property panel to be shown"); prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 22d07d739cd..10422c85579 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -6320,14 +6320,8 @@ static void def_cmp_switch(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } -static void def_cmp_switch_view(StructRNA *srna) +static void def_cmp_switch_view(StructRNA *UNUSED(srna)) { - PropertyRNA *prop; - - prop = RNA_def_property(srna, "check", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "custom1", 0); - RNA_def_property_ui_text(prop, "Switch", "Off: first socket, On: second socket"); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } static void def_cmp_colorcorrection(StructRNA *srna) diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 3c3d88c858f..00104b8667d 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -446,10 +446,12 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys int totpart; int totchild = 0; int totface; + int totvert; int num = -1; DM_ensure_tessface(modifier->dm_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ totface = modifier->dm_final->getNumTessFaces(modifier->dm_final); + totvert = modifier->dm_final->getNumVerts(modifier->dm_final); /* 1. check that everything is ok & updated */ if (!particlesystem || !totface) { @@ -484,13 +486,29 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys return num; } } + else if (part->from == PART_FROM_VERT) { + if (num != DMCACHE_NOTFOUND && num < totvert) { + MFace *mface = modifier->dm_final->getTessFaceDataArray(modifier->dm_final, CD_MFACE); + + *r_fuv = &particle->fuv; + + /* This finds the first face to contain the emitting vertex, + * this is not ideal, but is mostly fine as UV seams generally + * map to equal-colored parts of a texture */ + for (int i = 0; i < totface; i++, mface++) { + if (ELEM(num, mface->v1, mface->v2, mface->v3, mface->v4)) { + return i; + } + } + } + } } else { ChildParticle *cpa = particlesystem->child + particle_no - totpart; num = cpa->num; if (part->childtype == PART_CHILD_FACES) { - if (ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) { + if (ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME, PART_FROM_VERT)) { if (num != DMCACHE_NOTFOUND && num < totface) { *r_fuv = &cpa->fuv; return num; @@ -510,6 +528,22 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys return num; } } + else if (part->from == PART_FROM_VERT) { + if (num != DMCACHE_NOTFOUND && num < totvert) { + MFace *mface = modifier->dm_final->getTessFaceDataArray(modifier->dm_final, CD_MFACE); + + *r_fuv = &parent->fuv; + + /* This finds the first face to contain the emitting vertex, + * this is not ideal, but is mostly fine as UV seams generally + * map to equal-colored parts of a texture */ + for (int i = 0; i < totface; i++, mface++) { + if (ELEM(num, mface->v1, mface->v2, mface->v3, mface->v4)) { + return i; + } + } + } + } } } @@ -2095,7 +2129,7 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Even Distribution", "Use even distribution from faces based on face areas or edge lengths"); RNA_def_property_update(prop, 0, "rna_Particle_reset"); - + prop = RNA_def_property(srna, "use_die_on_collision", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_DIE_ON_COL); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 20c3ab89b8e..b9231574a24 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -6988,7 +6988,7 @@ static void rna_def_display_safe_areas(BlenderRNA *brna) RNA_def_property_array(prop, 2); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_float_array_default(prop, default_title); - RNA_def_property_ui_text(prop, "Title Safe margins", "Safe area for text and graphics"); + RNA_def_property_ui_text(prop, "Title Safe Margins", "Safe area for text and graphics"); RNA_def_property_update(prop, NC_SCENE | ND_DRAW_RENDER_VIEWPORT, NULL); prop = RNA_def_property(srna, "action", PROP_FLOAT, PROP_XYZ); @@ -6999,7 +6999,6 @@ static void rna_def_display_safe_areas(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Action Safe Margins", "Safe area for general elements"); RNA_def_property_update(prop, NC_SCENE | ND_DRAW_RENDER_VIEWPORT, NULL); - prop = RNA_def_property(srna, "title_center", PROP_FLOAT, PROP_XYZ); RNA_def_property_float_sdna(prop, NULL, "title_center"); RNA_def_property_array(prop, 2); diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index a80e4c60127..2619d231adc 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -280,8 +280,7 @@ static void rna_Scene_collada_export( int include_shapekeys, int deform_bones_only, int active_uv_only, - int include_uv_textures, - int include_material_textures, + int export_texture_type, int use_texture_copies, int triangulate, int use_object_instantiation, @@ -305,8 +304,7 @@ static void rna_Scene_collada_export( deform_bones_only, active_uv_only, - include_uv_textures, - include_material_textures, + export_texture_type, use_texture_copies, triangulate, @@ -403,11 +401,8 @@ void RNA_api_scene(StructRNA *srna) RNA_def_boolean(func, "active_uv_only", false, "Only Selected UV Map", "Export only the selected UV Map"); - RNA_def_boolean(func, "include_uv_textures", false, - "Include UV Textures", "Export textures assigned to the object UV Maps"); - - RNA_def_boolean(func, "include_material_textures", false, - "Include Material Textures", "Export textures assigned to the object Materials"); + RNA_def_int(func, "export_texture_type", 0, INT_MIN, INT_MAX, + "Texture Type", "Type for exported Textures (UV or MAT)", INT_MIN, INT_MAX); RNA_def_boolean(func, "use_texture_copies", true, "Copy", "Copy textures to same folder where the .dae file is exported"); diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 84b62721999..f628c5f14d9 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -341,7 +341,7 @@ static void rna_Sequence_use_translation_set(PointerRNA *ptr, int value) } } else { - seq->flag ^= SEQ_USE_TRANSFORM; + seq->flag &= ~SEQ_USE_TRANSFORM; } } @@ -355,7 +355,7 @@ static void rna_Sequence_use_crop_set(PointerRNA *ptr, int value) } } else { - seq->flag ^= SEQ_USE_CROP; + seq->flag &= ~SEQ_USE_CROP; } } @@ -1126,7 +1126,7 @@ static void rna_def_strip_crop(BlenderRNA *brna) prop = RNA_def_property(srna, "min_y", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "bottom"); - RNA_def_property_ui_text(prop, "Bottom", "Number of pixels to crop from the buttom"); + RNA_def_property_ui_text(prop, "Bottom", "Number of pixels to crop from the bottom"); RNA_def_property_ui_range(prop, 0, 4096, 1, -1); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceCrop_update"); @@ -2338,7 +2338,7 @@ static void rna_def_text(StructRNA *srna) prop = RNA_def_property(srna, "shadow_color", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "shadow_color"); - RNA_def_property_ui_text(prop, "Shadow Color", "Shadow color"); + RNA_def_property_ui_text(prop, "Shadow Color", ""); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); prop = RNA_def_property(srna, "location", PROP_FLOAT, PROP_XYZ); diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 46775af21db..7d8d24670a7 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -557,8 +557,7 @@ void RNA_api_ui_layout(StructRNA *srna) RNA_def_boolean(func, "emboss", true, "", "Draw the button itself, just the icon/text"); parm = RNA_def_property(func, "icon_value", PROP_INT, PROP_UNSIGNED); RNA_def_property_ui_text(parm, "Icon Value", "Override automatic icon of the item"); - parm = RNA_def_pointer(func, "properties", "OperatorProperties", "", - "Operator properties to fill in, return when 'properties' is set to true"); + parm = RNA_def_pointer(func, "properties", "OperatorProperties", "", "Operator properties to fill in"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR); RNA_def_function_return(func, parm); RNA_def_function_ui_description(func, "Item. Places a button into the layout to call an Operator"); diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index d1e89ea18d0..c0f2dbd0706 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -3317,7 +3317,7 @@ static void rna_def_userdef_view(BlenderRNA *brna) prop = RNA_def_property(srna, "ui_scale", PROP_FLOAT, PROP_FACTOR); RNA_def_property_ui_text(prop, "UI Scale", "Changes the size of the fonts and buttons in the interface"); RNA_def_property_range(prop, 0.25f, 4.0f); - RNA_def_property_ui_range(prop, 0.5f, 2.0f, 1, 1); + RNA_def_property_ui_range(prop, 0.5f, 2.0f, 1, 2); RNA_def_property_float_default(prop, 1.0f); RNA_def_property_update(prop, 0, "rna_userdef_dpi_update"); diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index b458b2e69d5..b5ecaf739c7 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -939,35 +939,8 @@ static void rna_wmClipboard_set(PointerRNA *UNUSED(ptr), const char *value) } #ifdef WITH_PYTHON -static void rna_Operator_unregister(struct Main *bmain, StructRNA *type) -{ - const char *idname; - wmOperatorType *ot = RNA_struct_blender_type_get(type); - wmWindowManager *wm; - - if (!ot) - return; - - /* update while blender is running */ - wm = bmain->wm.first; - 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); - - idname = ot->idname; - WM_operatortype_remove_ptr(ot); - MEM_freeN((void *)idname); - - /* not to be confused with the RNA_struct_free that WM_operatortype_remove calls, they are 2 different srna's */ - RNA_struct_free(&BLENDER_RNA, type); -} - -static int operator_poll(bContext *C, wmOperatorType *ot) +static int rna_operator_poll_cb(bContext *C, wmOperatorType *ot) { extern FunctionRNA rna_Operator_poll_func; @@ -992,7 +965,7 @@ static int operator_poll(bContext *C, wmOperatorType *ot) return visible; } -static int operator_execute(bContext *C, wmOperator *op) +static int rna_operator_execute_cb(bContext *C, wmOperator *op) { extern FunctionRNA rna_Operator_execute_func; @@ -1018,7 +991,7 @@ static int operator_execute(bContext *C, wmOperator *op) } /* same as execute() but no return value */ -static bool operator_check(bContext *C, wmOperator *op) +static bool rna_operator_check_cb(bContext *C, wmOperator *op) { extern FunctionRNA rna_Operator_check_func; @@ -1043,7 +1016,7 @@ static bool operator_check(bContext *C, wmOperator *op) return result; } -static int operator_invoke(bContext *C, wmOperator *op, const wmEvent *event) +static int rna_operator_invoke_cb(bContext *C, wmOperator *op, const wmEvent *event) { extern FunctionRNA rna_Operator_invoke_func; @@ -1070,7 +1043,7 @@ static int operator_invoke(bContext *C, wmOperator *op, const wmEvent *event) } /* same as invoke */ -static int operator_modal(bContext *C, wmOperator *op, const wmEvent *event) +static int rna_operator_modal_cb(bContext *C, wmOperator *op, const wmEvent *event) { extern FunctionRNA rna_Operator_modal_func; @@ -1096,7 +1069,7 @@ static int operator_modal(bContext *C, wmOperator *op, const wmEvent *event) return result; } -static void operator_draw(bContext *C, wmOperator *op) +static void rna_operator_draw_cb(bContext *C, wmOperator *op) { extern FunctionRNA rna_Operator_draw_func; @@ -1115,7 +1088,7 @@ static void operator_draw(bContext *C, wmOperator *op) } /* same as exec(), but call cancel */ -static void operator_cancel(bContext *C, wmOperator *op) +static void rna_operator_cancel_cb(bContext *C, wmOperator *op) { extern FunctionRNA rna_Operator_cancel_func; @@ -1133,35 +1106,42 @@ static void operator_cancel(bContext *C, wmOperator *op) RNA_parameter_list_free(&list); } -void operator_wrapper(wmOperatorType *ot, void *userdata); -void macro_wrapper(wmOperatorType *ot, void *userdata); +static void rna_Operator_unregister(struct Main *bmain, StructRNA *type); -static char _operator_idname[OP_MAX_TYPENAME]; -static char _operator_name[OP_MAX_TYPENAME]; -static char _operator_descr[RNA_DYN_DESCR_MAX]; -static char _operator_ctxt[RNA_DYN_DESCR_MAX]; -static char _operator_undo_group[OP_MAX_TYPENAME]; -static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *data, const char *identifier, - StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) +/* bpy_operator_wrap.c */ +extern void BPY_RNA_operator_wrapper(wmOperatorType *ot, void *userdata); +extern void BPY_RNA_operator_macro_wrapper(wmOperatorType *ot, void *userdata); + +static StructRNA *rna_Operator_register( + Main *bmain, ReportList *reports, void *data, const char *identifier, + StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) { wmOperatorType dummyot = {NULL}; wmOperator dummyop = {NULL}; PointerRNA dummyotr; int have_function[7]; + struct { + char idname[OP_MAX_TYPENAME]; + char name[OP_MAX_TYPENAME]; + char descr[RNA_DYN_DESCR_MAX]; + char ctxt[RNA_DYN_DESCR_MAX]; + char undo_group[OP_MAX_TYPENAME]; + } temp_buffers; + /* setup dummy operator & operator type to store static properties in */ dummyop.type = &dummyot; - dummyot.idname = _operator_idname; /* only assigne the pointer, string is NULL'd */ - dummyot.name = _operator_name; /* only assigne the pointer, string is NULL'd */ - dummyot.description = _operator_descr; /* only assigne the pointer, string is NULL'd */ - dummyot.translation_context = _operator_ctxt; /* only assigne the pointer, string is NULL'd */ - dummyot.undo_group = _operator_undo_group; /* only assigne the pointer, string is NULL'd */ + dummyot.idname = temp_buffers.idname; /* only assigne the pointer, string is NULL'd */ + dummyot.name = temp_buffers.name; /* only assigne the pointer, string is NULL'd */ + dummyot.description = temp_buffers.descr; /* only assigne the pointer, string is NULL'd */ + dummyot.translation_context = temp_buffers.ctxt; /* only assigne the pointer, string is NULL'd */ + dummyot.undo_group = temp_buffers.undo_group; /* only assigne the pointer, string is NULL'd */ RNA_pointer_create(NULL, &RNA_Operator, &dummyop, &dummyotr); /* clear in case they are left unset */ - _operator_idname[0] = _operator_name[0] = _operator_descr[0] = _operator_undo_group[0] = '\0'; + temp_buffers.idname[0] = temp_buffers.name[0] = temp_buffers.descr[0] = temp_buffers.undo_group[0] = '\0'; /* We have to set default op context! */ - strcpy(_operator_ctxt, BLT_I18NCONTEXT_OPERATOR_DEFAULT); + strcpy(temp_buffers.ctxt, BLT_I18NCONTEXT_OPERATOR_DEFAULT); /* validate the python class */ if (validate(&dummyotr, data, have_function) != 0) @@ -1172,7 +1152,7 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void * /* inconveniently long name sanity check */ { - char *ch = _operator_idname; + char *ch = temp_buffers.idname; int i; int dot = 0; for (i = 0; *ch; i++) { @@ -1185,7 +1165,7 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void * else { BKE_reportf(reports, RPT_ERROR, "Registering operator class: '%s', invalid bl_idname '%s', at position %d", - identifier, _operator_idname, i); + identifier, temp_buffers.idname, i); return NULL; } @@ -1194,7 +1174,7 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void * if (i > ((int)sizeof(dummyop.idname)) - 3) { BKE_reportf(reports, RPT_ERROR, "Registering operator class: '%s', invalid bl_idname '%s', " - "is too long, maximum length is %d", identifier, _operator_idname, + "is too long, maximum length is %d", identifier, temp_buffers.idname, (int)sizeof(dummyop.idname) - 3); return NULL; } @@ -1202,34 +1182,34 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void * if (dot != 1) { BKE_reportf(reports, RPT_ERROR, "Registering operator class: '%s', invalid bl_idname '%s', must contain 1 '.' character", - identifier, _operator_idname); + identifier, temp_buffers.idname); return NULL; } } /* end sanity check */ { - int idlen = strlen(_operator_idname) + 4; - int namelen = strlen(_operator_name) + 1; - int desclen = strlen(_operator_descr) + 1; - int ctxtlen = strlen(_operator_ctxt) + 1; - int ugrouplen = strlen(_operator_undo_group) + 1; - char *ch; + const uint idname_len = strlen(temp_buffers.idname) + 4; + const uint name_len = strlen(temp_buffers.name) + 1; + const uint desc_len = strlen(temp_buffers.descr) + 1; + const uint ctxt_len = strlen(temp_buffers.ctxt) + 1; + const uint undo_group_len = strlen(temp_buffers.undo_group) + 1; /* 2 terminators and 3 to convert a.b -> A_OT_b */ - ch = MEM_callocN(sizeof(char) * (idlen + namelen + desclen + ctxtlen + ugrouplen), "_operator_idname"); - WM_operator_bl_idname(ch, _operator_idname); /* convert the idname from python */ + char *ch = MEM_mallocN( + sizeof(char) * (idname_len + name_len + desc_len + ctxt_len + undo_group_len), __func__); + WM_operator_bl_idname(ch, temp_buffers.idname); /* convert the idname from python */ dummyot.idname = ch; - ch += idlen; - strcpy(ch, _operator_name); + ch += idname_len; + memcpy(ch, temp_buffers.name, name_len); dummyot.name = ch; - ch += namelen; - strcpy(ch, _operator_descr); + ch += name_len; + memcpy(ch, temp_buffers.descr, desc_len); dummyot.description = ch; - ch += desclen; - strcpy(ch, _operator_ctxt); + ch += desc_len; + memcpy(ch, temp_buffers.ctxt, ctxt_len); dummyot.translation_context = ch; - ch += ctxtlen; - strcpy(ch, _operator_undo_group); + ch += ctxt_len; + memcpy(ch, temp_buffers.undo_group, undo_group_len); dummyot.undo_group = ch; } } @@ -1252,14 +1232,14 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void * dummyot.ext.call = call; dummyot.ext.free = free; - dummyot.pyop_poll = (have_function[0]) ? operator_poll : NULL; - dummyot.exec = (have_function[1]) ? operator_execute : NULL; - dummyot.check = (have_function[2]) ? operator_check : NULL; - dummyot.invoke = (have_function[3]) ? operator_invoke : NULL; - dummyot.modal = (have_function[4]) ? operator_modal : NULL; - dummyot.ui = (have_function[5]) ? operator_draw : NULL; - dummyot.cancel = (have_function[6]) ? operator_cancel : NULL; - WM_operatortype_append_ptr(operator_wrapper, (void *)&dummyot); + dummyot.pyop_poll = (have_function[0]) ? rna_operator_poll_cb : NULL; + dummyot.exec = (have_function[1]) ? rna_operator_execute_cb : NULL; + dummyot.check = (have_function[2]) ? rna_operator_check_cb : NULL; + dummyot.invoke = (have_function[3]) ? rna_operator_invoke_cb : NULL; + dummyot.modal = (have_function[4]) ? rna_operator_modal_cb : NULL; + dummyot.ui = (have_function[5]) ? rna_operator_draw_cb : NULL; + dummyot.cancel = (have_function[6]) ? rna_operator_cancel_cb : NULL; + WM_operatortype_append_ptr(BPY_RNA_operator_wrapper, (void *)&dummyot); /* update while blender is running */ WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); @@ -1267,70 +1247,107 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void * return dummyot.ext.srna; } +static void rna_Operator_unregister(struct Main *bmain, StructRNA *type) +{ + const char *idname; + wmOperatorType *ot = RNA_struct_blender_type_get(type); + wmWindowManager *wm; + + if (!ot) + return; + + /* update while blender is running */ + wm = bmain->wm.first; + 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); + + idname = ot->idname; + WM_operatortype_remove_ptr(ot); + MEM_freeN((void *)idname); + + /* not to be confused with the RNA_struct_free that WM_operatortype_remove calls, they are 2 different srna's */ + RNA_struct_free(&BLENDER_RNA, type); +} + static void **rna_Operator_instance(PointerRNA *ptr) { wmOperator *op = ptr->data; return &op->py_instance; } -static StructRNA *rna_MacroOperator_register(Main *bmain, ReportList *reports, void *data, const char *identifier, - StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) +static StructRNA *rna_MacroOperator_register( + Main *bmain, ReportList *reports, void *data, const char *identifier, + StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) { wmOperatorType dummyot = {NULL}; wmOperator dummyop = {NULL}; PointerRNA dummyotr; int have_function[4]; + struct { + char idname[OP_MAX_TYPENAME]; + char name[OP_MAX_TYPENAME]; + char descr[RNA_DYN_DESCR_MAX]; + char ctxt[RNA_DYN_DESCR_MAX]; + char undo_group[OP_MAX_TYPENAME]; + } temp_buffers; + /* setup dummy operator & operator type to store static properties in */ dummyop.type = &dummyot; - dummyot.idname = _operator_idname; /* only assigne the pointer, string is NULL'd */ - dummyot.name = _operator_name; /* only assigne the pointer, string is NULL'd */ - dummyot.description = _operator_descr; /* only assigne the pointer, string is NULL'd */ - dummyot.translation_context = _operator_ctxt; /* only assigne the pointer, string is NULL'd */ - dummyot.undo_group = _operator_undo_group; /* only assigne the pointer, string is NULL'd */ + dummyot.idname = temp_buffers.idname; /* only assigne the pointer, string is NULL'd */ + dummyot.name = temp_buffers.name; /* only assigne the pointer, string is NULL'd */ + dummyot.description = temp_buffers.descr; /* only assigne the pointer, string is NULL'd */ + dummyot.translation_context = temp_buffers.ctxt; /* only assigne the pointer, string is NULL'd */ + dummyot.undo_group = temp_buffers.undo_group; /* only assigne the pointer, string is NULL'd */ RNA_pointer_create(NULL, &RNA_Macro, &dummyop, &dummyotr); /* clear in case they are left unset */ - _operator_idname[0] = _operator_name[0] = _operator_descr[0] = _operator_undo_group[0] = '\0'; + temp_buffers.idname[0] = temp_buffers.name[0] = temp_buffers.descr[0] = temp_buffers.undo_group[0] = '\0'; /* We have to set default op context! */ - strcpy(_operator_ctxt, BLT_I18NCONTEXT_OPERATOR_DEFAULT); + strcpy(temp_buffers.ctxt, BLT_I18NCONTEXT_OPERATOR_DEFAULT); /* validate the python class */ if (validate(&dummyotr, data, have_function) != 0) return NULL; + if (strlen(identifier) >= sizeof(dummyop.idname)) { + BKE_reportf(reports, RPT_ERROR, "Registering operator class: '%s' is too long, maximum length is %d", + identifier, (int)sizeof(dummyop.idname)); + return NULL; + } + { /* convert foo.bar to FOO_OT_bar * allocate the description and the idname in 1 go */ - int idlen = strlen(_operator_idname) + 4; - int namelen = strlen(_operator_name) + 1; - int desclen = strlen(_operator_descr) + 1; - int ctxtlen = strlen(_operator_ctxt) + 1; - int ugrouplen = strlen(_operator_undo_group) + 1; - char *ch; + const uint idname_len = strlen(temp_buffers.idname) + 4; + const uint name_len = strlen(temp_buffers.name) + 1; + const uint desc_len = strlen(temp_buffers.descr) + 1; + const uint ctxt_len = strlen(temp_buffers.ctxt) + 1; + const uint undo_group_len = strlen(temp_buffers.undo_group) + 1; /* 2 terminators and 3 to convert a.b -> A_OT_b */ - ch = MEM_callocN(sizeof(char) * (idlen + namelen + desclen + ctxtlen + ugrouplen), "_operator_idname"); - WM_operator_bl_idname(ch, _operator_idname); /* convert the idname from python */ + char *ch = MEM_mallocN( + sizeof(char) * (idname_len + name_len + desc_len + ctxt_len + undo_group_len), __func__); + WM_operator_bl_idname(ch, temp_buffers.idname); /* convert the idname from python */ dummyot.idname = ch; - ch += idlen; - strcpy(ch, _operator_name); + ch += idname_len; + memcpy(ch, temp_buffers.name, name_len); dummyot.name = ch; - ch += namelen; - strcpy(ch, _operator_descr); + ch += name_len; + memcpy(ch, temp_buffers.descr, desc_len); dummyot.description = ch; - ch += desclen; - strcpy(ch, _operator_ctxt); + ch += desc_len; + memcpy(ch, temp_buffers.ctxt, ctxt_len); dummyot.translation_context = ch; - ch += ctxtlen; - strcpy(ch, _operator_undo_group); + ch += ctxt_len; + memcpy(ch, temp_buffers.undo_group, undo_group_len); dummyot.undo_group = ch; } - if (strlen(identifier) >= sizeof(dummyop.idname)) { - BKE_reportf(reports, RPT_ERROR, "Registering operator class: '%s' is too long, maximum length is %d", - identifier, (int)sizeof(dummyop.idname)); - return NULL; - } - /* check if we have registered this operator type before, and remove it */ { wmOperatorType *ot = WM_operatortype_find(dummyot.idname, true); @@ -1348,10 +1365,10 @@ static StructRNA *rna_MacroOperator_register(Main *bmain, ReportList *reports, v dummyot.ext.call = call; dummyot.ext.free = free; - dummyot.pyop_poll = (have_function[0]) ? operator_poll : NULL; - dummyot.ui = (have_function[3]) ? operator_draw : NULL; + dummyot.pyop_poll = (have_function[0]) ? rna_operator_poll_cb : NULL; + dummyot.ui = (have_function[3]) ? rna_operator_draw_cb : NULL; - WM_operatortype_append_macro_ptr(macro_wrapper, (void *)&dummyot); + WM_operatortype_append_macro_ptr(BPY_RNA_operator_macro_wrapper, (void *)&dummyot); /* update while blender is running */ WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index 2b739dc0093..874ac34b613 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -50,6 +50,7 @@ #include "BKE_curve.h" #include "BKE_library_query.h" #include "BKE_modifier.h" +#include "BKE_mesh.h" #include "MOD_util.h" @@ -137,7 +138,7 @@ static void updateDepgraph(ModifierData *md, DagForest *forest, static void updateDepsgraph(ModifierData *md, struct Main *UNUSED(bmain), - struct Scene *scene, + struct Scene *UNUSED(scene), Object *UNUSED(ob), struct DepsNodeHandle *node) { @@ -149,33 +150,15 @@ static void updateDepsgraph(ModifierData *md, DEG_add_object_relation(node, amd->end_cap, DEG_OB_COMP_TRANSFORM, "Array Modifier End Cap"); } if (amd->curve_ob) { + struct Depsgraph *depsgraph = DEG_get_graph_from_handle(node); DEG_add_object_relation(node, amd->curve_ob, DEG_OB_COMP_GEOMETRY, "Array Modifier Curve"); - DEG_add_special_eval_flag(scene->depsgraph, &amd->curve_ob->id, DAG_EVAL_NEED_CURVE_PATH); + DEG_add_special_eval_flag(depsgraph, &amd->curve_ob->id, DAG_EVAL_NEED_CURVE_PATH); } if (amd->offset_ob != NULL) { DEG_add_object_relation(node, amd->offset_ob, DEG_OB_COMP_TRANSFORM, "Array Modifier Offset"); } } -static float vertarray_size(const MVert *mvert, int numVerts, int axis) -{ - int i; - float min_co, max_co; - - /* if there are no vertices, width is 0 */ - if (numVerts == 0) return 0; - - /* find the minimum and maximum coordinates on the desired axis */ - min_co = max_co = mvert->co[axis]; - mvert++; - for (i = 1; i < numVerts; ++i, ++mvert) { - if (mvert->co[axis] < min_co) min_co = mvert->co[axis]; - if (mvert->co[axis] > max_co) max_co = mvert->co[axis]; - } - - return max_co - min_co; -} - BLI_INLINE float sum_v3(const float v[3]) { return v[0] + v[1] + v[2]; @@ -472,12 +455,22 @@ static DerivedMesh *arrayModifier_doArray( unit_m4(offset); src_mvert = dm->getVertArray(dm); - if (amd->offset_type & MOD_ARR_OFF_CONST) - add_v3_v3v3(offset[3], offset[3], amd->offset); + if (amd->offset_type & MOD_ARR_OFF_CONST) { + add_v3_v3(offset[3], amd->offset); + } if (amd->offset_type & MOD_ARR_OFF_RELATIVE) { - for (j = 0; j < 3; j++) - offset[3][j] += amd->scale[j] * vertarray_size(src_mvert, chunk_nverts, j); + float min[3], max[3]; + const MVert *src_mv; + + INIT_MINMAX(min, max); + for (src_mv = src_mvert, j = chunk_nverts; j--; src_mv++) { + minmax_v3v3_v3(min, max, src_mv->co); + } + + for (j = 3; j--; ) { + offset[3][j] += amd->scale[j] * (max[j] - min[j]); + } } if (use_offset_ob) { diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c index 09444476bfe..3c6ba7acc88 100644 --- a/source/blender/modifiers/intern/MOD_curve.c +++ b/source/blender/modifiers/intern/MOD_curve.c @@ -111,7 +111,7 @@ static void updateDepgraph(ModifierData *md, DagForest *forest, static void updateDepsgraph(ModifierData *md, struct Main *UNUSED(bmain), - struct Scene *scene, + struct Scene *UNUSED(scene), Object *object, struct DepsNodeHandle *node) { @@ -123,8 +123,9 @@ static void updateDepsgraph(ModifierData *md, /* TODO(sergey): Currently path is evaluated as a part of modifier stack, * might be changed in the future. */ + struct Depsgraph *depsgraph = DEG_get_graph_from_handle(node); DEG_add_object_relation(node, cmd->object, DEG_OB_COMP_GEOMETRY, "Curve Modifier"); - DEG_add_special_eval_flag(scene->depsgraph, &cmd->object->id, DAG_EVAL_NEED_CURVE_PATH); + DEG_add_special_eval_flag(depsgraph, &cmd->object->id, DAG_EVAL_NEED_CURVE_PATH); } DEG_add_object_relation(node, object, DEG_OB_COMP_TRANSFORM, "Curve Modifier"); diff --git a/source/blender/modifiers/intern/MOD_dynamicpaint.c b/source/blender/modifiers/intern/MOD_dynamicpaint.c index bb75d655802..83a42504180 100644 --- a/source/blender/modifiers/intern/MOD_dynamicpaint.c +++ b/source/blender/modifiers/intern/MOD_dynamicpaint.c @@ -36,6 +36,7 @@ #include "BKE_cdderivedmesh.h" #include "BKE_dynamicpaint.h" +#include "BKE_library.h" #include "BKE_library_query.h" #include "BKE_modifier.h" @@ -58,6 +59,15 @@ static void copyData(ModifierData *md, ModifierData *target) DynamicPaintModifierData *tpmd = (DynamicPaintModifierData *)target; dynamicPaint_Modifier_copy(pmd, tpmd); + + if (tpmd->canvas) { + for (DynamicPaintSurface *surface = tpmd->canvas->surfaces.first; surface; surface = surface->next) { + id_us_plus((ID *)surface->init_texture); + } + } + if (tpmd->brush) { + id_us_plus((ID *)tpmd->brush->mat); + } } static void freeData(ModifierData *md) diff --git a/source/blender/modifiers/intern/MOD_fluidsim.c b/source/blender/modifiers/intern/MOD_fluidsim.c index c202c5e1cb4..1964e940cb2 100644 --- a/source/blender/modifiers/intern/MOD_fluidsim.c +++ b/source/blender/modifiers/intern/MOD_fluidsim.c @@ -68,12 +68,13 @@ static void copyData(ModifierData *md, ModifierData *target) FluidsimModifierData *fluidmd = (FluidsimModifierData *) md; FluidsimModifierData *tfluidmd = (FluidsimModifierData *) target; - if (tfluidmd->fss) - MEM_freeN(tfluidmd->fss); - - tfluidmd->fss = MEM_dupallocN(fluidmd->fss); - if (tfluidmd->fss && (tfluidmd->fss->meshVelocities != NULL)) { - tfluidmd->fss->meshVelocities = MEM_dupallocN(tfluidmd->fss->meshVelocities); + fluidsim_free(tfluidmd); + + if (fluidmd->fss) { + tfluidmd->fss = MEM_dupallocN(fluidmd->fss); + if (tfluidmd->fss && (tfluidmd->fss->meshVelocities != NULL)) { + tfluidmd->fss->meshVelocities = MEM_dupallocN(tfluidmd->fss->meshVelocities); + } } } diff --git a/source/blender/modifiers/intern/MOD_fluidsim_util.c b/source/blender/modifiers/intern/MOD_fluidsim_util.c index 2ecf06057db..3684e947fe0 100644 --- a/source/blender/modifiers/intern/MOD_fluidsim_util.c +++ b/source/blender/modifiers/intern/MOD_fluidsim_util.c @@ -150,9 +150,8 @@ void fluidsim_free(FluidsimModifierData *fluidmd) if (fluidmd && fluidmd->fss) { if (fluidmd->fss->meshVelocities) { MEM_freeN(fluidmd->fss->meshVelocities); - fluidmd->fss->meshVelocities = NULL; } - MEM_freeN(fluidmd->fss); + MEM_SAFE_FREE(fluidmd->fss); } return; diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index 406ce398ee0..b1938395a7b 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -83,7 +83,7 @@ static void copyData(ModifierData *md, ModifierData *target) MeshDeformModifierData *mmd = (MeshDeformModifierData *) md; MeshDeformModifierData *tmmd = (MeshDeformModifierData *) target; - *tmmd = *mmd; + modifier_copyData_generic(md, target); if (mmd->bindinfluences) tmmd->bindinfluences = MEM_dupallocN(mmd->bindinfluences); if (mmd->bindoffsets) tmmd->bindoffsets = MEM_dupallocN(mmd->bindoffsets); @@ -91,8 +91,8 @@ static void copyData(ModifierData *md, ModifierData *target) if (mmd->dyngrid) tmmd->dyngrid = MEM_dupallocN(mmd->dyngrid); if (mmd->dyninfluences) tmmd->dyninfluences = MEM_dupallocN(mmd->dyninfluences); if (mmd->dynverts) tmmd->dynverts = MEM_dupallocN(mmd->dynverts); - if (mmd->bindweights) tmmd->dynverts = MEM_dupallocN(mmd->bindweights); /* deprecated */ - if (mmd->bindcos) tmmd->dynverts = MEM_dupallocN(mmd->bindcos); /* deprecated */ + if (mmd->bindweights) tmmd->bindweights = MEM_dupallocN(mmd->bindweights); /* deprecated */ + if (mmd->bindcos) tmmd->bindcos = MEM_dupallocN(mmd->bindcos); /* deprecated */ } static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c index e77cc655c16..2c0bfc86e7d 100644 --- a/source/blender/modifiers/intern/MOD_ocean.c +++ b/source/blender/modifiers/intern/MOD_ocean.c @@ -160,40 +160,19 @@ static void freeData(ModifierData *md) static void copyData(ModifierData *md, ModifierData *target) { #ifdef WITH_OCEANSIM +#if 0 OceanModifierData *omd = (OceanModifierData *) md; +#endif OceanModifierData *tomd = (OceanModifierData *) target; - tomd->geometry_mode = omd->geometry_mode; - tomd->resolution = omd->resolution; - tomd->spatial_size = omd->spatial_size; - - tomd->wind_velocity = omd->wind_velocity; - - tomd->damp = omd->damp; - tomd->smallest_wave = omd->smallest_wave; - tomd->depth = omd->depth; + freeData(target); - tomd->wave_alignment = omd->wave_alignment; - tomd->wave_direction = omd->wave_direction; - tomd->wave_scale = omd->wave_scale; - - tomd->chop_amount = omd->chop_amount; - tomd->foam_coverage = omd->foam_coverage; - tomd->time = omd->time; - - tomd->seed = omd->seed; - tomd->flag = omd->flag; + modifier_copyData_generic(md, target); tomd->refresh = 0; - tomd->size = omd->size; - tomd->repeat_x = omd->repeat_x; - tomd->repeat_y = omd->repeat_y; - /* XXX todo: copy cache runtime too */ tomd->cached = 0; - tomd->bakestart = omd->bakestart; - tomd->bakeend = omd->bakeend; tomd->oceancache = NULL; tomd->ocean = BKE_ocean_add(); diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c index 79e3eb5f3df..b692137b604 100644 --- a/source/blender/modifiers/intern/MOD_surfacedeform.c +++ b/source/blender/modifiers/intern/MOD_surfacedeform.c @@ -138,7 +138,9 @@ static void copyData(ModifierData *md, ModifierData *target) SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md; SurfaceDeformModifierData *tsmd = (SurfaceDeformModifierData *)target; - *tsmd = *smd; + freeData(target); + + modifier_copyData_generic(md, target); if (smd->verts) { tsmd->verts = MEM_dupallocN(smd->verts); diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c index 78dc1ea8bcb..01468c1143a 100644 --- a/source/blender/modifiers/intern/MOD_uvproject.c +++ b/source/blender/modifiers/intern/MOD_uvproject.c @@ -45,6 +45,7 @@ #include "BKE_camera.h" +#include "BKE_library.h" #include "BKE_library_query.h" #include "BKE_mesh.h" #include "BKE_DerivedMesh.h" @@ -70,9 +71,12 @@ static void copyData(ModifierData *md, ModifierData *target) { #if 0 UVProjectModifierData *umd = (UVProjectModifierData *) md; - UVProjectModifierData *tumd = (UVProjectModifierData *) target; #endif + UVProjectModifierData *tumd = (UVProjectModifierData *) target; + modifier_copyData_generic(md, target); + + id_us_plus((ID *)tumd->image); } static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(md)) diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c index e958ab9a3dc..8139e29bade 100644 --- a/source/blender/nodes/composite/nodes/node_composite_image.c +++ b/source/blender/nodes/composite/nodes/node_composite_image.c @@ -116,6 +116,10 @@ static void cmp_node_image_add_pass_output(bNodeTree *ntree, bNode *node, } else { sock = BLI_findlink(&node->outputs, sock_index); + NodeImageLayer *sockdata = sock->storage; + if (sockdata) { + BLI_strncpy(sockdata->pass_name, passname, sizeof(sockdata->pass_name)); + } } BLI_linklist_append(available_sockets, sock); @@ -158,14 +162,11 @@ static void cmp_node_image_create_outputs(bNodeTree *ntree, bNode *node, LinkNod else type = SOCK_RGBA; + cmp_node_image_add_pass_output(ntree, node, rpass->name, rpass->name, -1, type, false, available_sockets, &prev_index); /* Special handling for the Combined pass to ensure compatibility. */ if (STREQ(rpass->name, RE_PASSNAME_COMBINED)) { - cmp_node_image_add_pass_output(ntree, node, "Image", rpass->name, -1, type, false, available_sockets, &prev_index); cmp_node_image_add_pass_output(ntree, node, "Alpha", rpass->name, -1, SOCK_FLOAT, false, available_sockets, &prev_index); } - else { - cmp_node_image_add_pass_output(ntree, node, rpass->name, rpass->name, -1, type, false, available_sockets, &prev_index); - } } BKE_image_release_ibuf(ima, ibuf, NULL); return; @@ -173,13 +174,10 @@ static void cmp_node_image_create_outputs(bNodeTree *ntree, bNode *node, LinkNod } } - cmp_node_image_add_pass_output(ntree, node, "Image", RE_PASSNAME_COMBINED, RRES_OUT_IMAGE, SOCK_RGBA, false, available_sockets, &prev_index); - cmp_node_image_add_pass_output(ntree, node, "Alpha", RE_PASSNAME_COMBINED, RRES_OUT_ALPHA, SOCK_FLOAT, false, available_sockets, &prev_index); + cmp_node_image_add_pass_output(ntree, node, "Image", RE_PASSNAME_COMBINED, -1, SOCK_RGBA, false, available_sockets, &prev_index); + cmp_node_image_add_pass_output(ntree, node, "Alpha", RE_PASSNAME_COMBINED, -1, SOCK_FLOAT, false, available_sockets, &prev_index); if (ima) { - if (!ima->rr) { - cmp_node_image_add_pass_output(ntree, node, RE_PASSNAME_Z, RE_PASSNAME_Z, RRES_OUT_Z, SOCK_FLOAT, false, available_sockets, &prev_index); - } BKE_image_release_ibuf(ima, ibuf, NULL); } } @@ -276,7 +274,7 @@ static void cmp_node_image_verify_outputs(bNodeTree *ntree, bNode *node, bool rl for (link = ntree->links.first; link; link = link->next) { if (link->fromsock == sock) break; } - if (!link && sock_index > 30) { + if (!link && (!rlayer || sock_index > 30)) { MEM_freeN(sock->storage); nodeRemoveSocket(ntree, node, sock); } diff --git a/source/blender/nodes/composite/nodes/node_composite_switchview.c b/source/blender/nodes/composite/nodes/node_composite_switchview.c index d805cf4d87f..e0d9fa33f13 100644 --- a/source/blender/nodes/composite/nodes/node_composite_switchview.c +++ b/source/blender/nodes/composite/nodes/node_composite_switchview.c @@ -137,7 +137,6 @@ static void init_switch_view(const bContext *C, PointerRNA *ptr) cmp_node_switch_view_sanitycheck(ntree, node); } -/* custom1 = mix type */ void register_node_type_cmp_switch_view(void) { static bNodeType ntype; diff --git a/source/blender/nodes/intern/node_exec.c b/source/blender/nodes/intern/node_exec.c index 2347564c696..0cf131adbdc 100644 --- a/source/blender/nodes/intern/node_exec.c +++ b/source/blender/nodes/intern/node_exec.c @@ -78,7 +78,8 @@ void node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNodeStack static void node_init_input_index(bNodeSocket *sock, int *index) { - if (sock->link && sock->link->fromsock) { + /* Only consider existing link if from socket is valid! */ + if (sock->link && sock->link->fromsock && sock->link->fromsock->stack_index >= 0) { sock->stack_index = sock->link->fromsock->stack_index; } else { diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.c index 9bd43f331fb..5bc97f13b41 100644 --- a/source/blender/nodes/shader/node_shader_util.c +++ b/source/blender/nodes/shader/node_shader_util.c @@ -142,28 +142,40 @@ void node_gpu_stack_from_data(struct GPUNodeStack *gs, int type, bNodeStack *ns) { memset(gs, 0, sizeof(*gs)); - nodestack_get_vec(gs->vec, type, ns); - gs->link = ns->data; - - if (type == SOCK_FLOAT) - gs->type = GPU_FLOAT; - else if (type == SOCK_VECTOR) - gs->type = GPU_VEC3; - else if (type == SOCK_RGBA) - gs->type = GPU_VEC4; - else if (type == SOCK_SHADER) - gs->type = GPU_VEC4; - else + if (ns == NULL) { + /* node_get_stack() will generate NULL bNodeStack pointers for unknown/unsuported types of sockets... */ + zero_v4(gs->vec); + gs->link = NULL; gs->type = GPU_NONE; + gs->name = ""; + gs->hasinput = false; + gs->hasoutput = false; + gs->sockettype = type; + } + else { + nodestack_get_vec(gs->vec, type, ns); + gs->link = ns->data; - gs->name = ""; - gs->hasinput = ns->hasinput && ns->data; - /* XXX Commented out the ns->data check here, as it seems it's not always set, - * even though there *is* a valid connection/output... But that might need - * further investigation. - */ - gs->hasoutput = ns->hasoutput /*&& ns->data*/; - gs->sockettype = ns->sockettype; + if (type == SOCK_FLOAT) + gs->type = GPU_FLOAT; + else if (type == SOCK_VECTOR) + gs->type = GPU_VEC3; + else if (type == SOCK_RGBA) + gs->type = GPU_VEC4; + else if (type == SOCK_SHADER) + gs->type = GPU_VEC4; + else + gs->type = GPU_NONE; + + gs->name = ""; + gs->hasinput = ns->hasinput && ns->data; + /* XXX Commented out the ns->data check here, as it seems it's not always set, + * even though there *is* a valid connection/output... But that might need + * further investigation. + */ + gs->hasoutput = ns->hasoutput /*&& ns->data*/; + gs->sockettype = ns->sockettype; + } } void node_data_from_gpu_stack(bNodeStack *ns, GPUNodeStack *gs) diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c index 44288db182a..e0330d110ca 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c @@ -43,7 +43,7 @@ static bNodeSocketTemplate sh_node_bsdf_principled_in[] = { { SOCK_FLOAT, 1, N_("Sheen"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, { SOCK_FLOAT, 1, N_("Sheen Tint"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, { SOCK_FLOAT, 1, N_("Clearcoat"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, - { SOCK_FLOAT, 1, N_("Clearcoat Gloss"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("Clearcoat Roughness"), 0.03f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, { SOCK_FLOAT, 1, N_("IOR"), 1.45f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f}, { SOCK_FLOAT, 1, N_("Transmission"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, { SOCK_FLOAT, 1, N_("Transmission Roughness"),0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, diff --git a/source/blender/nodes/shader/nodes/node_shader_normal_map.c b/source/blender/nodes/shader/nodes/node_shader_normal_map.c index e0bf34f42e4..36d7522e3e6 100644 --- a/source/blender/nodes/shader/nodes/node_shader_normal_map.c +++ b/source/blender/nodes/shader/nodes/node_shader_normal_map.c @@ -46,8 +46,10 @@ static void node_shader_init_normal_map(bNodeTree *UNUSED(ntree), bNode *node) node->storage = attr; } -static void node_shader_exec_normal_map(void *data, int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out) - { +static void node_shader_exec_normal_map( + void *data, int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), + bNodeStack **in, bNodeStack **out) +{ if (data) { ShadeInput *shi = ((ShaderCallData *)data)->shi; diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt index 038c1e7eb10..be4db6477fe 100644 --- a/source/blender/python/intern/CMakeLists.txt +++ b/source/blender/python/intern/CMakeLists.txt @@ -55,6 +55,7 @@ set(SRC bpy_app_handlers.c bpy_app_ocio.c bpy_app_oiio.c + bpy_app_opensubdiv.c bpy_app_openvdb.c bpy_app_sdl.c bpy_app_translations.c @@ -89,6 +90,7 @@ set(SRC bpy_app_handlers.h bpy_app_ocio.h bpy_app_oiio.h + bpy_app_opensubdiv.h bpy_app_openvdb.h bpy_app_sdl.h bpy_app_translations.h @@ -295,6 +297,13 @@ if(WITH_OPENIMAGEIO) ) endif() +if(WITH_OPENSUBDIV) + add_definitions(-DWITH_OPENSUBDIV) + list(APPEND INC + ../../../../intern/opensubdiv + ) +endif() + if(WITH_PLAYER) add_definitions(-DWITH_PLAYER) endif() diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c index ed7cec2f2d5..8b3464173d2 100644 --- a/source/blender/python/intern/bpy_app.c +++ b/source/blender/python/intern/bpy_app.c @@ -37,6 +37,7 @@ #include "bpy_app_ffmpeg.h" #include "bpy_app_ocio.h" #include "bpy_app_oiio.h" +#include "bpy_app_opensubdiv.h" #include "bpy_app_openvdb.h" #include "bpy_app_sdl.h" #include "bpy_app_build_options.h" @@ -109,6 +110,7 @@ static PyStructSequence_Field app_info_fields[] = { {(char *)"ffmpeg", (char *)"FFmpeg library information backend"}, {(char *)"ocio", (char *)"OpenColorIO library information backend"}, {(char *)"oiio", (char *)"OpenImageIO library information backend"}, + {(char *)"opensubdiv", (char *)"OpenSubdiv library information backend"}, {(char *)"openvdb", (char *)"OpenVDB library information backend"}, {(char *)"sdl", (char *)"SDL library information backend"}, {(char *)"build_options", (char *)"A set containing most important enabled optional build features"}, @@ -117,9 +119,21 @@ static PyStructSequence_Field app_info_fields[] = { {NULL}, }; +PyDoc_STRVAR(bpy_app_doc, +"This module contains application values that remain unchanged during runtime.\n" +"\n" +"Submodules:\n" +"\n" +".. toctree::\n" +" :maxdepth: 1\n" +"\n" +" bpy.app.handlers.rst\n" +" bpy.app.translations.rst\n" +); + static PyStructSequence_Desc app_info_desc = { (char *)"bpy.app", /* name */ - (char *)"This module contains application values that remain unchanged during runtime.", /* doc */ + bpy_app_doc, /* doc */ app_info_fields, /* fields */ ARRAY_SIZE(app_info_fields) - 1 }; @@ -188,6 +202,7 @@ static PyObject *make_app_info(void) SetObjItem(BPY_app_ffmpeg_struct()); SetObjItem(BPY_app_ocio_struct()); SetObjItem(BPY_app_oiio_struct()); + SetObjItem(BPY_app_opensubdiv_struct()); SetObjItem(BPY_app_openvdb_struct()); SetObjItem(BPY_app_sdl_struct()); SetObjItem(BPY_app_build_options_struct()); diff --git a/source/blender/python/intern/bpy_app_opensubdiv.c b/source/blender/python/intern/bpy_app_opensubdiv.c new file mode 100644 index 00000000000..7f269baf2b0 --- /dev/null +++ b/source/blender/python/intern/bpy_app_opensubdiv.c @@ -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. + * + * Contributor(s): Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/python/intern/bpy_app_opensubdiv.c + * \ingroup pythonintern + */ + +#include <Python.h> +#include "BLI_utildefines.h" + +#include "bpy_app_opensubdiv.h" + +#ifdef WITH_OPENSUBDIV +# include "opensubdiv_capi.h" +#endif + +static PyTypeObject BlenderAppOpenSubdivType; + +static PyStructSequence_Field app_opensubdiv_info_fields[] = { + {(char *)"supported", (char *)("Boolean, True when Blender is built with OpenSubdiv support")}, + {(char *)("version"), (char *)("The OpenSubdiv version as a tuple of 3 numbers")}, + {(char *)("version_string"), (char *)("The OpenSubdiv version formatted as a string")}, + {NULL} +}; + +static PyStructSequence_Desc app_opensubdiv_info_desc = { + (char *)"bpy.app.opensubdiv", /* name */ + (char *)"This module contains information about OpenSubdiv blender is linked against", /* doc */ + app_opensubdiv_info_fields, /* fields */ + ARRAY_SIZE(app_opensubdiv_info_fields) - 1 +}; + +static PyObject *make_opensubdiv_info(void) +{ + PyObject *opensubdiv_info; + int pos = 0; + + opensubdiv_info = PyStructSequence_New(&BlenderAppOpenSubdivType); + if (opensubdiv_info == NULL) { + return NULL; + } + +#ifndef WITH_OPENSUBDIV +#define SetStrItem(str) \ + PyStructSequence_SET_ITEM(opensubdiv_info, pos++, PyUnicode_FromString(str)) +#endif + +#define SetObjItem(obj) \ + PyStructSequence_SET_ITEM(opensubdiv_info, pos++, obj) + +#ifdef WITH_OPENSUBDIV + int curversion = openSubdiv_getVersionHex(); + SetObjItem(PyBool_FromLong(1)); + SetObjItem(Py_BuildValue("(iii)", + curversion / 10000, (curversion / 100) % 100, curversion % 100)); + SetObjItem(PyUnicode_FromFormat("%2d, %2d, %2d", + curversion / 10000, (curversion / 100) % 100, curversion % 100)); +#else + SetObjItem(PyBool_FromLong(0)); + SetObjItem(Py_BuildValue("(iii)", 0, 0, 0)); + SetStrItem("Unknown"); +#endif + + if (PyErr_Occurred()) { + Py_CLEAR(opensubdiv_info); + return NULL; + } + +#undef SetStrItem +#undef SetObjItem + + return opensubdiv_info; +} + +PyObject *BPY_app_opensubdiv_struct(void) +{ + PyObject *ret; + + PyStructSequence_InitType(&BlenderAppOpenSubdivType, &app_opensubdiv_info_desc); + + ret = make_opensubdiv_info(); + + /* prevent user from creating new instances */ + BlenderAppOpenSubdivType.tp_init = NULL; + BlenderAppOpenSubdivType.tp_new = NULL; + /* without this we can't do set(sys.modules) [#29635] */ + BlenderAppOpenSubdivType.tp_hash = (hashfunc)_Py_HashPointer; + + return ret; +} diff --git a/source/blender/python/intern/bpy_app_opensubdiv.h b/source/blender/python/intern/bpy_app_opensubdiv.h new file mode 100644 index 00000000000..b1da218b168 --- /dev/null +++ b/source/blender/python/intern/bpy_app_opensubdiv.h @@ -0,0 +1,32 @@ +/* + * ***** BEGIN GPL 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_opensubdiv.h + * \ingroup pythonintern + */ + +#ifndef __BPY_APP_OPENSUBDIV_H__ +#define __BPY_APP_OPENSUBDIV_H__ + +PyObject *BPY_app_opensubdiv_struct(void); + +#endif /* __BPY_APP_OPENSUBDIV_H__ */ diff --git a/source/blender/python/intern/bpy_app_sdl.c b/source/blender/python/intern/bpy_app_sdl.c index 2f4d8e6c325..76dab775953 100644 --- a/source/blender/python/intern/bpy_app_sdl.c +++ b/source/blender/python/intern/bpy_app_sdl.c @@ -56,7 +56,7 @@ static PyStructSequence_Field app_sdl_info_fields[] = { {(char *)"available", (char *)("Boolean, True when SDL is available. This is False when " "either *supported* is False, or *dynload* is True and " "Blender cannot find the correct library.")}, - {NULL} + {NULL} }; static PyStructSequence_Desc app_sdl_info_desc = { diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c index 11e27ca3e3c..90719905a79 100644 --- a/source/blender/python/intern/bpy_operator_wrap.c +++ b/source/blender/python/intern/bpy_operator_wrap.c @@ -118,7 +118,7 @@ static void operator_properties_init(wmOperatorType *ot) } -void operator_wrapper(wmOperatorType *ot, void *userdata) +void BPY_RNA_operator_wrapper(wmOperatorType *ot, void *userdata) { /* take care not to overwrite anything set in * WM_operatortype_append_ptr before opfunc() is called */ @@ -134,7 +134,7 @@ void operator_wrapper(wmOperatorType *ot, void *userdata) operator_properties_init(ot); } -void macro_wrapper(wmOperatorType *ot, void *userdata) +void BPY_RNA_operator_macro_wrapper(wmOperatorType *ot, void *userdata) { wmOperatorType *data = (wmOperatorType *)userdata; diff --git a/source/blender/python/intern/bpy_operator_wrap.h b/source/blender/python/intern/bpy_operator_wrap.h index 05a566a1485..0828c58e2bd 100644 --- a/source/blender/python/intern/bpy_operator_wrap.h +++ b/source/blender/python/intern/bpy_operator_wrap.h @@ -33,7 +33,7 @@ struct wmOperatorType; PyObject *PYOP_wrap_macro_define(PyObject *self, PyObject *args); /* exposed to rna/wm api */ -void operator_wrapper(struct wmOperatorType *ot, void *userdata); -void macro_wrapper(struct wmOperatorType *ot, void *userdata); +void BPY_RNA_operator_wrapper(struct wmOperatorType *ot, void *userdata); +void BPY_RNA_operator_macro_wrapper(struct wmOperatorType *ot, void *userdata); #endif diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index 2656e612b18..c7787ba9682 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -2862,8 +2862,8 @@ PyDoc_STRVAR(BPy_PointerProperty_doc, "name=\"\", " "description=\"\", " "options={'ANIMATABLE'}, " - "update=None,\n" - "poll=None)\n" + "poll=None, " + "update=None)\n" "\n" " Returns a new pointer property definition.\n" "\n" @@ -3001,7 +3001,7 @@ PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw) } PyDoc_STRVAR(BPy_RemoveProperty_doc, -".. function:: RemoveProperty(cls, attr="")\n" +".. function:: RemoveProperty(cls, attr)\n" "\n" " Removes a dynamically defined property.\n" "\n" diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index a0b76bd67ee..eda880d4dce 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -7265,15 +7265,12 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v { const ListBase *lb; Link *link; - FunctionRNA *func; - PropertyRNA *prop; const char *class_type = RNA_struct_identifier(srna); StructRNA *srna_base = RNA_struct_base(srna); 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, func_arg_min_count = 0; - bool is_staticmethod; + int i, arg_count, func_arg_count, func_arg_min_count = 0; const char *py_class_name = ((PyTypeObject *)py_class)->tp_name; /* __name__ */ if (srna_base) { @@ -7294,9 +7291,12 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v lb = RNA_struct_type_functions(srna); i = 0; 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); + FunctionRNA *func = (FunctionRNA *)link; + const int flag = RNA_function_flag(func); + /* TODO(campbell): this is used for classmethod's too, + * even though class methods should have 'FUNC_USE_SELF_TYPE' set, see Operator.poll for eg. + * Keep this as-is since its working but we should be using 'FUNC_USE_SELF_TYPE' for many functions. */ + const bool is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE); if (!(flag & FUNC_REGISTER)) continue; @@ -7322,7 +7322,8 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v 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", + "expected %.200s, %.200s class \"%.200s\" " + "attribute to be a static/class method, not a %.200s", class_type, py_class_name, RNA_function_identifier(func), Py_TYPE(item)->tp_name); return -1; } @@ -7331,7 +7332,8 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v else { if (PyFunction_Check(item) == 0) { PyErr_Format(PyExc_TypeError, - "expected %.200s, %.200s class \"%.200s\" attribute to be a function, not a %.200s", + "expected %.200s, %.200s class \"%.200s\" " + "attribute to be a function, not a %.200s", class_type, py_class_name, RNA_function_identifier(func), Py_TYPE(item)->tp_name); return -1; } @@ -7343,7 +7345,7 @@ 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 - * @staticmethods 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 (is_staticmethod) { func_arg_count++; @@ -7374,8 +7376,8 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v lb = RNA_struct_type_properties(srna); for (link = lb->first; link; link = link->next) { const char *identifier; - prop = (PropertyRNA *)link; - flag = RNA_property_flag(prop); + PropertyRNA *prop = (PropertyRNA *)link; + const int flag = RNA_property_flag(prop); if (!(flag & PROP_REGISTER)) continue; diff --git a/source/blender/python/mathutils/mathutils.c b/source/blender/python/mathutils/mathutils.c index 5c505247a97..1afb1d7be90 100644 --- a/source/blender/python/mathutils/mathutils.c +++ b/source/blender/python/mathutils/mathutils.c @@ -1,4 +1,4 @@ -/* +/* * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or @@ -38,18 +38,31 @@ #endif PyDoc_STRVAR(M_Mathutils_doc, -"This module provides access to the math classes:\n" +"This module provides access to math operations.\n" +"\n" +".. note::\n" +"\n" +" Classes, methods and attributes that accept vectors also accept other numeric sequences,\n" +" such as tuples, lists." +"\n\n" +"Submodules:\n" +"\n" +".. toctree::\n" +" :maxdepth: 1\n" +"\n" +" mathutils.geometry.rst\n" +" mathutils.bvhtree.rst\n" +" mathutils.kdtree.rst\n" +" mathutils.interpolate.rst\n" +" mathutils.noise.rst\n" +"\n" +"The :mod:`mathutils` module provides the following classes:\n" "\n" "- :class:`Color`,\n" "- :class:`Euler`,\n" "- :class:`Matrix`,\n" "- :class:`Quaternion`,\n" "- :class:`Vector`,\n" -"\n" -".. note::\n" -"\n" -" Classes, methods and attributes that accept vectors also accept other numeric sequences,\n" -" such as tuples, lists." ); static int mathutils_array_parse_fast(float *array, int size, @@ -219,7 +232,7 @@ int mathutils_array_parse_alloc(float **array, int array_min, PyObject *value, c error_prefix, size, array_min); return -1; } - + *array = PyMem_Malloc(size * sizeof(float)); memcpy(*array, ((BaseMathObject *)value)->data, size * sizeof(float)); return size; @@ -422,7 +435,7 @@ static Mathutils_Callback *mathutils_callbacks[MATHUTILS_TOT_CB] = {NULL}; unsigned char Mathutils_RegisterCallback(Mathutils_Callback *cb) { unsigned char i; - + /* find the first free slot */ for (i = 0; mathutils_callbacks[i]; i++) { if (mathutils_callbacks[i] == cb) /* already registered? */ @@ -625,14 +638,14 @@ PyMODINIT_FUNC PyInit_mathutils(void) return NULL; mod = PyModule_Create(&M_Mathutils_module_def); - + /* each type has its own new() function */ PyModule_AddObject(mod, vector_Type.tp_name, (PyObject *)&vector_Type); PyModule_AddObject(mod, matrix_Type.tp_name, (PyObject *)&matrix_Type); PyModule_AddObject(mod, euler_Type.tp_name, (PyObject *)&euler_Type); PyModule_AddObject(mod, quaternion_Type.tp_name, (PyObject *)&quaternion_Type); PyModule_AddObject(mod, color_Type.tp_name, (PyObject *)&color_Type); - + /* submodule */ PyModule_AddObject(mod, "geometry", (submodule = PyInit_mathutils_geometry())); /* XXX, python doesnt do imports with this usefully yet diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index f0323340899..f9942bef61f 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -335,7 +335,7 @@ typedef struct ObjectRen { char (*mcol)[MAX_CUSTOMDATA_LAYER_NAME]; int actmtface, actmcol, bakemtface; - char tangent_mask; /* which tangent layer should be calculated */ + short tangent_mask; /* which tangent layer should be calculated */ float obmat[4][4]; /* only used in convertblender.c, for instancing */ diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 41ff8e046e7..9633d95855e 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -3439,10 +3439,9 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) if (need_nmap_tangent_concrete || need_tangent) { int uv_start = CustomData_get_layer_index(&dm->faceData, CD_MTFACE); int uv_index = CustomData_get_named_layer_index(&dm->faceData, CD_MTFACE, layer->name); - BLI_assert(uv_start >= 0 && uv_index >= 0); - if ((uv_start < 0 || uv_index < 0)) - continue; - int n = uv_index - uv_start; + + /* if there are no UVs, orco tangents are in first slot */ + int n = (uv_start >= 0 && uv_index >= 0) ? uv_index - uv_start : 0; const float *tangent = (const float *) layer->data; float *ftang = RE_vlakren_get_nmap_tangent(obr, vlr, n, true); @@ -4658,14 +4657,22 @@ static void add_render_object(Render *re, Object *ob, Object *par, DupliObject * index= (dob)? dob->persistent_id[0]: 0; + /* It seems that we may generate psys->renderdata recursively in some nasty intricated cases of + * several levels of bupliobject (see T51524). + * For now, basic rule is, do not restore psys if it was already in 'render state'. + * Another, more robust solution could be to add some reference counting to that renderdata... */ + bool psys_has_renderdata = false; + /* the emitter has to be processed first (render levels of modifiers) */ /* so here we only check if the emitter should be rendered */ if (ob->particlesystem.first) { show_emitter= 0; for (psys=ob->particlesystem.first; psys; psys=psys->next) { show_emitter += psys->part->draw & PART_DRAW_EMITTER; - if (!(re->r.scemode & R_VIEWPORT_PREVIEW)) + if (!(re->r.scemode & R_VIEWPORT_PREVIEW)) { + psys_has_renderdata |= (psys->renderdata != NULL); psys_render_set(ob, psys, re->viewmat, re->winmat, re->winx, re->winy, timeoffset); + } } /* if no psys has "show emitter" selected don't render emitter */ @@ -4701,12 +4708,6 @@ static void add_render_object(Render *re, Object *ob, Object *par, DupliObject * if (ob->particlesystem.first) { psysindex= 1; for (psys=ob->particlesystem.first; psys; psys=psys->next, psysindex++) { - /* It seems that we may generate psys->renderdata recursively in some nasty intricated cases of - * several levels of bupliobject (see T51524). - * For now, basic rule is, do not restore psys if it was already in 'render state'. - * Another, more robust solution could be to add some reference counting to that renderdata... */ - const bool psys_has_renderdata = (psys->renderdata != NULL); - if (!psys_check_enabled(ob, psys, G.is_rendering)) continue; diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 59c7ea85c1d..77f399d08d1 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -464,48 +464,48 @@ static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, float *fp, *col= NULL; int pixsize= 3; - if(STREQ(rpass->name, RE_PASSNAME_COMBINED)) { + if (STREQ(rpass->name, RE_PASSNAME_COMBINED)) { add_filt_fmask(curmask, shr->combined, rpass->rect + 4*offset, rectx); } - else if(STREQ(rpass->name, RE_PASSNAME_Z)) { + else if (STREQ(rpass->name, RE_PASSNAME_Z)) { fp = rpass->rect + offset; *fp = shr->z; } - else if(STREQ(rpass->name, RE_PASSNAME_RGBA)) { + else if (STREQ(rpass->name, RE_PASSNAME_RGBA)) { col = shr->col; pixsize = 4; } - else if(STREQ(rpass->name, RE_PASSNAME_EMIT)) { + else if (STREQ(rpass->name, RE_PASSNAME_EMIT)) { col = shr->emit; } - else if(STREQ(rpass->name, RE_PASSNAME_DIFFUSE)) { + else if (STREQ(rpass->name, RE_PASSNAME_DIFFUSE)) { col = shr->diff; } - else if(STREQ(rpass->name, RE_PASSNAME_SPEC)) { + else if (STREQ(rpass->name, RE_PASSNAME_SPEC)) { col = shr->spec; } - else if(STREQ(rpass->name, RE_PASSNAME_SHADOW)) { + else if (STREQ(rpass->name, RE_PASSNAME_SHADOW)) { col = shr->shad; } - else if(STREQ(rpass->name, RE_PASSNAME_AO)) { + else if (STREQ(rpass->name, RE_PASSNAME_AO)) { col = shr->ao; } - else if(STREQ(rpass->name, RE_PASSNAME_ENVIRONMENT)) { + else if (STREQ(rpass->name, RE_PASSNAME_ENVIRONMENT)) { col = shr->env; } - else if(STREQ(rpass->name, RE_PASSNAME_INDIRECT)) { + else if (STREQ(rpass->name, RE_PASSNAME_INDIRECT)) { col = shr->indirect; } - else if(STREQ(rpass->name, RE_PASSNAME_REFLECT)) { + else if (STREQ(rpass->name, RE_PASSNAME_REFLECT)) { col = shr->refl; } - else if(STREQ(rpass->name, RE_PASSNAME_REFRACT)) { + else if (STREQ(rpass->name, RE_PASSNAME_REFRACT)) { col = shr->refr; } - else if(STREQ(rpass->name, RE_PASSNAME_NORMAL)) { + else if (STREQ(rpass->name, RE_PASSNAME_NORMAL)) { col = shr->nor; } - else if(STREQ(rpass->name, RE_PASSNAME_UV)) { + else if (STREQ(rpass->name, RE_PASSNAME_UV)) { /* box filter only, gauss will screwup UV too much */ if (shi->totuv) { float mult = (float)count_mask(curmask)/(float)R.osa; @@ -515,7 +515,7 @@ static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, fp[2]+= mult; } } - else if(STREQ(rpass->name, RE_PASSNAME_INDEXOB)) { + else if (STREQ(rpass->name, RE_PASSNAME_INDEXOB)) { /* no filter */ if (shi->vlr) { fp = rpass->rect + offset; @@ -523,7 +523,7 @@ static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, *fp = (float)shi->obr->ob->index; } } - else if(STREQ(rpass->name, RE_PASSNAME_INDEXMA)) { + else if (STREQ(rpass->name, RE_PASSNAME_INDEXMA)) { /* no filter */ if (shi->vlr) { fp = rpass->rect + offset; @@ -531,12 +531,12 @@ static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, *fp = (float)shi->mat->index; } } - else if(STREQ(rpass->name, RE_PASSNAME_MIST)) { + else if (STREQ(rpass->name, RE_PASSNAME_MIST)) { /* */ col = &shr->mist; pixsize = 1; } - else if(STREQ(rpass->name, RE_PASSNAME_VECTOR)) { + else if (STREQ(rpass->name, RE_PASSNAME_VECTOR)) { /* add minimum speed in pixel, no filter */ fp = rpass->rect + 4*offset; if ( (ABS(shr->winspeed[0]) + ABS(shr->winspeed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) { @@ -548,7 +548,7 @@ static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, fp[3] = shr->winspeed[3]; } } - else if(STREQ(rpass->name, RE_PASSNAME_RAYHITS)) { + else if (STREQ(rpass->name, RE_PASSNAME_RAYHITS)) { /* */ col = shr->rayhits; pixsize= 4; diff --git a/source/blender/render/intern/source/sunsky.c b/source/blender/render/intern/source/sunsky.c index d4e53eb7305..f0cf29e98ca 100644 --- a/source/blender/render/intern/source/sunsky.c +++ b/source/blender/render/intern/source/sunsky.c @@ -398,7 +398,7 @@ void InitAtmosphere(struct SunSky *sunSky, float sun_intens, float mief, float r vLambda2[0] = fLambda2[0]; vLambda2[1] = fLambda2[1]; vLambda2[2] = fLambda2[2]; - + vLambda4[0] = fLambda4[0]; vLambda4[1] = fLambda4[1]; vLambda4[2] = fLambda4[2]; diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index e497ec1a870..68707f163af 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -1601,7 +1601,6 @@ void zspan_scanconvert(ZSpan *zspan, void *handle, float *v1, float *v2, float * * Note: uses globals. * \param v1 start coordinate s * \param v2 target coordinate t - * \param b1 * \param b2 * \param b3 * \param a index for coordinate (x, y, or z) diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 492dec2cc10..60a39b24208 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -103,6 +103,7 @@ enum { struct wmWindow *WM_window_open(struct bContext *C, const struct rcti *rect); struct wmWindow *WM_window_open_temp(struct bContext *C, int x, int y, int sizex, int sizey, int type); +void WM_window_set_dpi(wmWindow *win); /* returns true if draw method is triple buffer */ bool WM_is_draw_triple(struct wmWindow *win); diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index d0522fdd7d4..67e961b9cd0 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -483,13 +483,12 @@ void wm_close_and_free(bContext *C, wmWindowManager *wm) void wm_close_and_free_all(bContext *C, ListBase *wmlist) { - Main *bmain = CTX_data_main(C); wmWindowManager *wm; - + while ((wm = wmlist->first)) { wm_close_and_free(C, wm); BLI_remlink(wmlist, wm); - BKE_libblock_free_data(bmain, &wm->id, true); + BKE_libblock_free_data(&wm->id, true); MEM_freeN(wm); } } diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index 77ffa46b990..25c6980f58e 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -926,15 +926,14 @@ void wm_draw_update(bContext *C) for (win = wm->windows.first; win; win = win->next) { #ifdef WIN32 - if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY)) { - GHOST_TWindowState 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 invisible windows - */ - continue; - } + GHOST_TWindowState state = GHOST_GetWindowState(win->ghostwin); + + if (state == GHOST_kWindowStateMinimized) { + /* do not update minimized windows, gives issues on Intel (see T33223) + * and AMD (see T50856). it seems logical to skip update for invisible + * window anyway. + */ + continue; } #endif if (win->drawmethod != U.wmdrawmethod) { diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 187c1193ec6..b4a6366fb4e 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -316,7 +316,7 @@ 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, const bool use_factory_settings) +static void wm_init_userdef(bContext *C, const bool read_userdef_from_memory) { Main *bmain = CTX_data_main(C); @@ -336,14 +336,12 @@ static void wm_init_userdef(bContext *C, const bool use_factory_settings) } /* avoid re-saving for every small change to our prefs, allow overrides */ - if (use_factory_settings) { + if (read_userdef_from_memory) { BLO_update_defaults_userpref_blend(); } /* update tempdir from user preferences */ BKE_tempdir_init(U.tempdir); - - BKE_blender_userdef_refresh(); } @@ -667,7 +665,7 @@ int wm_homefile_read( * * And in this case versioning code is to be run. */ - bool read_userdef_from_memory = true; + bool read_userdef_from_memory = false; eBLOReadSkip skip_flags = 0; /* options exclude eachother */ @@ -713,7 +711,6 @@ int wm_homefile_read( BKE_blender_userdef_set_data(userdef); MEM_freeN(userdef); - read_userdef_from_memory = false; skip_flags |= BLO_READ_SKIP_USERDEF; printf("Read prefs: %s\n", filepath_userdef); } @@ -775,6 +772,9 @@ int wm_homefile_read( success = BKE_blendfile_read_from_memory( C, datatoc_startup_blend, datatoc_startup_blend_size, NULL, skip_flags, true); + if (success && !(skip_flags & BLO_READ_SKIP_USERDEF)) { + read_userdef_from_memory = true; + } if (BLI_listbase_is_empty(&wmbase)) { wm_clear_default_size(C); } @@ -810,6 +810,7 @@ int wm_homefile_read( /* we need to have preferences load to overwrite preferences from previous template */ userdef_template = BKE_blendfile_userdef_read_from_memory( datatoc_startup_blend, datatoc_startup_blend_size, NULL); + read_userdef_from_memory = true; } if (userdef_template) { BKE_blender_userdef_set_app_template(userdef_template); @@ -1093,7 +1094,7 @@ static int wm_file_write(bContext *C, const char *filepath, int fileflags, Repor BKE_reportf(reports, RPT_ERROR, "Cannot save blend file, path '%s' is not writable", filepath); return ret; } - + /* note: used to replace the file extension (to ensure '.blend'), * no need to now because the operator ensures, * its handy for scripts to save to a predefined name without blender editing it */ diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c index 3b733f9558c..f19c999a4f1 100644 --- a/source/blender/windowmanager/intern/wm_files_link.c +++ b/source/blender/windowmanager/intern/wm_files_link.c @@ -608,7 +608,8 @@ static void lib_relocate_do( } /* Note that in reload case, we also want to replace indirect usages. */ - const short remap_flags = ID_REMAP_SKIP_NEVER_NULL_USAGE | (do_reload ? 0 : ID_REMAP_SKIP_INDIRECT_USAGE); + const short remap_flags = ID_REMAP_SKIP_NEVER_NULL_USAGE | ID_REMAP_NO_INDIRECT_PROXY_DATA_USAGE | + (do_reload ? 0 : ID_REMAP_SKIP_INDIRECT_USAGE); for (item_idx = 0, itemlink = lapp_data->items.list; itemlink; item_idx++, itemlink = itemlink->next) { WMLinkAppendDataItem *item = itemlink->link; ID *old_id = item->customdata; diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 9bafe72d805..00a9976e8be 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -181,7 +181,7 @@ void WM_init(bContext *C, int argc, const char **argv) ED_file_init(); /* for fsmenu */ ED_node_init_butfuncs(); - BLF_init(11, U.dpi); /* Please update source/gamengine/GamePlayer/GPG_ghost.cpp if you change this */ + BLF_init(); /* Please update source/gamengine/GamePlayer/GPG_ghost.cpp if you change this */ BLT_lang_init(); /* Enforce loading the UI for the initial homefile */ diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c index 6bf7bcc2934..0a6e329a7c1 100644 --- a/source/blender/windowmanager/intern/wm_playanim.c +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -1256,7 +1256,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv) //GHOST_ActivateWindowDrawingContext(g_WS.ghost_window); /* initialize the font */ - BLF_init(11, 72); + BLF_init(); ps.fontid = BLF_load_mem("monospace", (unsigned char *)datatoc_bmonofont_ttf, datatoc_bmonofont_ttf_size); BLF_size(ps.fontid, 11, 72); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index de169881bc4..8afeb8e7b3d 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -375,7 +375,7 @@ void wm_window_title(wmWindowManager *wm, wmWindow *win) } } -static void wm_window_set_dpi(wmWindow *win) +void WM_window_set_dpi(wmWindow *win) { int auto_dpi = GHOST_GetDPIHint(win->ghostwin); @@ -406,8 +406,10 @@ static void wm_window_set_dpi(wmWindow *win) U.pixelsize = GHOST_GetNativePixelSize(win->ghostwin) * pixelsize; U.dpi = dpi / pixelsize; U.virtual_pixel = (pixelsize == 1) ? VIRTUAL_PIXEL_NATIVE : VIRTUAL_PIXEL_DOUBLE; + U.widget_unit = (U.pixelsize * U.dpi * 20 + 36) / 72; - BKE_blender_userdef_refresh(); + /* update font drawing */ + BLF_default_dpi(U.pixelsize * U.dpi); } /* belongs to below */ @@ -483,7 +485,7 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm, const char *title, wm } /* needed here, because it's used before it reads userdef */ - wm_window_set_dpi(win); + WM_window_set_dpi(win); wm_window_swap_buffers(win); @@ -870,7 +872,7 @@ void wm_window_make_drawable(wmWindowManager *wm, wmWindow *win) GHOST_ActivateWindowDrawingContext(win->ghostwin); /* this can change per window */ - wm_window_set_dpi(win); + WM_window_set_dpi(win); } } @@ -1070,7 +1072,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr WM_jobs_stop(wm, win->screen, NULL); } - wm_window_set_dpi(win); + WM_window_set_dpi(win); /* win32: gives undefined window size when minimized */ if (state != GHOST_kWindowStateMinimized) { @@ -1157,11 +1159,10 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr case GHOST_kEventWindowDPIHintChanged: { - wm_window_set_dpi(win); + WM_window_set_dpi(win); /* font's are stored at each DPI level, without this we can easy load 100's of fonts */ BLF_cache_clear(); - BKE_blender_userdef_refresh(); WM_main_add_notifier(NC_WINDOW, NULL); /* full redraw */ WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); /* refresh region sizes */ break; @@ -1247,7 +1248,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr { // only update if the actual pixel size changes float prev_pixelsize = U.pixelsize; - wm_window_set_dpi(win); + WM_window_set_dpi(win); if (U.pixelsize != prev_pixelsize) { // close all popups since they are positioned with the pixel diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 82a3527a655..d00c7b6a022 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -721,7 +721,9 @@ struct uiLayout *uiLayoutRadial(struct uiLayout *layout) RET_NULL int UI_pie_menu_invoke_from_operator_enum(struct bContext *C, const char *title, const char *opname, const char *propname, const struct wmEvent *event) RET_ZERO -/* RNA COLLADA dependency */ +/* RNA COLLADA dependency */ +/* XXX (gaia) Why do we need this declaration here? */ +/* The collada header is included anyways further up... */ int collada_export(struct Scene *sce, const char *filepath, int apply_modifiers, @@ -734,8 +736,7 @@ int collada_export(struct Scene *sce, int deform_bones_only, int active_uv_only, - int include_uv_textures, - int include_material_textures, + BC_export_texture_type export_texture_type, int use_texture_copies, int triangulate, @@ -750,7 +751,10 @@ int collada_export(struct Scene *sce, void ED_mesh_calc_tessface(struct Mesh *mesh, bool free_mpoly) RET_NONE /* bpy/python internal api */ -void operator_wrapper(struct wmOperatorType *ot, void *userdata) RET_NONE +extern void BPY_RNA_operator_wrapper(struct wmOperatorType *ot, void *userdata); +extern void BPY_RNA_operator_macro_wrapper(struct wmOperatorType *ot, void *userdata); +void BPY_RNA_operator_wrapper(struct wmOperatorType *ot, void *userdata) RET_NONE +void BPY_RNA_operator_macro_wrapper(struct wmOperatorType *ot, void *userdata) RET_NONE void BPY_text_free_code(struct Text *text) RET_NONE void BPY_id_release(struct ID *id) RET_NONE int BPY_context_member_get(struct bContext *C, const char *member, struct bContextDataResult *result) RET_ZERO @@ -758,7 +762,6 @@ void BPY_pyconstraint_target(struct bPythonConstraint *con, struct bConstraintTa float BPY_driver_exec(PathResolvedRNA *anim_rna, struct ChannelDriver *driver, const float evaltime) RET_ZERO /* might need this one! */ void BPY_DECREF(void *pyob_ptr) RET_NONE void BPY_pyconstraint_exec(struct bPythonConstraint *con, struct bConstraintOb *cob, struct ListBase *targets) RET_NONE -void macro_wrapper(struct wmOperatorType *ot, void *userdata) RET_NONE bool pyrna_id_FromPyObject(struct PyObject *obj, struct ID **id) RET_ZERO struct PyObject *pyrna_id_CreatePyObject(struct ID *id) RET_NULL bool pyrna_id_CheckPyObject(struct PyObject *obj) RET_ZERO diff --git a/source/gameengine/GamePlayer/common/GPC_MouseDevice.h b/source/gameengine/GamePlayer/common/GPC_MouseDevice.h index 504df2376bb..24922197723 100644 --- a/source/gameengine/GamePlayer/common/GPC_MouseDevice.h +++ b/source/gameengine/GamePlayer/common/GPC_MouseDevice.h @@ -67,8 +67,6 @@ public: * Call this routine to update the mouse device when a button state changes. * \param button Which button state changes. * \param isDown The new state of the button. - * \param x Position x-coordinate of the cursor at the time of the state change. - * \param y Position y-coordinate of the cursor at the time of the state change. * \return Indication as to whether the event was processed. */ virtual bool ConvertButtonEvent(TButtonId button, bool isDown); diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp index 0c206dfce3d..906e9d9a821 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp @@ -516,7 +516,7 @@ int main( #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_init(); BLT_lang_init(); BLT_lang_set(""); diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp index 822f2e054f8..d858097abef 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.cpp +++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp @@ -124,7 +124,7 @@ void KX_SoundActuator::play() AUD_Device_free(device); // in case of pingpong, we have to free the sound - if(sound != m_sound) + if (sound != m_sound) AUD_Sound_free(sound); if (m_handle != NULL) { diff --git a/tests/gtests/blenlib/BLI_kdopbvh_test.cc b/tests/gtests/blenlib/BLI_kdopbvh_test.cc new file mode 100644 index 00000000000..e713ddc1695 --- /dev/null +++ b/tests/gtests/blenlib/BLI_kdopbvh_test.cc @@ -0,0 +1,95 @@ +/* Apache License, Version 2.0 */ + +#include "testing/testing.h" + +/* TODO: ray intersection, overlap ... etc.*/ + +extern "C" { +#include "BLI_compiler_attrs.h" +#include "BLI_kdopbvh.h" +#include "BLI_rand.h" +#include "BLI_math_vector.h" +#include "MEM_guardedalloc.h" +} + +/* -------------------------------------------------------------------- */ +/* Helper Functions */ + +static void rng_v3_round( + float *coords, int coords_len, + struct RNG *rng, int round, float scale) +{ + for (int i = 0; i < coords_len; i++) { + float f = BLI_rng_get_float(rng) * 2.0f - 1.0f; + coords[i] = ((float)((int)(f * round)) / (float)round) * scale; + } +} + +/* -------------------------------------------------------------------- */ +/* Tests */ + +TEST(kdopbvh, Empty) +{ + BVHTree *tree = BLI_bvhtree_new(0, 0.0, 8, 8); + BLI_bvhtree_balance(tree); + EXPECT_EQ(0, BLI_bvhtree_get_size(tree)); + BLI_bvhtree_free(tree); +} + +TEST(kdopbvh, Single) +{ + BVHTree *tree = BLI_bvhtree_new(1, 0.0, 8, 8); + { + float co[3] = {0}; + BLI_bvhtree_insert(tree, 0, co, 1); + } + + EXPECT_EQ(BLI_bvhtree_get_size(tree), 1); + + BLI_bvhtree_balance(tree); + BLI_bvhtree_free(tree); +} + +/** + * Note that a small epsilon is added to the BVH nodes bounds, even if we pass in zero. + * Use rounding to ensure very close nodes don't cause the wrong node to be found as nearest. + */ +static void find_nearest_points_test(int points_len, float scale, int round, int random_seed) +{ + struct RNG *rng = BLI_rng_new(random_seed); + BVHTree *tree = BLI_bvhtree_new(points_len, 0.0, 8, 8); + + void *mem = MEM_mallocN(sizeof(float[3]) * points_len, __func__); + float (*points)[3] = (float (*)[3])mem; + + for (int i = 0; i < points_len; i++) { + rng_v3_round(points[i], 3, rng, round, scale); + BLI_bvhtree_insert(tree, i, points[i], 1); + } + BLI_bvhtree_balance(tree); + /* first find each point */ + for (int i = 0; i < points_len; i++) { + const int j = BLI_bvhtree_find_nearest(tree, points[i], NULL, NULL, NULL); + if (j != i) { +#if 0 + const float dist = len_v3v3(points[i], points[j]); + if (dist > (1.0f / (float)round)) { + printf("%.15f (%d %d)\n", dist, i, j); + print_v3_id(points[i]); + print_v3_id(points[j]); + fflush(stdout); + } +#endif + EXPECT_GE(j, 0); + EXPECT_LT(j, points_len); + EXPECT_EQ_ARRAY(points[i], points[j], 3); + } + } + BLI_bvhtree_free(tree); + BLI_rng_free(rng); + MEM_freeN(points); +} + +TEST(kdopbvh, FindNearest_1) { find_nearest_points_test(1, 1.0, 1000, 1234); } +TEST(kdopbvh, FindNearest_2) { find_nearest_points_test(2, 1.0, 1000, 123); } +TEST(kdopbvh, FindNearest_500) { find_nearest_points_test(500, 1.0, 1000, 12); } diff --git a/tests/gtests/blenlib/BLI_path_util_test.cc b/tests/gtests/blenlib/BLI_path_util_test.cc index ef469da50b2..41fad661ea9 100644 --- a/tests/gtests/blenlib/BLI_path_util_test.cc +++ b/tests/gtests/blenlib/BLI_path_util_test.cc @@ -41,7 +41,7 @@ const char *GHOST_getSystemDir(int version, const char *versionstr) struct ImBuf; void IMB_freeImBuf(struct ImBuf *ibuf) {} -struct ImBuf *IMB_dupImBuf(struct ImBuf *ibuf) {return NULL;} +struct ImBuf *IMB_dupImBuf(const ImBuf *ibuf) {return NULL;} #ifdef __linux__ char *zLhm65070058860608_br_find_exe(const char *default_exe) diff --git a/tests/gtests/blenlib/CMakeLists.txt b/tests/gtests/blenlib/CMakeLists.txt index a190d9cd8c5..8b013e7a7a6 100644 --- a/tests/gtests/blenlib/CMakeLists.txt +++ b/tests/gtests/blenlib/CMakeLists.txt @@ -37,6 +37,7 @@ set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${PLATFORM_LIN BLENDER_TEST(BLI_array_store "bf_blenlib") BLENDER_TEST(BLI_array_utils "bf_blenlib") +BLENDER_TEST(BLI_kdopbvh "bf_blenlib;bf_intern_eigen") BLENDER_TEST(BLI_stack "bf_blenlib") BLENDER_TEST(BLI_math_color "bf_blenlib") BLENDER_TEST(BLI_math_geom "bf_blenlib;bf_intern_eigen") diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt index ac480f4d58c..9e1ebcbe669 100644 --- a/tests/python/CMakeLists.txt +++ b/tests/python/CMakeLists.txt @@ -49,7 +49,8 @@ endif() # for testing with valgrind prefix: valgrind --track-origins=yes --error-limit=no set(TEST_BLENDER_EXE_BARE ${TEST_BLENDER_EXE}) -set(TEST_BLENDER_EXE ${TEST_BLENDER_EXE} --background -noaudio --factory-startup --env-system-scripts ${CMAKE_SOURCE_DIR}/release/scripts) +set(TEST_BLENDER_EXE_PARAMS --background -noaudio --factory-startup --env-system-scripts ${CMAKE_SOURCE_DIR}/release/scripts) +set(TEST_BLENDER_EXE ${TEST_BLENDER_EXE} ${TEST_BLENDER_EXE_PARAMS} ) # ------------------------------------------------------------------------------ @@ -103,15 +104,15 @@ add_test(bevel ${TEST_BLENDER_EXE} ) add_test(split_faces ${TEST_BLENDER_EXE} - ${TEST_SRC_DIR}/modeling/split_faces_test.blend - --python-text run_tests + ${TEST_SRC_DIR}/modeling/split_faces_test.blend + --python-text run_tests ) # ------------------------------------------------------------------------------ # MODIFIERS TESTS add_test(modifier_array ${TEST_BLENDER_EXE} - ${TEST_SRC_DIR}/modifier_stack/array_test.blend - --python-text run_tests + ${TEST_SRC_DIR}/modifier_stack/array_test.blend + --python-text run_tests ) # ------------------------------------------------------------------------------ @@ -458,12 +459,6 @@ if(WITH_ALEMBIC) get_filename_component(real_include_dir ${ALEMBIC_INCLUDE_DIR} REALPATH) get_filename_component(ALEMBIC_ROOT_DIR ${real_include_dir} DIRECTORY) - add_test(script_alembic_import ${TEST_BLENDER_EXE} - --python ${CMAKE_CURRENT_LIST_DIR}/bl_alembic_import_test.py - -- - --testdir "${TEST_SRC_DIR}/alembic" - ) - if(MSVC) add_test(NAME alembic_tests COMMAND @@ -473,6 +468,15 @@ if(WITH_ALEMBIC) --testdir "${TEST_SRC_DIR}/alembic" --alembic-root "${ALEMBIC_ROOT_DIR}" ) + add_test(NAME script_alembic_import + COMMAND + "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS} + --python ${CMAKE_CURRENT_LIST_DIR}/bl_alembic_import_test.py + -- + --testdir "${TEST_SRC_DIR}/alembic" + --with-legacy-depsgraph=${WITH_LEGACY_DEPSGRAPH} + ) + else() add_test(alembic_tests ${CMAKE_CURRENT_LIST_DIR}/alembic_tests.py @@ -480,5 +484,12 @@ if(WITH_ALEMBIC) --testdir "${TEST_SRC_DIR}/alembic" --alembic-root "${ALEMBIC_ROOT_DIR}" ) + add_test(script_alembic_import ${TEST_BLENDER_EXE} + --python ${CMAKE_CURRENT_LIST_DIR}/bl_alembic_import_test.py + -- + --testdir "${TEST_SRC_DIR}/alembic" + --with-legacy-depsgraph=${WITH_LEGACY_DEPSGRAPH} + ) + endif() endif() diff --git a/tests/python/alembic_tests.py b/tests/python/alembic_tests.py index e36a6391298..96a68de9801 100755 --- a/tests/python/alembic_tests.py +++ b/tests/python/alembic_tests.py @@ -157,6 +157,8 @@ class AbstractAlembicTest(unittest.TestCase): if proptype == 'CompoundProperty': # To read those, call self.abcprop() on it. continue + if len(parts) < 2: + raise ValueError('Error parsing result from abcprop: %s', info.strip()) valtype_and_arrsize, name_and_extent = parts[1:] # Parse name and extent diff --git a/tests/python/bl_alembic_import_test.py b/tests/python/bl_alembic_import_test.py index 358b8a3c758..d8cd64a1d56 100644 --- a/tests/python/bl_alembic_import_test.py +++ b/tests/python/bl_alembic_import_test.py @@ -129,6 +129,9 @@ class SimpleImportTest(AbstractAlembicTest): bpy.data.cache_files[fname].filepath = relpath.replace('1.abc', '2.abc') bpy.context.scene.update() + if args.with_legacy_depsgraph: + bpy.context.scene.frame_set(10) + x, y, z = cube.matrix_world.to_euler('XYZ') self.assertAlmostEqual(x, math.pi / 2, places=5) self.assertAlmostEqual(y, 0) @@ -207,12 +210,14 @@ def main(): import argparse if '--' in sys.argv: - argv = [sys.argv[0]] + sys.argv[sys.argv.index('--')+1:] + argv = [sys.argv[0]] + sys.argv[sys.argv.index('--') + 1:] else: argv = sys.argv parser = argparse.ArgumentParser() parser.add_argument('--testdir', required=True, type=pathlib.Path) + parser.add_argument('--with-legacy-depsgraph', default=False, + type=lambda v: v in {'ON', 'YES', 'TRUE'}) args, remaining = parser.parse_known_args(argv) unittest.main(argv=remaining) diff --git a/tests/python/bl_keymap_completeness.py b/tests/python/bl_keymap_completeness.py index 00322907f69..652ed449a3c 100644 --- a/tests/python/bl_keymap_completeness.py +++ b/tests/python/bl_keymap_completeness.py @@ -80,5 +80,6 @@ def main(): import sys sys.exit(1) + if __name__ == "__main__": main() diff --git a/tests/python/bl_load_py_modules.py b/tests/python/bl_load_py_modules.py index c13679d16f0..4935491a6be 100644 --- a/tests/python/bl_load_py_modules.py +++ b/tests/python/bl_load_py_modules.py @@ -36,6 +36,9 @@ BLACKLIST = { "cycles", "io_export_dxf", # TODO, check on why this fails 'io_import_dxf', # Because of cydxfentity.so dependency + + # The unpacked wheel is only loaded when actually used, not directly on import: + "io_blend_utils/blender_bam-unpacked.whl", } # Some modules need to add to the `sys.path`. @@ -211,11 +214,10 @@ def load_modules(): [(os.sep + f + ".py") for f in BLACKLIST]) for f in source_files: - ok = False for ignore in ignore_paths: if ignore in f: - ok = True - if not ok: + break + else: raise Exception("Source file %r not loaded in test" % f) print("loaded %d modules" % len(loaded_files)) diff --git a/tests/python/pep8.py b/tests/python/pep8.py index 0e6250f534b..dde4250f6aa 100644 --- a/tests/python/pep8.py +++ b/tests/python/pep8.py @@ -178,5 +178,6 @@ def main(): "--max-line-length=1000" " '%s'" % f) + if __name__ == "__main__": main() diff --git a/tests/python/rna_info_dump.py b/tests/python/rna_info_dump.py index c26d94a1246..da228e52652 100644 --- a/tests/python/rna_info_dump.py +++ b/tests/python/rna_info_dump.py @@ -127,5 +127,6 @@ def api_dump(use_properties=True, use_functions=True): print("END") + if __name__ == "__main__": api_dump() |