diff options
author | Joseph Eagar <joeedh@gmail.com> | 2022-03-29 08:54:24 +0300 |
---|---|---|
committer | Joseph Eagar <joeedh@gmail.com> | 2022-03-29 08:54:24 +0300 |
commit | 176b331c43c5378b0a346b7c96b0934c9c5bf19f (patch) | |
tree | 546efd965d57bfa16945c2ef1ab664b2a3667471 | |
parent | 2f3ace40240797100161a659a12d995e1480b91b (diff) | |
parent | 540bfbbb27966b4b8affeaa273a70beac9373b23 (diff) |
Merge branch 'master' into temp-sculpt-colors
397 files changed, 17302 insertions, 5262 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index bf40347e2ef..ca457ab6b37 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -284,6 +284,7 @@ option(WITH_IMAGE_TIFF "Enable LibTIFF Support" ON) option(WITH_IMAGE_DDS "Enable DDS Image Support" ON) option(WITH_IMAGE_CINEON "Enable CINEON and DPX Image Support" ON) option(WITH_IMAGE_HDR "Enable HDR Image Support" ON) +option(WITH_IMAGE_WEBP "Enable WebP Image Support" OFF) # Audio/Video format support option(WITH_CODEC_AVI "Enable Blenders own AVI file support (raw/jpeg)" ON) @@ -445,7 +446,7 @@ if(NOT APPLE) endif() option(WITH_CYCLES_HIP_BINARIES "Build Cycles AMD HIP binaries" OFF) - set(CYCLES_HIP_BINARIES_ARCH gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032 gfx1034 CACHE STRING "AMD HIP architectures to build binaries for") + set(CYCLES_HIP_BINARIES_ARCH gfx900 gfx906 gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032 gfx1034 CACHE STRING "AMD HIP architectures to build binaries for") mark_as_advanced(WITH_CYCLES_DEVICE_HIP) mark_as_advanced(CYCLES_HIP_BINARIES_ARCH) endif() @@ -1973,7 +1974,7 @@ if(FIRST_RUN) set(_msg " - ${_setting}") string(LENGTH "${_msg}" _len) - while("32" GREATER "${_len}") + while("36" GREATER "${_len}") string(APPEND _msg " ") math(EXPR _len "${_len} + 1") endwhile() diff --git a/build_files/build_environment/cmake/download.cmake b/build_files/build_environment/cmake/download.cmake index b92073636f5..5ca46c15d8d 100644 --- a/build_files/build_environment/cmake/download.cmake +++ b/build_files/build_environment/cmake/download.cmake @@ -1,11 +1,16 @@ # SPDX-License-Identifier: GPL-2.0-or-later +## Update and uncomment this in the release branch +# set(BLENDER_VERSION 3.1) + function(download_source dep) set(TARGET_FILE ${${dep}_FILE}) set(TARGET_HASH_TYPE ${${dep}_HASH_TYPE}) set(TARGET_HASH ${${dep}_HASH}) if(PACKAGE_USE_UPSTREAM_SOURCES) set(TARGET_URI ${${dep}_URI}) + elseif(BLENDER_VERSION) + set(TARGET_URI https://svn.blender.org/svnroot/bf-blender/tags/blender-${BLENDER_VERSION}-release/lib/packages/${TARGET_FILE}) else() set(TARGET_URI https://svn.blender.org/svnroot/bf-blender/trunk/lib/packages/${TARGET_FILE}) endif() diff --git a/build_files/cmake/Modules/FindWebP.cmake b/build_files/cmake/Modules/FindWebP.cmake new file mode 100644 index 00000000000..741c48ec447 --- /dev/null +++ b/build_files/cmake/Modules/FindWebP.cmake @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2022 Blender Foundation. + +# - Find WebP library +# Find the native WebP includes and library +# This module defines +# WEBP_INCLUDE_DIRS, where to find WebP headers, Set when WebP is found. +# WEBP_LIBRARIES, libraries to link against to use WebP. +# WEBP_ROOT_DIR, The base directory to search for WebP. +# This can also be an environment variable. +# WEBP_FOUND, If false, do not try to use WebP. +# +# also defined, but not for general use are +# WEBP_LIBRARY, where to find the WEBP library. + +# If WEBP_ROOT_DIR was defined in the environment, use it. +IF(NOT WEBP_ROOT_DIR AND NOT $ENV{WEBP_ROOT_DIR} STREQUAL "") + SET(WEBP_ROOT_DIR $ENV{WEBP_ROOT_DIR}) +ENDIF() + +SET(_webp_SEARCH_DIRS + ${WEBP_ROOT_DIR} + /opt/lib/webp +) + +FIND_PATH(WEBP_INCLUDE_DIR + NAMES + webp/types.h + HINTS + ${_webp_SEARCH_DIRS} + PATH_SUFFIXES + include +) + +SET(_webp_FIND_COMPONENTS + webp + webpmux + webpdemux +) + +SET(_webp_LIBRARIES) +FOREACH(COMPONENT ${_webp_FIND_COMPONENTS}) + STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT) + + FIND_LIBRARY(WEBP_${UPPERCOMPONENT}_LIBRARY + NAMES + ${COMPONENT} + NAMES_PER_DIR + HINTS + ${_webp_SEARCH_DIRS} + PATH_SUFFIXES + lib64 lib lib/static + ) + LIST(APPEND _webp_LIBRARIES "${WEBP_${UPPERCOMPONENT}_LIBRARY}") +ENDFOREACH() + +IF(${WEBP_WEBP_LIBRARY_NOTFOUND}) + set(WEBP_FOUND FALSE) +ELSE() + # handle the QUIETLY and REQUIRED arguments and set WEBP_FOUND to TRUE if + # all listed variables are TRUE + INCLUDE(FindPackageHandleStandardArgs) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(WebP DEFAULT_MSG _webp_LIBRARIES WEBP_INCLUDE_DIR) + + IF(WEBP_FOUND) + get_filename_component(WEBP_LIBRARY_DIR ${WEBP_WEBP_LIBRARY} DIRECTORY) + SET(WEBP_INCLUDE_DIRS ${WEBP_INCLUDE_DIR}) + SET(WEBP_LIBRARIES ${_webp_LIBRARIES}) + ELSE() + SET(WEBPL_PUGIXML_FOUND FALSE) + ENDIF() +ENDIF() + +MARK_AS_ADVANCED( + WEBP_INCLUDE_DIR + WEBP_LIBRARY_DIR +) diff --git a/build_files/cmake/packaging.cmake b/build_files/cmake/packaging.cmake index 2079cb7df51..f6073eba82e 100644 --- a/build_files/cmake/packaging.cmake +++ b/build_files/cmake/packaging.cmake @@ -106,8 +106,8 @@ if(WIN32) set(CPACK_WIX_LIGHT_EXTRA_FLAGS -dcl:medium) endif() -set(CPACK_PACKAGE_EXECUTABLES "blender-launcher" "blender") -set(CPACK_CREATE_DESKTOP_LINKS "blender-launcher" "blender") +set(CPACK_PACKAGE_EXECUTABLES "blender-launcher" "Blender") +set(CPACK_CREATE_DESKTOP_LINKS "blender-launcher" "Blender") include(CPack) diff --git a/build_files/cmake/platform/platform_apple.cmake b/build_files/cmake/platform/platform_apple.cmake index b09f2f8917b..43ce23081af 100644 --- a/build_files/cmake/platform/platform_apple.cmake +++ b/build_files/cmake/platform/platform_apple.cmake @@ -232,6 +232,15 @@ if(WITH_IMAGE_TIFF) endif() endif() +if(WITH_IMAGE_WEBP) + set(WEBP_ROOT_DIR ${LIBDIR}/webp) + find_package(WebP) + if(NOT WEBP_FOUND) + message(WARNING "WebP not found, disabling WITH_IMAGE_WEBP") + set(WITH_IMAGE_WEBP OFF) + endif() +endif() + if(WITH_BOOST) set(Boost_NO_BOOST_CMAKE ON) set(BOOST_ROOT ${LIBDIR}/boost) diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake index 0a7119802c8..cc168476d5d 100644 --- a/build_files/cmake/platform/platform_unix.cmake +++ b/build_files/cmake/platform/platform_unix.cmake @@ -368,6 +368,14 @@ if(WITH_PUGIXML) endif() endif() +if(WITH_IMAGE_WEBP) + set(WEBP_ROOT_DIR ${LIBDIR}/webp) + find_package_wrapper(WebP) + if(NOT WEBP_FOUND) + set(WITH_IMAGE_WEBP OFF) + endif() +endif() + if(WITH_OPENIMAGEIO) find_package_wrapper(OpenImageIO) set(OPENIMAGEIO_LIBRARIES diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake index ca4af2274e6..8ae38e03fb1 100644 --- a/build_files/cmake/platform/platform_win32.cmake +++ b/build_files/cmake/platform/platform_win32.cmake @@ -343,6 +343,16 @@ if(WITH_FFTW3) set(FFTW3_LIBPATH ${FFTW3}/lib) endif() +windows_find_package(WebP) +if(NOT WEBP_FOUND) + if(EXISTS ${LIBDIR}/webp) + set(WEBP_INCLUDE_DIRS ${LIBDIR}/webp/include) + set(WEBP_ROOT_DIR ${LIBDIR}/webp) + set(WEBP_LIBRARIES ${LIBDIR}/webp/lib/webp.lib ${LIBDIR}/webp/lib/webpdemux.lib ${LIBDIR}/webp/lib/webpmux.lib) + set(WEBP_FOUND ON) + endif() +endif() + if(WITH_OPENCOLLADA) set(OPENCOLLADA ${LIBDIR}/opencollada) diff --git a/extern/fmtlib/LICENSE.rst b/extern/fmtlib/LICENSE.rst new file mode 100644 index 00000000000..f0ec3db4d2a --- /dev/null +++ b/extern/fmtlib/LICENSE.rst @@ -0,0 +1,27 @@ +Copyright (c) 2012 - present, Victor Zverovich + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--- Optional exception to the license --- + +As an exception, if, as a result of your compiling your source code, portions +of this Software are embedded into a machine-executable object form of such +source code, you may redistribute such embedded portions in such object form +without including the above copyright and permission notices. diff --git a/extern/fmtlib/README.blender b/extern/fmtlib/README.blender new file mode 100644 index 00000000000..98c5684305e --- /dev/null +++ b/extern/fmtlib/README.blender @@ -0,0 +1,8 @@ +Project: {fmt} +URL: https://github.com/fmtlib/fmt +License: MIT +Upstream version: 8.1.1 (b6f4cea) +Local modifications: + +- Took only files needed for Blender: LICENSE, README and include/fmt + folder's core.h, format-inl.h, format.h diff --git a/extern/fmtlib/README.rst b/extern/fmtlib/README.rst new file mode 100644 index 00000000000..394f28d97bb --- /dev/null +++ b/extern/fmtlib/README.rst @@ -0,0 +1,528 @@ +{fmt} +===== + +.. image:: https://github.com/fmtlib/fmt/workflows/linux/badge.svg + :target: https://github.com/fmtlib/fmt/actions?query=workflow%3Alinux + +.. image:: https://github.com/fmtlib/fmt/workflows/macos/badge.svg + :target: https://github.com/fmtlib/fmt/actions?query=workflow%3Amacos + +.. image:: https://github.com/fmtlib/fmt/workflows/windows/badge.svg + :target: https://github.com/fmtlib/fmt/actions?query=workflow%3Awindows + +.. image:: https://ci.appveyor.com/api/projects/status/ehjkiefde6gucy1v?svg=true + :target: https://ci.appveyor.com/project/vitaut/fmt + +.. image:: https://oss-fuzz-build-logs.storage.googleapis.com/badges/fmt.svg + :alt: fmt is continuously fuzzed at oss-fuzz + :target: https://bugs.chromium.org/p/oss-fuzz/issues/list?\ + colspec=ID%20Type%20Component%20Status%20Proj%20Reported%20Owner%20\ + Summary&q=proj%3Dfmt&can=1 + +.. image:: https://img.shields.io/badge/stackoverflow-fmt-blue.svg + :alt: Ask questions at StackOverflow with the tag fmt + :target: https://stackoverflow.com/questions/tagged/fmt + +**{fmt}** is an open-source formatting library providing a fast and safe +alternative to C stdio and C++ iostreams. + +If you like this project, please consider donating to the BYSOL +Foundation that helps victims of political repressions in Belarus: +https://bysol.org/en/bs/general/. + +`Documentation <https://fmt.dev>`__ + +Q&A: ask questions on `StackOverflow with the tag fmt +<https://stackoverflow.com/questions/tagged/fmt>`_. + +Try {fmt} in `Compiler Explorer <https://godbolt.org/z/Eq5763>`_. + +Features +-------- + +* Simple `format API <https://fmt.dev/latest/api.html>`_ with positional arguments + for localization +* Implementation of `C++20 std::format + <https://en.cppreference.com/w/cpp/utility/format>`__ +* `Format string syntax <https://fmt.dev/latest/syntax.html>`_ similar to Python's + `format <https://docs.python.org/3/library/stdtypes.html#str.format>`_ +* Fast IEEE 754 floating-point formatter with correct rounding, shortness and + round-trip guarantees +* Safe `printf implementation + <https://fmt.dev/latest/api.html#printf-formatting>`_ including the POSIX + extension for positional arguments +* Extensibility: `support for user-defined types + <https://fmt.dev/latest/api.html#formatting-user-defined-types>`_ +* High performance: faster than common standard library implementations of + ``(s)printf``, iostreams, ``to_string`` and ``to_chars``, see `Speed tests`_ + and `Converting a hundred million integers to strings per second + <http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html>`_ +* Small code size both in terms of source code with the minimum configuration + consisting of just three files, ``core.h``, ``format.h`` and ``format-inl.h``, + and compiled code; see `Compile time and code bloat`_ +* Reliability: the library has an extensive set of `tests + <https://github.com/fmtlib/fmt/tree/master/test>`_ and is `continuously fuzzed + <https://bugs.chromium.org/p/oss-fuzz/issues/list?colspec=ID%20Type%20 + Component%20Status%20Proj%20Reported%20Owner%20Summary&q=proj%3Dfmt&can=1>`_ +* Safety: the library is fully type safe, errors in format strings can be + reported at compile time, automatic memory management prevents buffer overflow + errors +* Ease of use: small self-contained code base, no external dependencies, + permissive MIT `license + <https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>`_ +* `Portability <https://fmt.dev/latest/index.html#portability>`_ with + consistent output across platforms and support for older compilers +* Clean warning-free codebase even on high warning levels such as + ``-Wall -Wextra -pedantic`` +* Locale-independence by default +* Optional header-only configuration enabled with the ``FMT_HEADER_ONLY`` macro + +See the `documentation <https://fmt.dev>`_ for more details. + +Examples +-------- + +**Print to stdout** (`run <https://godbolt.org/z/Tevcjh>`_) + +.. code:: c++ + + #include <fmt/core.h> + + int main() { + fmt::print("Hello, world!\n"); + } + +**Format a string** (`run <https://godbolt.org/z/oK8h33>`_) + +.. code:: c++ + + std::string s = fmt::format("The answer is {}.", 42); + // s == "The answer is 42." + +**Format a string using positional arguments** (`run <https://godbolt.org/z/Yn7Txe>`_) + +.. code:: c++ + + std::string s = fmt::format("I'd rather be {1} than {0}.", "right", "happy"); + // s == "I'd rather be happy than right." + +**Print chrono durations** (`run <https://godbolt.org/z/K8s4Mc>`_) + +.. code:: c++ + + #include <fmt/chrono.h> + + int main() { + using namespace std::literals::chrono_literals; + fmt::print("Default format: {} {}\n", 42s, 100ms); + fmt::print("strftime-like format: {:%H:%M:%S}\n", 3h + 15min + 30s); + } + +Output:: + + Default format: 42s 100ms + strftime-like format: 03:15:30 + +**Print a container** (`run <https://godbolt.org/z/MjsY7c>`_) + +.. code:: c++ + + #include <vector> + #include <fmt/ranges.h> + + int main() { + std::vector<int> v = {1, 2, 3}; + fmt::print("{}\n", v); + } + +Output:: + + [1, 2, 3] + +**Check a format string at compile time** + +.. code:: c++ + + std::string s = fmt::format("{:d}", "I am not a number"); + +This gives a compile-time error in C++20 because ``d`` is an invalid format +specifier for a string. + +**Write a file from a single thread** + +.. code:: c++ + + #include <fmt/os.h> + + int main() { + auto out = fmt::output_file("guide.txt"); + out.print("Don't {}", "Panic"); + } + +This can be `5 to 9 times faster than fprintf +<http://www.zverovich.net/2020/08/04/optimal-file-buffer-size.html>`_. + +**Print with colors and text styles** + +.. code:: c++ + + #include <fmt/color.h> + + int main() { + fmt::print(fg(fmt::color::crimson) | fmt::emphasis::bold, + "Hello, {}!\n", "world"); + fmt::print(fg(fmt::color::floral_white) | bg(fmt::color::slate_gray) | + fmt::emphasis::underline, "Hello, {}!\n", "мир"); + fmt::print(fg(fmt::color::steel_blue) | fmt::emphasis::italic, + "Hello, {}!\n", "世界"); + } + +Output on a modern terminal: + +.. image:: https://user-images.githubusercontent.com/ + 576385/88485597-d312f600-cf2b-11ea-9cbe-61f535a86e28.png + +Benchmarks +---------- + +Speed tests +~~~~~~~~~~~ + +================= ============= =========== +Library Method Run Time, s +================= ============= =========== +libc printf 1.04 +libc++ std::ostream 3.05 +{fmt} 6.1.1 fmt::print 0.75 +Boost Format 1.67 boost::format 7.24 +Folly Format folly::format 2.23 +================= ============= =========== + +{fmt} is the fastest of the benchmarked methods, ~35% faster than ``printf``. + +The above results were generated by building ``tinyformat_test.cpp`` on macOS +10.14.6 with ``clang++ -O3 -DNDEBUG -DSPEED_TEST -DHAVE_FORMAT``, and taking the +best of three runs. In the test, the format string ``"%0.10f:%04d:%+g:%s:%p:%c:%%\n"`` +or equivalent is filled 2,000,000 times with output sent to ``/dev/null``; for +further details refer to the `source +<https://github.com/fmtlib/format-benchmark/blob/master/src/tinyformat-test.cc>`_. + +{fmt} is up to 20-30x faster than ``std::ostringstream`` and ``sprintf`` on +floating-point formatting (`dtoa-benchmark <https://github.com/fmtlib/dtoa-benchmark>`_) +and faster than `double-conversion <https://github.com/google/double-conversion>`_ and +`ryu <https://github.com/ulfjack/ryu>`_: + +.. image:: https://user-images.githubusercontent.com/576385/ + 95684665-11719600-0ba8-11eb-8e5b-972ff4e49428.png + :target: https://fmt.dev/unknown_mac64_clang12.0.html + +Compile time and code bloat +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The script `bloat-test.py +<https://github.com/fmtlib/format-benchmark/blob/master/bloat-test.py>`_ +from `format-benchmark <https://github.com/fmtlib/format-benchmark>`_ +tests compile time and code bloat for nontrivial projects. +It generates 100 translation units and uses ``printf()`` or its alternative +five times in each to simulate a medium sized project. The resulting +executable size and compile time (Apple LLVM version 8.1.0 (clang-802.0.42), +macOS Sierra, best of three) is shown in the following tables. + +**Optimized build (-O3)** + +============= =============== ==================== ================== +Method Compile Time, s Executable size, KiB Stripped size, KiB +============= =============== ==================== ================== +printf 2.6 29 26 +printf+string 16.4 29 26 +iostreams 31.1 59 55 +{fmt} 19.0 37 34 +Boost Format 91.9 226 203 +Folly Format 115.7 101 88 +============= =============== ==================== ================== + +As you can see, {fmt} has 60% less overhead in terms of resulting binary code +size compared to iostreams and comes pretty close to ``printf``. Boost Format +and Folly Format have the largest overheads. + +``printf+string`` is the same as ``printf`` but with extra ``<string>`` +include to measure the overhead of the latter. + +**Non-optimized build** + +============= =============== ==================== ================== +Method Compile Time, s Executable size, KiB Stripped size, KiB +============= =============== ==================== ================== +printf 2.2 33 30 +printf+string 16.0 33 30 +iostreams 28.3 56 52 +{fmt} 18.2 59 50 +Boost Format 54.1 365 303 +Folly Format 79.9 445 430 +============= =============== ==================== ================== + +``libc``, ``lib(std)c++`` and ``libfmt`` are all linked as shared libraries to +compare formatting function overhead only. Boost Format is a +header-only library so it doesn't provide any linkage options. + +Running the tests +~~~~~~~~~~~~~~~~~ + +Please refer to `Building the library`__ for the instructions on how to build +the library and run the unit tests. + +__ https://fmt.dev/latest/usage.html#building-the-library + +Benchmarks reside in a separate repository, +`format-benchmarks <https://github.com/fmtlib/format-benchmark>`_, +so to run the benchmarks you first need to clone this repository and +generate Makefiles with CMake:: + + $ git clone --recursive https://github.com/fmtlib/format-benchmark.git + $ cd format-benchmark + $ cmake . + +Then you can run the speed test:: + + $ make speed-test + +or the bloat test:: + + $ make bloat-test + +Migrating code +-------------- + +`clang-tidy-fmt <https://github.com/mikecrowe/clang-tidy-fmt>`_ provides clang +tidy checks for converting occurrences of ``printf`` and ``fprintf`` to +``fmt::print``. + +Projects using this library +--------------------------- + +* `0 A.D. <https://play0ad.com/>`_: a free, open-source, cross-platform + real-time strategy game + +* `2GIS <https://2gis.ru/>`_: free business listings with a city map + +* `AMPL/MP <https://github.com/ampl/mp>`_: + an open-source library for mathematical programming + +* `Aseprite <https://github.com/aseprite/aseprite>`_: + animated sprite editor & pixel art tool + +* `AvioBook <https://www.aviobook.aero/en>`_: a comprehensive aircraft + operations suite + +* `Blizzard Battle.net <https://battle.net/>`_: an online gaming platform + +* `Celestia <https://celestia.space/>`_: real-time 3D visualization of space + +* `Ceph <https://ceph.com/>`_: a scalable distributed storage system + +* `ccache <https://ccache.dev/>`_: a compiler cache + +* `ClickHouse <https://github.com/ClickHouse/ClickHouse>`_: analytical database + management system + +* `CUAUV <https://cuauv.org/>`_: Cornell University's autonomous underwater + vehicle + +* `Drake <https://drake.mit.edu/>`_: a planning, control, and analysis toolbox + for nonlinear dynamical systems (MIT) + +* `Envoy <https://lyft.github.io/envoy/>`_: C++ L7 proxy and communication bus + (Lyft) + +* `FiveM <https://fivem.net/>`_: a modification framework for GTA V + +* `fmtlog <https://github.com/MengRao/fmtlog>`_: a performant fmtlib-style + logging library with latency in nanoseconds + +* `Folly <https://github.com/facebook/folly>`_: Facebook open-source library + +* `Grand Mountain Adventure + <https://store.steampowered.com/app/1247360/Grand_Mountain_Adventure/>`_: + A beautiful open-world ski & snowboarding game + +* `HarpyWar/pvpgn <https://github.com/pvpgn/pvpgn-server>`_: + Player vs Player Gaming Network with tweaks + +* `KBEngine <https://github.com/kbengine/kbengine>`_: an open-source MMOG server + engine + +* `Keypirinha <https://keypirinha.com/>`_: a semantic launcher for Windows + +* `Kodi <https://kodi.tv/>`_ (formerly xbmc): home theater software + +* `Knuth <https://kth.cash/>`_: high-performance Bitcoin full-node + +* `Microsoft Verona <https://github.com/microsoft/verona>`_: + research programming language for concurrent ownership + +* `MongoDB <https://mongodb.com/>`_: distributed document database + +* `MongoDB Smasher <https://github.com/duckie/mongo_smasher>`_: a small tool to + generate randomized datasets + +* `OpenSpace <https://openspaceproject.com/>`_: an open-source + astrovisualization framework + +* `PenUltima Online (POL) <https://www.polserver.com/>`_: + an MMO server, compatible with most Ultima Online clients + +* `PyTorch <https://github.com/pytorch/pytorch>`_: an open-source machine + learning library + +* `quasardb <https://www.quasardb.net/>`_: a distributed, high-performance, + associative database + +* `Quill <https://github.com/odygrd/quill>`_: asynchronous low-latency logging library + +* `QKW <https://github.com/ravijanjam/qkw>`_: generalizing aliasing to simplify + navigation, and executing complex multi-line terminal command sequences + +* `redis-cerberus <https://github.com/HunanTV/redis-cerberus>`_: a Redis cluster + proxy + +* `redpanda <https://vectorized.io/redpanda>`_: a 10x faster Kafka® replacement + for mission critical systems written in C++ + +* `rpclib <http://rpclib.net/>`_: a modern C++ msgpack-RPC server and client + library + +* `Salesforce Analytics Cloud + <https://www.salesforce.com/analytics-cloud/overview/>`_: + business intelligence software + +* `Scylla <https://www.scylladb.com/>`_: a Cassandra-compatible NoSQL data store + that can handle 1 million transactions per second on a single server + +* `Seastar <http://www.seastar-project.org/>`_: an advanced, open-source C++ + framework for high-performance server applications on modern hardware + +* `spdlog <https://github.com/gabime/spdlog>`_: super fast C++ logging library + +* `Stellar <https://www.stellar.org/>`_: financial platform + +* `Touch Surgery <https://www.touchsurgery.com/>`_: surgery simulator + +* `TrinityCore <https://github.com/TrinityCore/TrinityCore>`_: open-source + MMORPG framework + +* `Windows Terminal <https://github.com/microsoft/terminal>`_: the new Windows + terminal + +`More... <https://github.com/search?q=fmtlib&type=Code>`_ + +If you are aware of other projects using this library, please let me know +by `email <mailto:victor.zverovich@gmail.com>`_ or by submitting an +`issue <https://github.com/fmtlib/fmt/issues>`_. + +Motivation +---------- + +So why yet another formatting library? + +There are plenty of methods for doing this task, from standard ones like +the printf family of function and iostreams to Boost Format and FastFormat +libraries. The reason for creating a new library is that every existing +solution that I found either had serious issues or didn't provide +all the features I needed. + +printf +~~~~~~ + +The good thing about ``printf`` is that it is pretty fast and readily available +being a part of the C standard library. The main drawback is that it +doesn't support user-defined types. ``printf`` also has safety issues although +they are somewhat mitigated with `__attribute__ ((format (printf, ...)) +<https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ in GCC. +There is a POSIX extension that adds positional arguments required for +`i18n <https://en.wikipedia.org/wiki/Internationalization_and_localization>`_ +to ``printf`` but it is not a part of C99 and may not be available on some +platforms. + +iostreams +~~~~~~~~~ + +The main issue with iostreams is best illustrated with an example: + +.. code:: c++ + + std::cout << std::setprecision(2) << std::fixed << 1.23456 << "\n"; + +which is a lot of typing compared to printf: + +.. code:: c++ + + printf("%.2f\n", 1.23456); + +Matthew Wilson, the author of FastFormat, called this "chevron hell". iostreams +don't support positional arguments by design. + +The good part is that iostreams support user-defined types and are safe although +error handling is awkward. + +Boost Format +~~~~~~~~~~~~ + +This is a very powerful library which supports both ``printf``-like format +strings and positional arguments. Its main drawback is performance. According to +various benchmarks, it is much slower than other methods considered here. Boost +Format also has excessive build times and severe code bloat issues (see +`Benchmarks`_). + +FastFormat +~~~~~~~~~~ + +This is an interesting library which is fast, safe and has positional arguments. +However, it has significant limitations, citing its author: + + Three features that have no hope of being accommodated within the + current design are: + + * Leading zeros (or any other non-space padding) + * Octal/hexadecimal encoding + * Runtime width/alignment specification + +It is also quite big and has a heavy dependency, STLSoft, which might be too +restrictive for using it in some projects. + +Boost Spirit.Karma +~~~~~~~~~~~~~~~~~~ + +This is not really a formatting library but I decided to include it here for +completeness. As iostreams, it suffers from the problem of mixing verbatim text +with arguments. The library is pretty fast, but slower on integer formatting +than ``fmt::format_to`` with format string compilation on Karma's own benchmark, +see `Converting a hundred million integers to strings per second +<http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html>`_. + +License +------- + +{fmt} is distributed under the MIT `license +<https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>`_. + +Documentation License +--------------------- + +The `Format String Syntax <https://fmt.dev/latest/syntax.html>`_ +section in the documentation is based on the one from Python `string module +documentation <https://docs.python.org/3/library/string.html#module-string>`_. +For this reason the documentation is distributed under the Python Software +Foundation license available in `doc/python-license.txt +<https://raw.github.com/fmtlib/fmt/master/doc/python-license.txt>`_. +It only applies if you distribute the documentation of {fmt}. + +Maintainers +----------- + +The {fmt} library is maintained by Victor Zverovich (`vitaut +<https://github.com/vitaut>`_) and Jonathan Müller (`foonathan +<https://github.com/foonathan>`_) with contributions from many other people. +See `Contributors <https://github.com/fmtlib/fmt/graphs/contributors>`_ and +`Releases <https://github.com/fmtlib/fmt/releases>`_ for some of the names. +Let us know if your contribution is not listed or mentioned incorrectly and +we'll make it right. diff --git a/extern/fmtlib/include/fmt/core.h b/extern/fmtlib/include/fmt/core.h new file mode 100644 index 00000000000..92a7aa1df69 --- /dev/null +++ b/extern/fmtlib/include/fmt/core.h @@ -0,0 +1,3236 @@ +// Formatting library for C++ - the core API for char/UTF-8 +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#ifndef FMT_CORE_H_ +#define FMT_CORE_H_ + +#include <cstddef> // std::byte +#include <cstdio> // std::FILE +#include <cstring> +#include <iterator> +#include <limits> +#include <string> +#include <type_traits> + +// The fmt library version in the form major * 10000 + minor * 100 + patch. +#define FMT_VERSION 80101 + +#if defined(__clang__) && !defined(__ibmxl__) +# define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__) +#else +# define FMT_CLANG_VERSION 0 +#endif + +#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER) && \ + !defined(__NVCOMPILER) +# define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) +#else +# define FMT_GCC_VERSION 0 +#endif + +#ifndef FMT_GCC_PRAGMA +// Workaround _Pragma bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59884. +# if FMT_GCC_VERSION >= 504 +# define FMT_GCC_PRAGMA(arg) _Pragma(arg) +# else +# define FMT_GCC_PRAGMA(arg) +# endif +#endif + +#ifdef __ICL +# define FMT_ICC_VERSION __ICL +#elif defined(__INTEL_COMPILER) +# define FMT_ICC_VERSION __INTEL_COMPILER +#else +# define FMT_ICC_VERSION 0 +#endif + +#ifdef __NVCC__ +# define FMT_NVCC __NVCC__ +#else +# define FMT_NVCC 0 +#endif + +#ifdef _MSC_VER +# define FMT_MSC_VER _MSC_VER +# define FMT_MSC_WARNING(...) __pragma(warning(__VA_ARGS__)) +#else +# define FMT_MSC_VER 0 +# define FMT_MSC_WARNING(...) +#endif + +#ifdef __has_feature +# define FMT_HAS_FEATURE(x) __has_feature(x) +#else +# define FMT_HAS_FEATURE(x) 0 +#endif + +#if defined(__has_include) && \ + (!defined(__INTELLISENSE__) || FMT_MSC_VER > 1900) && \ + (!FMT_ICC_VERSION || FMT_ICC_VERSION >= 1600) +# define FMT_HAS_INCLUDE(x) __has_include(x) +#else +# define FMT_HAS_INCLUDE(x) 0 +#endif + +#ifdef __has_cpp_attribute +# define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +#else +# define FMT_HAS_CPP_ATTRIBUTE(x) 0 +#endif + +#ifdef _MSVC_LANG +# define FMT_CPLUSPLUS _MSVC_LANG +#else +# define FMT_CPLUSPLUS __cplusplus +#endif + +#define FMT_HAS_CPP14_ATTRIBUTE(attribute) \ + (FMT_CPLUSPLUS >= 201402L && FMT_HAS_CPP_ATTRIBUTE(attribute)) + +#define FMT_HAS_CPP17_ATTRIBUTE(attribute) \ + (FMT_CPLUSPLUS >= 201703L && FMT_HAS_CPP_ATTRIBUTE(attribute)) + +// Check if relaxed C++14 constexpr is supported. +// GCC doesn't allow throw in constexpr until version 6 (bug 67371). +#ifndef FMT_USE_CONSTEXPR +# define FMT_USE_CONSTEXPR \ + (FMT_HAS_FEATURE(cxx_relaxed_constexpr) || FMT_MSC_VER >= 1912 || \ + (FMT_GCC_VERSION >= 600 && __cplusplus >= 201402L)) && \ + !FMT_NVCC && !FMT_ICC_VERSION +#endif +#if FMT_USE_CONSTEXPR +# define FMT_CONSTEXPR constexpr +# define FMT_CONSTEXPR_DECL constexpr +#else +# define FMT_CONSTEXPR +# define FMT_CONSTEXPR_DECL +#endif + +#if ((__cplusplus >= 202002L) && \ + (!defined(_GLIBCXX_RELEASE) || _GLIBCXX_RELEASE > 9)) || \ + (__cplusplus >= 201709L && FMT_GCC_VERSION >= 1002) +# define FMT_CONSTEXPR20 constexpr +#else +# define FMT_CONSTEXPR20 +#endif + +// Check if constexpr std::char_traits<>::compare,length is supported. +#if defined(__GLIBCXX__) +# if __cplusplus >= 201703L && defined(_GLIBCXX_RELEASE) && \ + _GLIBCXX_RELEASE >= 7 // GCC 7+ libstdc++ has _GLIBCXX_RELEASE. +# define FMT_CONSTEXPR_CHAR_TRAITS constexpr +# endif +#elif defined(_LIBCPP_VERSION) && __cplusplus >= 201703L && \ + _LIBCPP_VERSION >= 4000 +# define FMT_CONSTEXPR_CHAR_TRAITS constexpr +#elif FMT_MSC_VER >= 1914 && _MSVC_LANG >= 201703L +# define FMT_CONSTEXPR_CHAR_TRAITS constexpr +#endif +#ifndef FMT_CONSTEXPR_CHAR_TRAITS +# define FMT_CONSTEXPR_CHAR_TRAITS +#endif + +// Check if exceptions are disabled. +#ifndef FMT_EXCEPTIONS +# if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || \ + FMT_MSC_VER && !_HAS_EXCEPTIONS +# define FMT_EXCEPTIONS 0 +# else +# define FMT_EXCEPTIONS 1 +# endif +#endif + +// Define FMT_USE_NOEXCEPT to make fmt use noexcept (C++11 feature). +#ifndef FMT_USE_NOEXCEPT +# define FMT_USE_NOEXCEPT 0 +#endif + +#if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \ + FMT_GCC_VERSION >= 408 || FMT_MSC_VER >= 1900 +# define FMT_DETECTED_NOEXCEPT noexcept +# define FMT_HAS_CXX11_NOEXCEPT 1 +#else +# define FMT_DETECTED_NOEXCEPT throw() +# define FMT_HAS_CXX11_NOEXCEPT 0 +#endif + +#ifndef FMT_NOEXCEPT +# if FMT_EXCEPTIONS || FMT_HAS_CXX11_NOEXCEPT +# define FMT_NOEXCEPT FMT_DETECTED_NOEXCEPT +# else +# define FMT_NOEXCEPT +# endif +#endif + +// [[noreturn]] is disabled on MSVC and NVCC because of bogus unreachable code +// warnings. +#if FMT_EXCEPTIONS && FMT_HAS_CPP_ATTRIBUTE(noreturn) && !FMT_MSC_VER && \ + !FMT_NVCC +# define FMT_NORETURN [[noreturn]] +#else +# define FMT_NORETURN +#endif + +#if __cplusplus == 201103L || __cplusplus == 201402L +# if defined(__INTEL_COMPILER) || defined(__PGI) +# define FMT_FALLTHROUGH +# elif defined(__clang__) +# define FMT_FALLTHROUGH [[clang::fallthrough]] +# elif FMT_GCC_VERSION >= 700 && \ + (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 520) +# define FMT_FALLTHROUGH [[gnu::fallthrough]] +# else +# define FMT_FALLTHROUGH +# endif +#elif FMT_HAS_CPP17_ATTRIBUTE(fallthrough) +# define FMT_FALLTHROUGH [[fallthrough]] +#else +# define FMT_FALLTHROUGH +#endif + +#ifndef FMT_NODISCARD +# if FMT_HAS_CPP17_ATTRIBUTE(nodiscard) +# define FMT_NODISCARD [[nodiscard]] +# else +# define FMT_NODISCARD +# endif +#endif + +#ifndef FMT_USE_FLOAT +# define FMT_USE_FLOAT 1 +#endif +#ifndef FMT_USE_DOUBLE +# define FMT_USE_DOUBLE 1 +#endif +#ifndef FMT_USE_LONG_DOUBLE +# define FMT_USE_LONG_DOUBLE 1 +#endif + +#ifndef FMT_INLINE +# if FMT_GCC_VERSION || FMT_CLANG_VERSION +# define FMT_INLINE inline __attribute__((always_inline)) +# else +# define FMT_INLINE inline +# endif +#endif + +#ifndef FMT_DEPRECATED +# if FMT_HAS_CPP14_ATTRIBUTE(deprecated) || FMT_MSC_VER >= 1900 +# define FMT_DEPRECATED [[deprecated]] +# else +# if (defined(__GNUC__) && !defined(__LCC__)) || defined(__clang__) +# define FMT_DEPRECATED __attribute__((deprecated)) +# elif FMT_MSC_VER +# define FMT_DEPRECATED __declspec(deprecated) +# else +# define FMT_DEPRECATED /* deprecated */ +# endif +# endif +#endif + +#ifndef FMT_BEGIN_NAMESPACE +# define FMT_BEGIN_NAMESPACE \ + namespace fmt { \ + inline namespace v8 { +# define FMT_END_NAMESPACE \ + } \ + } +#endif + +#ifndef FMT_MODULE_EXPORT +# define FMT_MODULE_EXPORT +# define FMT_MODULE_EXPORT_BEGIN +# define FMT_MODULE_EXPORT_END +# define FMT_BEGIN_DETAIL_NAMESPACE namespace detail { +# define FMT_END_DETAIL_NAMESPACE } +#endif + +#if !defined(FMT_HEADER_ONLY) && defined(_WIN32) +# define FMT_CLASS_API FMT_MSC_WARNING(suppress : 4275) +# ifdef FMT_EXPORT +# define FMT_API __declspec(dllexport) +# elif defined(FMT_SHARED) +# define FMT_API __declspec(dllimport) +# endif +#else +# define FMT_CLASS_API +# if defined(FMT_EXPORT) || defined(FMT_SHARED) +# if defined(__GNUC__) || defined(__clang__) +# define FMT_API __attribute__((visibility("default"))) +# endif +# endif +#endif +#ifndef FMT_API +# define FMT_API +#endif + +// libc++ supports string_view in pre-c++17. +#if (FMT_HAS_INCLUDE(<string_view>) && \ + (__cplusplus > 201402L || defined(_LIBCPP_VERSION))) || \ + (defined(_MSVC_LANG) && _MSVC_LANG > 201402L && _MSC_VER >= 1910) +# include <string_view> +# define FMT_USE_STRING_VIEW +#elif FMT_HAS_INCLUDE("experimental/string_view") && __cplusplus >= 201402L +# include <experimental/string_view> +# define FMT_USE_EXPERIMENTAL_STRING_VIEW +#endif + +#ifndef FMT_UNICODE +# define FMT_UNICODE !FMT_MSC_VER +#endif + +#ifndef FMT_CONSTEVAL +# if ((FMT_GCC_VERSION >= 1000 || FMT_CLANG_VERSION >= 1101) && \ + __cplusplus > 201703L && !defined(__apple_build_version__)) || \ + (defined(__cpp_consteval) && \ + (!FMT_MSC_VER || _MSC_FULL_VER >= 193030704)) +// consteval is broken in MSVC before VS2022 and Apple clang 13. +# define FMT_CONSTEVAL consteval +# define FMT_HAS_CONSTEVAL +# else +# define FMT_CONSTEVAL +# endif +#endif + +#ifndef FMT_USE_NONTYPE_TEMPLATE_PARAMETERS +# if defined(__cpp_nontype_template_args) && \ + ((FMT_GCC_VERSION >= 903 && __cplusplus >= 201709L) || \ + __cpp_nontype_template_args >= 201911L) +# define FMT_USE_NONTYPE_TEMPLATE_PARAMETERS 1 +# else +# define FMT_USE_NONTYPE_TEMPLATE_PARAMETERS 0 +# endif +#endif + +// Enable minimal optimizations for more compact code in debug mode. +FMT_GCC_PRAGMA("GCC push_options") +#ifndef __OPTIMIZE__ +FMT_GCC_PRAGMA("GCC optimize(\"Og\")") +#endif + +FMT_BEGIN_NAMESPACE +FMT_MODULE_EXPORT_BEGIN + +// Implementations of enable_if_t and other metafunctions for older systems. +template <bool B, typename T = void> +using enable_if_t = typename std::enable_if<B, T>::type; +template <bool B, typename T, typename F> +using conditional_t = typename std::conditional<B, T, F>::type; +template <bool B> using bool_constant = std::integral_constant<bool, B>; +template <typename T> +using remove_reference_t = typename std::remove_reference<T>::type; +template <typename T> +using remove_const_t = typename std::remove_const<T>::type; +template <typename T> +using remove_cvref_t = typename std::remove_cv<remove_reference_t<T>>::type; +template <typename T> struct type_identity { using type = T; }; +template <typename T> using type_identity_t = typename type_identity<T>::type; + +struct monostate { + constexpr monostate() {} +}; + +// An enable_if helper to be used in template parameters which results in much +// shorter symbols: https://godbolt.org/z/sWw4vP. Extra parentheses are needed +// to workaround a bug in MSVC 2019 (see #1140 and #1186). +#ifdef FMT_DOC +# define FMT_ENABLE_IF(...) +#else +# define FMT_ENABLE_IF(...) enable_if_t<(__VA_ARGS__), int> = 0 +#endif + +FMT_BEGIN_DETAIL_NAMESPACE + +// Suppress "unused variable" warnings with the method described in +// https://herbsutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings/. +// (void)var does not work on many Intel compilers. +template <typename... T> FMT_CONSTEXPR void ignore_unused(const T&...) {} + +constexpr FMT_INLINE auto is_constant_evaluated(bool default_value = false) + FMT_NOEXCEPT -> bool { +#ifdef __cpp_lib_is_constant_evaluated + ignore_unused(default_value); + return std::is_constant_evaluated(); +#else + return default_value; +#endif +} + +// A function to suppress "conditional expression is constant" warnings. +template <typename T> constexpr FMT_INLINE auto const_check(T value) -> T { + return value; +} + +FMT_NORETURN FMT_API void assert_fail(const char* file, int line, + const char* message); + +#ifndef FMT_ASSERT +# ifdef NDEBUG +// FMT_ASSERT is not empty to avoid -Werror=empty-body. +# define FMT_ASSERT(condition, message) \ + ::fmt::detail::ignore_unused((condition), (message)) +# else +# define FMT_ASSERT(condition, message) \ + ((condition) /* void() fails with -Winvalid-constexpr on clang 4.0.1 */ \ + ? (void)0 \ + : ::fmt::detail::assert_fail(__FILE__, __LINE__, (message))) +# endif +#endif + +#ifdef __cpp_lib_byte +using byte = std::byte; +#else +enum class byte : unsigned char {}; +#endif + +#if defined(FMT_USE_STRING_VIEW) +template <typename Char> using std_string_view = std::basic_string_view<Char>; +#elif defined(FMT_USE_EXPERIMENTAL_STRING_VIEW) +template <typename Char> +using std_string_view = std::experimental::basic_string_view<Char>; +#else +template <typename T> struct std_string_view {}; +#endif + +#ifdef FMT_USE_INT128 +// Do nothing. +#elif defined(__SIZEOF_INT128__) && !FMT_NVCC && \ + !(FMT_CLANG_VERSION && FMT_MSC_VER) +# define FMT_USE_INT128 1 +using int128_t = __int128_t; +using uint128_t = __uint128_t; +template <typename T> inline auto convert_for_visit(T value) -> T { + return value; +} +#else +# define FMT_USE_INT128 0 +#endif +#if !FMT_USE_INT128 +enum class int128_t {}; +enum class uint128_t {}; +// Reduce template instantiations. +template <typename T> inline auto convert_for_visit(T) -> monostate { + return {}; +} +#endif + +// Casts a nonnegative integer to unsigned. +template <typename Int> +FMT_CONSTEXPR auto to_unsigned(Int value) -> + typename std::make_unsigned<Int>::type { + FMT_ASSERT(value >= 0, "negative value"); + return static_cast<typename std::make_unsigned<Int>::type>(value); +} + +FMT_MSC_WARNING(suppress : 4566) constexpr unsigned char micro[] = "\u00B5"; + +constexpr auto is_utf8() -> bool { + // Avoid buggy sign extensions in MSVC's constant evaluation mode. + // https://developercommunity.visualstudio.com/t/C-difference-in-behavior-for-unsigned/1233612 + using uchar = unsigned char; + return FMT_UNICODE || (sizeof(micro) == 3 && uchar(micro[0]) == 0xC2 && + uchar(micro[1]) == 0xB5); +} +FMT_END_DETAIL_NAMESPACE + +/** + An implementation of ``std::basic_string_view`` for pre-C++17. It provides a + subset of the API. ``fmt::basic_string_view`` is used for format strings even + if ``std::string_view`` is available to prevent issues when a library is + compiled with a different ``-std`` option than the client code (which is not + recommended). + */ +template <typename Char> class basic_string_view { + private: + const Char* data_; + size_t size_; + + public: + using value_type = Char; + using iterator = const Char*; + + constexpr basic_string_view() FMT_NOEXCEPT : data_(nullptr), size_(0) {} + + /** Constructs a string reference object from a C string and a size. */ + constexpr basic_string_view(const Char* s, size_t count) FMT_NOEXCEPT + : data_(s), + size_(count) {} + + /** + \rst + Constructs a string reference object from a C string computing + the size with ``std::char_traits<Char>::length``. + \endrst + */ + FMT_CONSTEXPR_CHAR_TRAITS + FMT_INLINE + basic_string_view(const Char* s) + : data_(s), + size_(detail::const_check(std::is_same<Char, char>::value && + !detail::is_constant_evaluated(true)) + ? std::strlen(reinterpret_cast<const char*>(s)) + : std::char_traits<Char>::length(s)) {} + + /** Constructs a string reference from a ``std::basic_string`` object. */ + template <typename Traits, typename Alloc> + FMT_CONSTEXPR basic_string_view( + const std::basic_string<Char, Traits, Alloc>& s) FMT_NOEXCEPT + : data_(s.data()), + size_(s.size()) {} + + template <typename S, FMT_ENABLE_IF(std::is_same< + S, detail::std_string_view<Char>>::value)> + FMT_CONSTEXPR basic_string_view(S s) FMT_NOEXCEPT : data_(s.data()), + size_(s.size()) {} + + /** Returns a pointer to the string data. */ + constexpr auto data() const FMT_NOEXCEPT -> const Char* { return data_; } + + /** Returns the string size. */ + constexpr auto size() const FMT_NOEXCEPT -> size_t { return size_; } + + constexpr auto begin() const FMT_NOEXCEPT -> iterator { return data_; } + constexpr auto end() const FMT_NOEXCEPT -> iterator { return data_ + size_; } + + constexpr auto operator[](size_t pos) const FMT_NOEXCEPT -> const Char& { + return data_[pos]; + } + + FMT_CONSTEXPR void remove_prefix(size_t n) FMT_NOEXCEPT { + data_ += n; + size_ -= n; + } + + // Lexicographically compare this string reference to other. + FMT_CONSTEXPR_CHAR_TRAITS auto compare(basic_string_view other) const -> int { + size_t str_size = size_ < other.size_ ? size_ : other.size_; + int result = std::char_traits<Char>::compare(data_, other.data_, str_size); + if (result == 0) + result = size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1); + return result; + } + + FMT_CONSTEXPR_CHAR_TRAITS friend auto operator==(basic_string_view lhs, + basic_string_view rhs) + -> bool { + return lhs.compare(rhs) == 0; + } + friend auto operator!=(basic_string_view lhs, basic_string_view rhs) -> bool { + return lhs.compare(rhs) != 0; + } + friend auto operator<(basic_string_view lhs, basic_string_view rhs) -> bool { + return lhs.compare(rhs) < 0; + } + friend auto operator<=(basic_string_view lhs, basic_string_view rhs) -> bool { + return lhs.compare(rhs) <= 0; + } + friend auto operator>(basic_string_view lhs, basic_string_view rhs) -> bool { + return lhs.compare(rhs) > 0; + } + friend auto operator>=(basic_string_view lhs, basic_string_view rhs) -> bool { + return lhs.compare(rhs) >= 0; + } +}; + +using string_view = basic_string_view<char>; + +/** Specifies if ``T`` is a character type. Can be specialized by users. */ +template <typename T> struct is_char : std::false_type {}; +template <> struct is_char<char> : std::true_type {}; + +// Returns a string view of `s`. +template <typename Char, FMT_ENABLE_IF(is_char<Char>::value)> +FMT_INLINE auto to_string_view(const Char* s) -> basic_string_view<Char> { + return s; +} +template <typename Char, typename Traits, typename Alloc> +inline auto to_string_view(const std::basic_string<Char, Traits, Alloc>& s) + -> basic_string_view<Char> { + return s; +} +template <typename Char> +constexpr auto to_string_view(basic_string_view<Char> s) + -> basic_string_view<Char> { + return s; +} +template <typename Char, + FMT_ENABLE_IF(!std::is_empty<detail::std_string_view<Char>>::value)> +inline auto to_string_view(detail::std_string_view<Char> s) + -> basic_string_view<Char> { + return s; +} + +// A base class for compile-time strings. It is defined in the fmt namespace to +// make formatting functions visible via ADL, e.g. format(FMT_STRING("{}"), 42). +struct compile_string {}; + +template <typename S> +struct is_compile_string : std::is_base_of<compile_string, S> {}; + +template <typename S, FMT_ENABLE_IF(is_compile_string<S>::value)> +constexpr auto to_string_view(const S& s) + -> basic_string_view<typename S::char_type> { + return basic_string_view<typename S::char_type>(s); +} + +FMT_BEGIN_DETAIL_NAMESPACE + +void to_string_view(...); +using fmt::to_string_view; + +// Specifies whether S is a string type convertible to fmt::basic_string_view. +// It should be a constexpr function but MSVC 2017 fails to compile it in +// enable_if and MSVC 2015 fails to compile it as an alias template. +template <typename S> +struct is_string : std::is_class<decltype(to_string_view(std::declval<S>()))> { +}; + +template <typename S, typename = void> struct char_t_impl {}; +template <typename S> struct char_t_impl<S, enable_if_t<is_string<S>::value>> { + using result = decltype(to_string_view(std::declval<S>())); + using type = typename result::value_type; +}; + +// Reports a compile-time error if S is not a valid format string. +template <typename..., typename S, FMT_ENABLE_IF(!is_compile_string<S>::value)> +FMT_INLINE void check_format_string(const S&) { +#ifdef FMT_ENFORCE_COMPILE_STRING + static_assert(is_compile_string<S>::value, + "FMT_ENFORCE_COMPILE_STRING requires all format strings to use " + "FMT_STRING."); +#endif +} +template <typename..., typename S, FMT_ENABLE_IF(is_compile_string<S>::value)> +void check_format_string(S); + +FMT_NORETURN FMT_API void throw_format_error(const char* message); + +struct error_handler { + constexpr error_handler() = default; + constexpr error_handler(const error_handler&) = default; + + // This function is intentionally not constexpr to give a compile-time error. + FMT_NORETURN FMT_API void on_error(const char* message); +}; +FMT_END_DETAIL_NAMESPACE + +/** String's character type. */ +template <typename S> using char_t = typename detail::char_t_impl<S>::type; + +/** + \rst + Parsing context consisting of a format string range being parsed and an + argument counter for automatic indexing. + You can use the ``format_parse_context`` type alias for ``char`` instead. + \endrst + */ +template <typename Char, typename ErrorHandler = detail::error_handler> +class basic_format_parse_context : private ErrorHandler { + private: + basic_string_view<Char> format_str_; + int next_arg_id_; + + public: + using char_type = Char; + using iterator = typename basic_string_view<Char>::iterator; + + explicit constexpr basic_format_parse_context( + basic_string_view<Char> format_str, ErrorHandler eh = {}, + int next_arg_id = 0) + : ErrorHandler(eh), format_str_(format_str), next_arg_id_(next_arg_id) {} + + /** + Returns an iterator to the beginning of the format string range being + parsed. + */ + constexpr auto begin() const FMT_NOEXCEPT -> iterator { + return format_str_.begin(); + } + + /** + Returns an iterator past the end of the format string range being parsed. + */ + constexpr auto end() const FMT_NOEXCEPT -> iterator { + return format_str_.end(); + } + + /** Advances the begin iterator to ``it``. */ + FMT_CONSTEXPR void advance_to(iterator it) { + format_str_.remove_prefix(detail::to_unsigned(it - begin())); + } + + /** + Reports an error if using the manual argument indexing; otherwise returns + the next argument index and switches to the automatic indexing. + */ + FMT_CONSTEXPR auto next_arg_id() -> int { + // Don't check if the argument id is valid to avoid overhead and because it + // will be checked during formatting anyway. + if (next_arg_id_ >= 0) return next_arg_id_++; + on_error("cannot switch from manual to automatic argument indexing"); + return 0; + } + + /** + Reports an error if using the automatic argument indexing; otherwise + switches to the manual indexing. + */ + FMT_CONSTEXPR void check_arg_id(int) { + if (next_arg_id_ > 0) + on_error("cannot switch from automatic to manual argument indexing"); + else + next_arg_id_ = -1; + } + + FMT_CONSTEXPR void check_arg_id(basic_string_view<Char>) {} + + FMT_CONSTEXPR void on_error(const char* message) { + ErrorHandler::on_error(message); + } + + constexpr auto error_handler() const -> ErrorHandler { return *this; } +}; + +using format_parse_context = basic_format_parse_context<char>; + +template <typename Context> class basic_format_arg; +template <typename Context> class basic_format_args; +template <typename Context> class dynamic_format_arg_store; + +// A formatter for objects of type T. +template <typename T, typename Char = char, typename Enable = void> +struct formatter { + // A deleted default constructor indicates a disabled formatter. + formatter() = delete; +}; + +// Specifies if T has an enabled formatter specialization. A type can be +// formattable even if it doesn't have a formatter e.g. via a conversion. +template <typename T, typename Context> +using has_formatter = + std::is_constructible<typename Context::template formatter_type<T>>; + +// Checks whether T is a container with contiguous storage. +template <typename T> struct is_contiguous : std::false_type {}; +template <typename Char> +struct is_contiguous<std::basic_string<Char>> : std::true_type {}; + +class appender; + +FMT_BEGIN_DETAIL_NAMESPACE + +template <typename Context, typename T> +constexpr auto has_const_formatter_impl(T*) + -> decltype(typename Context::template formatter_type<T>().format( + std::declval<const T&>(), std::declval<Context&>()), + true) { + return true; +} +template <typename Context> +constexpr auto has_const_formatter_impl(...) -> bool { + return false; +} +template <typename T, typename Context> +constexpr auto has_const_formatter() -> bool { + return has_const_formatter_impl<Context>(static_cast<T*>(nullptr)); +} + +// Extracts a reference to the container from back_insert_iterator. +template <typename Container> +inline auto get_container(std::back_insert_iterator<Container> it) + -> Container& { + using bi_iterator = std::back_insert_iterator<Container>; + struct accessor : bi_iterator { + accessor(bi_iterator iter) : bi_iterator(iter) {} + using bi_iterator::container; + }; + return *accessor(it).container; +} + +template <typename Char, typename InputIt, typename OutputIt> +FMT_CONSTEXPR auto copy_str(InputIt begin, InputIt end, OutputIt out) + -> OutputIt { + while (begin != end) *out++ = static_cast<Char>(*begin++); + return out; +} + +template <typename Char, typename T, typename U, + FMT_ENABLE_IF( + std::is_same<remove_const_t<T>, U>::value&& is_char<U>::value)> +FMT_CONSTEXPR auto copy_str(T* begin, T* end, U* out) -> U* { + if (is_constant_evaluated()) return copy_str<Char, T*, U*>(begin, end, out); + auto size = to_unsigned(end - begin); + memcpy(out, begin, size * sizeof(U)); + return out + size; +} + +/** + \rst + A contiguous memory buffer with an optional growing ability. It is an internal + class and shouldn't be used directly, only via `~fmt::basic_memory_buffer`. + \endrst + */ +template <typename T> class buffer { + private: + T* ptr_; + size_t size_; + size_t capacity_; + + protected: + // Don't initialize ptr_ since it is not accessed to save a few cycles. + FMT_MSC_WARNING(suppress : 26495) + buffer(size_t sz) FMT_NOEXCEPT : size_(sz), capacity_(sz) {} + + FMT_CONSTEXPR20 buffer(T* p = nullptr, size_t sz = 0, + size_t cap = 0) FMT_NOEXCEPT : ptr_(p), + size_(sz), + capacity_(cap) {} + + FMT_CONSTEXPR20 ~buffer() = default; + buffer(buffer&&) = default; + + /** Sets the buffer data and capacity. */ + FMT_CONSTEXPR void set(T* buf_data, size_t buf_capacity) FMT_NOEXCEPT { + ptr_ = buf_data; + capacity_ = buf_capacity; + } + + /** Increases the buffer capacity to hold at least *capacity* elements. */ + virtual FMT_CONSTEXPR20 void grow(size_t capacity) = 0; + + public: + using value_type = T; + using const_reference = const T&; + + buffer(const buffer&) = delete; + void operator=(const buffer&) = delete; + + auto begin() FMT_NOEXCEPT -> T* { return ptr_; } + auto end() FMT_NOEXCEPT -> T* { return ptr_ + size_; } + + auto begin() const FMT_NOEXCEPT -> const T* { return ptr_; } + auto end() const FMT_NOEXCEPT -> const T* { return ptr_ + size_; } + + /** Returns the size of this buffer. */ + constexpr auto size() const FMT_NOEXCEPT -> size_t { return size_; } + + /** Returns the capacity of this buffer. */ + constexpr auto capacity() const FMT_NOEXCEPT -> size_t { return capacity_; } + + /** Returns a pointer to the buffer data. */ + FMT_CONSTEXPR auto data() FMT_NOEXCEPT -> T* { return ptr_; } + + /** Returns a pointer to the buffer data. */ + FMT_CONSTEXPR auto data() const FMT_NOEXCEPT -> const T* { return ptr_; } + + /** Clears this buffer. */ + void clear() { size_ = 0; } + + // Tries resizing the buffer to contain *count* elements. If T is a POD type + // the new elements may not be initialized. + FMT_CONSTEXPR20 void try_resize(size_t count) { + try_reserve(count); + size_ = count <= capacity_ ? count : capacity_; + } + + // Tries increasing the buffer capacity to *new_capacity*. It can increase the + // capacity by a smaller amount than requested but guarantees there is space + // for at least one additional element either by increasing the capacity or by + // flushing the buffer if it is full. + FMT_CONSTEXPR20 void try_reserve(size_t new_capacity) { + if (new_capacity > capacity_) grow(new_capacity); + } + + FMT_CONSTEXPR20 void push_back(const T& value) { + try_reserve(size_ + 1); + ptr_[size_++] = value; + } + + /** Appends data to the end of the buffer. */ + template <typename U> void append(const U* begin, const U* end); + + template <typename I> FMT_CONSTEXPR auto operator[](I index) -> T& { + return ptr_[index]; + } + template <typename I> + FMT_CONSTEXPR auto operator[](I index) const -> const T& { + return ptr_[index]; + } +}; + +struct buffer_traits { + explicit buffer_traits(size_t) {} + auto count() const -> size_t { return 0; } + auto limit(size_t size) -> size_t { return size; } +}; + +class fixed_buffer_traits { + private: + size_t count_ = 0; + size_t limit_; + + public: + explicit fixed_buffer_traits(size_t limit) : limit_(limit) {} + auto count() const -> size_t { return count_; } + auto limit(size_t size) -> size_t { + size_t n = limit_ > count_ ? limit_ - count_ : 0; + count_ += size; + return size < n ? size : n; + } +}; + +// A buffer that writes to an output iterator when flushed. +template <typename OutputIt, typename T, typename Traits = buffer_traits> +class iterator_buffer final : public Traits, public buffer<T> { + private: + OutputIt out_; + enum { buffer_size = 256 }; + T data_[buffer_size]; + + protected: + FMT_CONSTEXPR20 void grow(size_t) override { + if (this->size() == buffer_size) flush(); + } + + void flush() { + auto size = this->size(); + this->clear(); + out_ = copy_str<T>(data_, data_ + this->limit(size), out_); + } + + public: + explicit iterator_buffer(OutputIt out, size_t n = buffer_size) + : Traits(n), buffer<T>(data_, 0, buffer_size), out_(out) {} + iterator_buffer(iterator_buffer&& other) + : Traits(other), buffer<T>(data_, 0, buffer_size), out_(other.out_) {} + ~iterator_buffer() { flush(); } + + auto out() -> OutputIt { + flush(); + return out_; + } + auto count() const -> size_t { return Traits::count() + this->size(); } +}; + +template <typename T> +class iterator_buffer<T*, T, fixed_buffer_traits> final + : public fixed_buffer_traits, + public buffer<T> { + private: + T* out_; + enum { buffer_size = 256 }; + T data_[buffer_size]; + + protected: + FMT_CONSTEXPR20 void grow(size_t) override { + if (this->size() == this->capacity()) flush(); + } + + void flush() { + size_t n = this->limit(this->size()); + if (this->data() == out_) { + out_ += n; + this->set(data_, buffer_size); + } + this->clear(); + } + + public: + explicit iterator_buffer(T* out, size_t n = buffer_size) + : fixed_buffer_traits(n), buffer<T>(out, 0, n), out_(out) {} + iterator_buffer(iterator_buffer&& other) + : fixed_buffer_traits(other), + buffer<T>(std::move(other)), + out_(other.out_) { + if (this->data() != out_) { + this->set(data_, buffer_size); + this->clear(); + } + } + ~iterator_buffer() { flush(); } + + auto out() -> T* { + flush(); + return out_; + } + auto count() const -> size_t { + return fixed_buffer_traits::count() + this->size(); + } +}; + +template <typename T> class iterator_buffer<T*, T> final : public buffer<T> { + protected: + FMT_CONSTEXPR20 void grow(size_t) override {} + + public: + explicit iterator_buffer(T* out, size_t = 0) : buffer<T>(out, 0, ~size_t()) {} + + auto out() -> T* { return &*this->end(); } +}; + +// A buffer that writes to a container with the contiguous storage. +template <typename Container> +class iterator_buffer<std::back_insert_iterator<Container>, + enable_if_t<is_contiguous<Container>::value, + typename Container::value_type>> + final : public buffer<typename Container::value_type> { + private: + Container& container_; + + protected: + FMT_CONSTEXPR20 void grow(size_t capacity) override { + container_.resize(capacity); + this->set(&container_[0], capacity); + } + + public: + explicit iterator_buffer(Container& c) + : buffer<typename Container::value_type>(c.size()), container_(c) {} + explicit iterator_buffer(std::back_insert_iterator<Container> out, size_t = 0) + : iterator_buffer(get_container(out)) {} + auto out() -> std::back_insert_iterator<Container> { + return std::back_inserter(container_); + } +}; + +// A buffer that counts the number of code units written discarding the output. +template <typename T = char> class counting_buffer final : public buffer<T> { + private: + enum { buffer_size = 256 }; + T data_[buffer_size]; + size_t count_ = 0; + + protected: + FMT_CONSTEXPR20 void grow(size_t) override { + if (this->size() != buffer_size) return; + count_ += this->size(); + this->clear(); + } + + public: + counting_buffer() : buffer<T>(data_, 0, buffer_size) {} + + auto count() -> size_t { return count_ + this->size(); } +}; + +template <typename T> +using buffer_appender = conditional_t<std::is_same<T, char>::value, appender, + std::back_insert_iterator<buffer<T>>>; + +// Maps an output iterator to a buffer. +template <typename T, typename OutputIt> +auto get_buffer(OutputIt out) -> iterator_buffer<OutputIt, T> { + return iterator_buffer<OutputIt, T>(out); +} + +template <typename Buffer> +auto get_iterator(Buffer& buf) -> decltype(buf.out()) { + return buf.out(); +} +template <typename T> auto get_iterator(buffer<T>& buf) -> buffer_appender<T> { + return buffer_appender<T>(buf); +} + +template <typename T, typename Char = char, typename Enable = void> +struct fallback_formatter { + fallback_formatter() = delete; +}; + +// Specifies if T has an enabled fallback_formatter specialization. +template <typename T, typename Char> +using has_fallback_formatter = + std::is_constructible<fallback_formatter<T, Char>>; + +struct view {}; + +template <typename Char, typename T> struct named_arg : view { + const Char* name; + const T& value; + named_arg(const Char* n, const T& v) : name(n), value(v) {} +}; + +template <typename Char> struct named_arg_info { + const Char* name; + int id; +}; + +template <typename T, typename Char, size_t NUM_ARGS, size_t NUM_NAMED_ARGS> +struct arg_data { + // args_[0].named_args points to named_args_ to avoid bloating format_args. + // +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning. + T args_[1 + (NUM_ARGS != 0 ? NUM_ARGS : +1)]; + named_arg_info<Char> named_args_[NUM_NAMED_ARGS]; + + template <typename... U> + arg_data(const U&... init) : args_{T(named_args_, NUM_NAMED_ARGS), init...} {} + arg_data(const arg_data& other) = delete; + auto args() const -> const T* { return args_ + 1; } + auto named_args() -> named_arg_info<Char>* { return named_args_; } +}; + +template <typename T, typename Char, size_t NUM_ARGS> +struct arg_data<T, Char, NUM_ARGS, 0> { + // +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning. + T args_[NUM_ARGS != 0 ? NUM_ARGS : +1]; + + template <typename... U> + FMT_CONSTEXPR FMT_INLINE arg_data(const U&... init) : args_{init...} {} + FMT_CONSTEXPR FMT_INLINE auto args() const -> const T* { return args_; } + FMT_CONSTEXPR FMT_INLINE auto named_args() -> std::nullptr_t { + return nullptr; + } +}; + +template <typename Char> +inline void init_named_args(named_arg_info<Char>*, int, int) {} + +template <typename T> struct is_named_arg : std::false_type {}; +template <typename T> struct is_statically_named_arg : std::false_type {}; + +template <typename T, typename Char> +struct is_named_arg<named_arg<Char, T>> : std::true_type {}; + +template <typename Char, typename T, typename... Tail, + FMT_ENABLE_IF(!is_named_arg<T>::value)> +void init_named_args(named_arg_info<Char>* named_args, int arg_count, + int named_arg_count, const T&, const Tail&... args) { + init_named_args(named_args, arg_count + 1, named_arg_count, args...); +} + +template <typename Char, typename T, typename... Tail, + FMT_ENABLE_IF(is_named_arg<T>::value)> +void init_named_args(named_arg_info<Char>* named_args, int arg_count, + int named_arg_count, const T& arg, const Tail&... args) { + named_args[named_arg_count++] = {arg.name, arg_count}; + init_named_args(named_args, arg_count + 1, named_arg_count, args...); +} + +template <typename... Args> +FMT_CONSTEXPR FMT_INLINE void init_named_args(std::nullptr_t, int, int, + const Args&...) {} + +template <bool B = false> constexpr auto count() -> size_t { return B ? 1 : 0; } +template <bool B1, bool B2, bool... Tail> constexpr auto count() -> size_t { + return (B1 ? 1 : 0) + count<B2, Tail...>(); +} + +template <typename... Args> constexpr auto count_named_args() -> size_t { + return count<is_named_arg<Args>::value...>(); +} + +template <typename... Args> +constexpr auto count_statically_named_args() -> size_t { + return count<is_statically_named_arg<Args>::value...>(); +} + +enum class type { + none_type, + // Integer types should go first, + int_type, + uint_type, + long_long_type, + ulong_long_type, + int128_type, + uint128_type, + bool_type, + char_type, + last_integer_type = char_type, + // followed by floating-point types. + float_type, + double_type, + long_double_type, + last_numeric_type = long_double_type, + cstring_type, + string_type, + pointer_type, + custom_type +}; + +// Maps core type T to the corresponding type enum constant. +template <typename T, typename Char> +struct type_constant : std::integral_constant<type, type::custom_type> {}; + +#define FMT_TYPE_CONSTANT(Type, constant) \ + template <typename Char> \ + struct type_constant<Type, Char> \ + : std::integral_constant<type, type::constant> {} + +FMT_TYPE_CONSTANT(int, int_type); +FMT_TYPE_CONSTANT(unsigned, uint_type); +FMT_TYPE_CONSTANT(long long, long_long_type); +FMT_TYPE_CONSTANT(unsigned long long, ulong_long_type); +FMT_TYPE_CONSTANT(int128_t, int128_type); +FMT_TYPE_CONSTANT(uint128_t, uint128_type); +FMT_TYPE_CONSTANT(bool, bool_type); +FMT_TYPE_CONSTANT(Char, char_type); +FMT_TYPE_CONSTANT(float, float_type); +FMT_TYPE_CONSTANT(double, double_type); +FMT_TYPE_CONSTANT(long double, long_double_type); +FMT_TYPE_CONSTANT(const Char*, cstring_type); +FMT_TYPE_CONSTANT(basic_string_view<Char>, string_type); +FMT_TYPE_CONSTANT(const void*, pointer_type); + +constexpr bool is_integral_type(type t) { + return t > type::none_type && t <= type::last_integer_type; +} + +constexpr bool is_arithmetic_type(type t) { + return t > type::none_type && t <= type::last_numeric_type; +} + +struct unformattable {}; +struct unformattable_char : unformattable {}; +struct unformattable_const : unformattable {}; +struct unformattable_pointer : unformattable {}; + +template <typename Char> struct string_value { + const Char* data; + size_t size; +}; + +template <typename Char> struct named_arg_value { + const named_arg_info<Char>* data; + size_t size; +}; + +template <typename Context> struct custom_value { + using parse_context = typename Context::parse_context_type; + void* value; + void (*format)(void* arg, parse_context& parse_ctx, Context& ctx); +}; + +// A formatting argument value. +template <typename Context> class value { + public: + using char_type = typename Context::char_type; + + union { + monostate no_value; + int int_value; + unsigned uint_value; + long long long_long_value; + unsigned long long ulong_long_value; + int128_t int128_value; + uint128_t uint128_value; + bool bool_value; + char_type char_value; + float float_value; + double double_value; + long double long_double_value; + const void* pointer; + string_value<char_type> string; + custom_value<Context> custom; + named_arg_value<char_type> named_args; + }; + + constexpr FMT_INLINE value() : no_value() {} + constexpr FMT_INLINE value(int val) : int_value(val) {} + constexpr FMT_INLINE value(unsigned val) : uint_value(val) {} + constexpr FMT_INLINE value(long long val) : long_long_value(val) {} + constexpr FMT_INLINE value(unsigned long long val) : ulong_long_value(val) {} + FMT_INLINE value(int128_t val) : int128_value(val) {} + FMT_INLINE value(uint128_t val) : uint128_value(val) {} + constexpr FMT_INLINE value(float val) : float_value(val) {} + constexpr FMT_INLINE value(double val) : double_value(val) {} + FMT_INLINE value(long double val) : long_double_value(val) {} + constexpr FMT_INLINE value(bool val) : bool_value(val) {} + constexpr FMT_INLINE value(char_type val) : char_value(val) {} + FMT_CONSTEXPR FMT_INLINE value(const char_type* val) { + string.data = val; + if (is_constant_evaluated()) string.size = {}; + } + FMT_CONSTEXPR FMT_INLINE value(basic_string_view<char_type> val) { + string.data = val.data(); + string.size = val.size(); + } + FMT_INLINE value(const void* val) : pointer(val) {} + FMT_INLINE value(const named_arg_info<char_type>* args, size_t size) + : named_args{args, size} {} + + template <typename T> FMT_CONSTEXPR FMT_INLINE value(T& val) { + using value_type = remove_cvref_t<T>; + custom.value = const_cast<value_type*>(&val); + // Get the formatter type through the context to allow different contexts + // have different extension points, e.g. `formatter<T>` for `format` and + // `printf_formatter<T>` for `printf`. + custom.format = format_custom_arg< + value_type, + conditional_t<has_formatter<value_type, Context>::value, + typename Context::template formatter_type<value_type>, + fallback_formatter<value_type, char_type>>>; + } + value(unformattable); + value(unformattable_char); + value(unformattable_const); + value(unformattable_pointer); + + private: + // Formats an argument of a custom type, such as a user-defined class. + template <typename T, typename Formatter> + static void format_custom_arg(void* arg, + typename Context::parse_context_type& parse_ctx, + Context& ctx) { + auto f = Formatter(); + parse_ctx.advance_to(f.parse(parse_ctx)); + using qualified_type = + conditional_t<has_const_formatter<T, Context>(), const T, T>; + ctx.advance_to(f.format(*static_cast<qualified_type*>(arg), ctx)); + } +}; + +template <typename Context, typename T> +FMT_CONSTEXPR auto make_arg(const T& value) -> basic_format_arg<Context>; + +// To minimize the number of types we need to deal with, long is translated +// either to int or to long long depending on its size. +enum { long_short = sizeof(long) == sizeof(int) }; +using long_type = conditional_t<long_short, int, long long>; +using ulong_type = conditional_t<long_short, unsigned, unsigned long long>; + +// Maps formatting arguments to core types. +// arg_mapper reports errors by returning unformattable instead of using +// static_assert because it's used in the is_formattable trait. +template <typename Context> struct arg_mapper { + using char_type = typename Context::char_type; + + FMT_CONSTEXPR FMT_INLINE auto map(signed char val) -> int { return val; } + FMT_CONSTEXPR FMT_INLINE auto map(unsigned char val) -> unsigned { + return val; + } + FMT_CONSTEXPR FMT_INLINE auto map(short val) -> int { return val; } + FMT_CONSTEXPR FMT_INLINE auto map(unsigned short val) -> unsigned { + return val; + } + FMT_CONSTEXPR FMT_INLINE auto map(int val) -> int { return val; } + FMT_CONSTEXPR FMT_INLINE auto map(unsigned val) -> unsigned { return val; } + FMT_CONSTEXPR FMT_INLINE auto map(long val) -> long_type { return val; } + FMT_CONSTEXPR FMT_INLINE auto map(unsigned long val) -> ulong_type { + return val; + } + FMT_CONSTEXPR FMT_INLINE auto map(long long val) -> long long { return val; } + FMT_CONSTEXPR FMT_INLINE auto map(unsigned long long val) + -> unsigned long long { + return val; + } + FMT_CONSTEXPR FMT_INLINE auto map(int128_t val) -> int128_t { return val; } + FMT_CONSTEXPR FMT_INLINE auto map(uint128_t val) -> uint128_t { return val; } + FMT_CONSTEXPR FMT_INLINE auto map(bool val) -> bool { return val; } + + template <typename T, FMT_ENABLE_IF(std::is_same<T, char>::value || + std::is_same<T, char_type>::value)> + FMT_CONSTEXPR FMT_INLINE auto map(T val) -> char_type { + return val; + } + template <typename T, enable_if_t<(std::is_same<T, wchar_t>::value || +#ifdef __cpp_char8_t + std::is_same<T, char8_t>::value || +#endif + std::is_same<T, char16_t>::value || + std::is_same<T, char32_t>::value) && + !std::is_same<T, char_type>::value, + int> = 0> + FMT_CONSTEXPR FMT_INLINE auto map(T) -> unformattable_char { + return {}; + } + + FMT_CONSTEXPR FMT_INLINE auto map(float val) -> float { return val; } + FMT_CONSTEXPR FMT_INLINE auto map(double val) -> double { return val; } + FMT_CONSTEXPR FMT_INLINE auto map(long double val) -> long double { + return val; + } + + FMT_CONSTEXPR FMT_INLINE auto map(char_type* val) -> const char_type* { + return val; + } + FMT_CONSTEXPR FMT_INLINE auto map(const char_type* val) -> const char_type* { + return val; + } + template <typename T, + FMT_ENABLE_IF(is_string<T>::value && !std::is_pointer<T>::value && + std::is_same<char_type, char_t<T>>::value)> + FMT_CONSTEXPR FMT_INLINE auto map(const T& val) + -> basic_string_view<char_type> { + return to_string_view(val); + } + template <typename T, + FMT_ENABLE_IF(is_string<T>::value && !std::is_pointer<T>::value && + !std::is_same<char_type, char_t<T>>::value)> + FMT_CONSTEXPR FMT_INLINE auto map(const T&) -> unformattable_char { + return {}; + } + template <typename T, + FMT_ENABLE_IF( + std::is_constructible<basic_string_view<char_type>, T>::value && + !is_string<T>::value && !has_formatter<T, Context>::value && + !has_fallback_formatter<T, char_type>::value)> + FMT_CONSTEXPR FMT_INLINE auto map(const T& val) + -> basic_string_view<char_type> { + return basic_string_view<char_type>(val); + } + template < + typename T, + FMT_ENABLE_IF( + std::is_constructible<std_string_view<char_type>, T>::value && + !std::is_constructible<basic_string_view<char_type>, T>::value && + !is_string<T>::value && !has_formatter<T, Context>::value && + !has_fallback_formatter<T, char_type>::value)> + FMT_CONSTEXPR FMT_INLINE auto map(const T& val) + -> basic_string_view<char_type> { + return std_string_view<char_type>(val); + } + + using cstring_result = conditional_t<std::is_same<char_type, char>::value, + const char*, unformattable_pointer>; + + FMT_DEPRECATED FMT_CONSTEXPR FMT_INLINE auto map(const signed char* val) + -> cstring_result { + return map(reinterpret_cast<const char*>(val)); + } + FMT_DEPRECATED FMT_CONSTEXPR FMT_INLINE auto map(const unsigned char* val) + -> cstring_result { + return map(reinterpret_cast<const char*>(val)); + } + FMT_DEPRECATED FMT_CONSTEXPR FMT_INLINE auto map(signed char* val) + -> cstring_result { + return map(reinterpret_cast<const char*>(val)); + } + FMT_DEPRECATED FMT_CONSTEXPR FMT_INLINE auto map(unsigned char* val) + -> cstring_result { + return map(reinterpret_cast<const char*>(val)); + } + + FMT_CONSTEXPR FMT_INLINE auto map(void* val) -> const void* { return val; } + FMT_CONSTEXPR FMT_INLINE auto map(const void* val) -> const void* { + return val; + } + FMT_CONSTEXPR FMT_INLINE auto map(std::nullptr_t val) -> const void* { + return val; + } + + // We use SFINAE instead of a const T* parameter to avoid conflicting with + // the C array overload. + template < + typename T, + FMT_ENABLE_IF( + std::is_member_pointer<T>::value || + std::is_function<typename std::remove_pointer<T>::type>::value || + (std::is_convertible<const T&, const void*>::value && + !std::is_convertible<const T&, const char_type*>::value))> + FMT_CONSTEXPR auto map(const T&) -> unformattable_pointer { + return {}; + } + + template <typename T, std::size_t N, + FMT_ENABLE_IF(!std::is_same<T, wchar_t>::value)> + FMT_CONSTEXPR FMT_INLINE auto map(const T (&values)[N]) -> const T (&)[N] { + return values; + } + + template <typename T, + FMT_ENABLE_IF( + std::is_enum<T>::value&& std::is_convertible<T, int>::value && + !has_formatter<T, Context>::value && + !has_fallback_formatter<T, char_type>::value)> + FMT_CONSTEXPR FMT_INLINE auto map(const T& val) + -> decltype(std::declval<arg_mapper>().map( + static_cast<typename std::underlying_type<T>::type>(val))) { + return map(static_cast<typename std::underlying_type<T>::type>(val)); + } + + FMT_CONSTEXPR FMT_INLINE auto map(detail::byte val) -> unsigned { + return map(static_cast<unsigned char>(val)); + } + + template <typename T, typename U = remove_cvref_t<T>> + struct formattable + : bool_constant<has_const_formatter<U, Context>() || + !std::is_const<remove_reference_t<T>>::value || + has_fallback_formatter<U, char_type>::value> {}; + +#if FMT_MSC_VER != 0 && FMT_MSC_VER < 1910 + // Workaround a bug in MSVC. + template <typename T> FMT_CONSTEXPR FMT_INLINE auto do_map(T&& val) -> T& { + return val; + } +#else + template <typename T, FMT_ENABLE_IF(formattable<T>::value)> + FMT_CONSTEXPR FMT_INLINE auto do_map(T&& val) -> T& { + return val; + } + template <typename T, FMT_ENABLE_IF(!formattable<T>::value)> + FMT_CONSTEXPR FMT_INLINE auto do_map(T&&) -> unformattable_const { + return {}; + } +#endif + + template <typename T, typename U = remove_cvref_t<T>, + FMT_ENABLE_IF(!is_string<U>::value && !is_char<U>::value && + !std::is_array<U>::value && + (has_formatter<U, Context>::value || + has_fallback_formatter<U, char_type>::value))> + FMT_CONSTEXPR FMT_INLINE auto map(T&& val) + -> decltype(this->do_map(std::forward<T>(val))) { + return do_map(std::forward<T>(val)); + } + + template <typename T, FMT_ENABLE_IF(is_named_arg<T>::value)> + FMT_CONSTEXPR FMT_INLINE auto map(const T& named_arg) + -> decltype(std::declval<arg_mapper>().map(named_arg.value)) { + return map(named_arg.value); + } + + auto map(...) -> unformattable { return {}; } +}; + +// A type constant after applying arg_mapper<Context>. +template <typename T, typename Context> +using mapped_type_constant = + type_constant<decltype(arg_mapper<Context>().map(std::declval<const T&>())), + typename Context::char_type>; + +enum { packed_arg_bits = 4 }; +// Maximum number of arguments with packed types. +enum { max_packed_args = 62 / packed_arg_bits }; +enum : unsigned long long { is_unpacked_bit = 1ULL << 63 }; +enum : unsigned long long { has_named_args_bit = 1ULL << 62 }; + +FMT_END_DETAIL_NAMESPACE + +// An output iterator that appends to a buffer. +// It is used to reduce symbol sizes for the common case. +class appender : public std::back_insert_iterator<detail::buffer<char>> { + using base = std::back_insert_iterator<detail::buffer<char>>; + + template <typename T> + friend auto get_buffer(appender out) -> detail::buffer<char>& { + return detail::get_container(out); + } + + public: + using std::back_insert_iterator<detail::buffer<char>>::back_insert_iterator; + appender(base it) FMT_NOEXCEPT : base(it) {} + using _Unchecked_type = appender; // Mark iterator as checked. + + auto operator++() FMT_NOEXCEPT -> appender& { return *this; } + + auto operator++(int) FMT_NOEXCEPT -> appender { return *this; } +}; + +// A formatting argument. It is a trivially copyable/constructible type to +// allow storage in basic_memory_buffer. +template <typename Context> class basic_format_arg { + private: + detail::value<Context> value_; + detail::type type_; + + template <typename ContextType, typename T> + friend FMT_CONSTEXPR auto detail::make_arg(const T& value) + -> basic_format_arg<ContextType>; + + template <typename Visitor, typename Ctx> + friend FMT_CONSTEXPR auto visit_format_arg(Visitor&& vis, + const basic_format_arg<Ctx>& arg) + -> decltype(vis(0)); + + friend class basic_format_args<Context>; + friend class dynamic_format_arg_store<Context>; + + using char_type = typename Context::char_type; + + template <typename T, typename Char, size_t NUM_ARGS, size_t NUM_NAMED_ARGS> + friend struct detail::arg_data; + + basic_format_arg(const detail::named_arg_info<char_type>* args, size_t size) + : value_(args, size) {} + + public: + class handle { + public: + explicit handle(detail::custom_value<Context> custom) : custom_(custom) {} + + void format(typename Context::parse_context_type& parse_ctx, + Context& ctx) const { + custom_.format(custom_.value, parse_ctx, ctx); + } + + private: + detail::custom_value<Context> custom_; + }; + + constexpr basic_format_arg() : type_(detail::type::none_type) {} + + constexpr explicit operator bool() const FMT_NOEXCEPT { + return type_ != detail::type::none_type; + } + + auto type() const -> detail::type { return type_; } + + auto is_integral() const -> bool { return detail::is_integral_type(type_); } + auto is_arithmetic() const -> bool { + return detail::is_arithmetic_type(type_); + } +}; + +/** + \rst + Visits an argument dispatching to the appropriate visit method based on + the argument type. For example, if the argument type is ``double`` then + ``vis(value)`` will be called with the value of type ``double``. + \endrst + */ +template <typename Visitor, typename Context> +FMT_CONSTEXPR FMT_INLINE auto visit_format_arg( + Visitor&& vis, const basic_format_arg<Context>& arg) -> decltype(vis(0)) { + switch (arg.type_) { + case detail::type::none_type: + break; + case detail::type::int_type: + return vis(arg.value_.int_value); + case detail::type::uint_type: + return vis(arg.value_.uint_value); + case detail::type::long_long_type: + return vis(arg.value_.long_long_value); + case detail::type::ulong_long_type: + return vis(arg.value_.ulong_long_value); + case detail::type::int128_type: + return vis(detail::convert_for_visit(arg.value_.int128_value)); + case detail::type::uint128_type: + return vis(detail::convert_for_visit(arg.value_.uint128_value)); + case detail::type::bool_type: + return vis(arg.value_.bool_value); + case detail::type::char_type: + return vis(arg.value_.char_value); + case detail::type::float_type: + return vis(arg.value_.float_value); + case detail::type::double_type: + return vis(arg.value_.double_value); + case detail::type::long_double_type: + return vis(arg.value_.long_double_value); + case detail::type::cstring_type: + return vis(arg.value_.string.data); + case detail::type::string_type: + using sv = basic_string_view<typename Context::char_type>; + return vis(sv(arg.value_.string.data, arg.value_.string.size)); + case detail::type::pointer_type: + return vis(arg.value_.pointer); + case detail::type::custom_type: + return vis(typename basic_format_arg<Context>::handle(arg.value_.custom)); + } + return vis(monostate()); +} + +FMT_BEGIN_DETAIL_NAMESPACE + +template <typename Char, typename InputIt> +auto copy_str(InputIt begin, InputIt end, appender out) -> appender { + get_container(out).append(begin, end); + return out; +} + +#if FMT_GCC_VERSION && FMT_GCC_VERSION < 500 +// A workaround for gcc 4.8 to make void_t work in a SFINAE context. +template <typename... Ts> struct void_t_impl { using type = void; }; +template <typename... Ts> +using void_t = typename detail::void_t_impl<Ts...>::type; +#else +template <typename...> using void_t = void; +#endif + +template <typename It, typename T, typename Enable = void> +struct is_output_iterator : std::false_type {}; + +template <typename It, typename T> +struct is_output_iterator< + It, T, + void_t<typename std::iterator_traits<It>::iterator_category, + decltype(*std::declval<It>() = std::declval<T>())>> + : std::true_type {}; + +template <typename OutputIt> +struct is_back_insert_iterator : std::false_type {}; +template <typename Container> +struct is_back_insert_iterator<std::back_insert_iterator<Container>> + : std::true_type {}; + +template <typename OutputIt> +struct is_contiguous_back_insert_iterator : std::false_type {}; +template <typename Container> +struct is_contiguous_back_insert_iterator<std::back_insert_iterator<Container>> + : is_contiguous<Container> {}; +template <> +struct is_contiguous_back_insert_iterator<appender> : std::true_type {}; + +// A type-erased reference to an std::locale to avoid heavy <locale> include. +class locale_ref { + private: + const void* locale_; // A type-erased pointer to std::locale. + + public: + constexpr locale_ref() : locale_(nullptr) {} + template <typename Locale> explicit locale_ref(const Locale& loc); + + explicit operator bool() const FMT_NOEXCEPT { return locale_ != nullptr; } + + template <typename Locale> auto get() const -> Locale; +}; + +template <typename> constexpr auto encode_types() -> unsigned long long { + return 0; +} + +template <typename Context, typename Arg, typename... Args> +constexpr auto encode_types() -> unsigned long long { + return static_cast<unsigned>(mapped_type_constant<Arg, Context>::value) | + (encode_types<Context, Args...>() << packed_arg_bits); +} + +template <typename Context, typename T> +FMT_CONSTEXPR auto make_arg(const T& value) -> basic_format_arg<Context> { + basic_format_arg<Context> arg; + arg.type_ = mapped_type_constant<T, Context>::value; + arg.value_ = arg_mapper<Context>().map(value); + return arg; +} + +// The type template parameter is there to avoid an ODR violation when using +// a fallback formatter in one translation unit and an implicit conversion in +// another (not recommended). +template <bool IS_PACKED, typename Context, type, typename T, + FMT_ENABLE_IF(IS_PACKED)> +FMT_CONSTEXPR FMT_INLINE auto make_arg(T&& val) -> value<Context> { + const auto& arg = arg_mapper<Context>().map(std::forward<T>(val)); + + constexpr bool formattable_char = + !std::is_same<decltype(arg), const unformattable_char&>::value; + static_assert(formattable_char, "Mixing character types is disallowed."); + + constexpr bool formattable_const = + !std::is_same<decltype(arg), const unformattable_const&>::value; + static_assert(formattable_const, "Cannot format a const argument."); + + // Formatting of arbitrary pointers is disallowed. If you want to output + // a pointer cast it to "void *" or "const void *". In particular, this + // forbids formatting of "[const] volatile char *" which is printed as bool + // by iostreams. + constexpr bool formattable_pointer = + !std::is_same<decltype(arg), const unformattable_pointer&>::value; + static_assert(formattable_pointer, + "Formatting of non-void pointers is disallowed."); + + constexpr bool formattable = + !std::is_same<decltype(arg), const unformattable&>::value; + static_assert( + formattable, + "Cannot format an argument. To make type T formattable provide a " + "formatter<T> specialization: https://fmt.dev/latest/api.html#udt"); + return {arg}; +} + +template <bool IS_PACKED, typename Context, type, typename T, + FMT_ENABLE_IF(!IS_PACKED)> +inline auto make_arg(const T& value) -> basic_format_arg<Context> { + return make_arg<Context>(value); +} +FMT_END_DETAIL_NAMESPACE + +// Formatting context. +template <typename OutputIt, typename Char> class basic_format_context { + public: + /** The character type for the output. */ + using char_type = Char; + + private: + OutputIt out_; + basic_format_args<basic_format_context> args_; + detail::locale_ref loc_; + + public: + using iterator = OutputIt; + using format_arg = basic_format_arg<basic_format_context>; + using parse_context_type = basic_format_parse_context<Char>; + template <typename T> using formatter_type = formatter<T, char_type>; + + basic_format_context(basic_format_context&&) = default; + basic_format_context(const basic_format_context&) = delete; + void operator=(const basic_format_context&) = delete; + /** + Constructs a ``basic_format_context`` object. References to the arguments are + stored in the object so make sure they have appropriate lifetimes. + */ + constexpr basic_format_context( + OutputIt out, basic_format_args<basic_format_context> ctx_args, + detail::locale_ref loc = detail::locale_ref()) + : out_(out), args_(ctx_args), loc_(loc) {} + + constexpr auto arg(int id) const -> format_arg { return args_.get(id); } + FMT_CONSTEXPR auto arg(basic_string_view<char_type> name) -> format_arg { + return args_.get(name); + } + FMT_CONSTEXPR auto arg_id(basic_string_view<char_type> name) -> int { + return args_.get_id(name); + } + auto args() const -> const basic_format_args<basic_format_context>& { + return args_; + } + + FMT_CONSTEXPR auto error_handler() -> detail::error_handler { return {}; } + void on_error(const char* message) { error_handler().on_error(message); } + + // Returns an iterator to the beginning of the output range. + FMT_CONSTEXPR auto out() -> iterator { return out_; } + + // Advances the begin iterator to ``it``. + void advance_to(iterator it) { + if (!detail::is_back_insert_iterator<iterator>()) out_ = it; + } + + FMT_CONSTEXPR auto locale() -> detail::locale_ref { return loc_; } +}; + +template <typename Char> +using buffer_context = + basic_format_context<detail::buffer_appender<Char>, Char>; +using format_context = buffer_context<char>; + +// Workaround an alias issue: https://stackoverflow.com/q/62767544/471164. +#define FMT_BUFFER_CONTEXT(Char) \ + basic_format_context<detail::buffer_appender<Char>, Char> + +template <typename T, typename Char = char> +using is_formattable = bool_constant< + !std::is_base_of<detail::unformattable, + decltype(detail::arg_mapper<buffer_context<Char>>().map( + std::declval<T>()))>::value && + !detail::has_fallback_formatter<T, Char>::value>; + +/** + \rst + An array of references to arguments. It can be implicitly converted into + `~fmt::basic_format_args` for passing into type-erased formatting functions + such as `~fmt::vformat`. + \endrst + */ +template <typename Context, typename... Args> +class format_arg_store +#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409 + // Workaround a GCC template argument substitution bug. + : public basic_format_args<Context> +#endif +{ + private: + static const size_t num_args = sizeof...(Args); + static const size_t num_named_args = detail::count_named_args<Args...>(); + static const bool is_packed = num_args <= detail::max_packed_args; + + using value_type = conditional_t<is_packed, detail::value<Context>, + basic_format_arg<Context>>; + + detail::arg_data<value_type, typename Context::char_type, num_args, + num_named_args> + data_; + + friend class basic_format_args<Context>; + + static constexpr unsigned long long desc = + (is_packed ? detail::encode_types<Context, Args...>() + : detail::is_unpacked_bit | num_args) | + (num_named_args != 0 + ? static_cast<unsigned long long>(detail::has_named_args_bit) + : 0); + + public: + template <typename... T> + FMT_CONSTEXPR FMT_INLINE format_arg_store(T&&... args) + : +#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409 + basic_format_args<Context>(*this), +#endif + data_{detail::make_arg< + is_packed, Context, + detail::mapped_type_constant<remove_cvref_t<T>, Context>::value>( + std::forward<T>(args))...} { + detail::init_named_args(data_.named_args(), 0, 0, args...); + } +}; + +/** + \rst + Constructs a `~fmt::format_arg_store` object that contains references to + arguments and can be implicitly converted to `~fmt::format_args`. `Context` + can be omitted in which case it defaults to `~fmt::context`. + See `~fmt::arg` for lifetime considerations. + \endrst + */ +template <typename Context = format_context, typename... Args> +constexpr auto make_format_args(Args&&... args) + -> format_arg_store<Context, remove_cvref_t<Args>...> { + return {std::forward<Args>(args)...}; +} + +/** + \rst + Returns a named argument to be used in a formatting function. + It should only be used in a call to a formatting function or + `dynamic_format_arg_store::push_back`. + + **Example**:: + + fmt::print("Elapsed time: {s:.2f} seconds", fmt::arg("s", 1.23)); + \endrst + */ +template <typename Char, typename T> +inline auto arg(const Char* name, const T& arg) -> detail::named_arg<Char, T> { + static_assert(!detail::is_named_arg<T>(), "nested named arguments"); + return {name, arg}; +} + +/** + \rst + A view of a collection of formatting arguments. To avoid lifetime issues it + should only be used as a parameter type in type-erased functions such as + ``vformat``:: + + void vlog(string_view format_str, format_args args); // OK + format_args args = make_format_args(42); // Error: dangling reference + \endrst + */ +template <typename Context> class basic_format_args { + public: + using size_type = int; + using format_arg = basic_format_arg<Context>; + + private: + // A descriptor that contains information about formatting arguments. + // If the number of arguments is less or equal to max_packed_args then + // argument types are passed in the descriptor. This reduces binary code size + // per formatting function call. + unsigned long long desc_; + union { + // If is_packed() returns true then argument values are stored in values_; + // otherwise they are stored in args_. This is done to improve cache + // locality and reduce compiled code size since storing larger objects + // may require more code (at least on x86-64) even if the same amount of + // data is actually copied to stack. It saves ~10% on the bloat test. + const detail::value<Context>* values_; + const format_arg* args_; + }; + + constexpr auto is_packed() const -> bool { + return (desc_ & detail::is_unpacked_bit) == 0; + } + auto has_named_args() const -> bool { + return (desc_ & detail::has_named_args_bit) != 0; + } + + FMT_CONSTEXPR auto type(int index) const -> detail::type { + int shift = index * detail::packed_arg_bits; + unsigned int mask = (1 << detail::packed_arg_bits) - 1; + return static_cast<detail::type>((desc_ >> shift) & mask); + } + + constexpr FMT_INLINE basic_format_args(unsigned long long desc, + const detail::value<Context>* values) + : desc_(desc), values_(values) {} + constexpr basic_format_args(unsigned long long desc, const format_arg* args) + : desc_(desc), args_(args) {} + + public: + constexpr basic_format_args() : desc_(0), args_(nullptr) {} + + /** + \rst + Constructs a `basic_format_args` object from `~fmt::format_arg_store`. + \endrst + */ + template <typename... Args> + constexpr FMT_INLINE basic_format_args( + const format_arg_store<Context, Args...>& store) + : basic_format_args(format_arg_store<Context, Args...>::desc, + store.data_.args()) {} + + /** + \rst + Constructs a `basic_format_args` object from + `~fmt::dynamic_format_arg_store`. + \endrst + */ + constexpr FMT_INLINE basic_format_args( + const dynamic_format_arg_store<Context>& store) + : basic_format_args(store.get_types(), store.data()) {} + + /** + \rst + Constructs a `basic_format_args` object from a dynamic set of arguments. + \endrst + */ + constexpr basic_format_args(const format_arg* args, int count) + : basic_format_args(detail::is_unpacked_bit | detail::to_unsigned(count), + args) {} + + /** Returns the argument with the specified id. */ + FMT_CONSTEXPR auto get(int id) const -> format_arg { + format_arg arg; + if (!is_packed()) { + if (id < max_size()) arg = args_[id]; + return arg; + } + if (id >= detail::max_packed_args) return arg; + arg.type_ = type(id); + if (arg.type_ == detail::type::none_type) return arg; + arg.value_ = values_[id]; + return arg; + } + + template <typename Char> + auto get(basic_string_view<Char> name) const -> format_arg { + int id = get_id(name); + return id >= 0 ? get(id) : format_arg(); + } + + template <typename Char> + auto get_id(basic_string_view<Char> name) const -> int { + if (!has_named_args()) return -1; + const auto& named_args = + (is_packed() ? values_[-1] : args_[-1].value_).named_args; + for (size_t i = 0; i < named_args.size; ++i) { + if (named_args.data[i].name == name) return named_args.data[i].id; + } + return -1; + } + + auto max_size() const -> int { + unsigned long long max_packed = detail::max_packed_args; + return static_cast<int>(is_packed() ? max_packed + : desc_ & ~detail::is_unpacked_bit); + } +}; + +/** An alias to ``basic_format_args<format_context>``. */ +// A separate type would result in shorter symbols but break ABI compatibility +// between clang and gcc on ARM (#1919). +using format_args = basic_format_args<format_context>; + +// We cannot use enum classes as bit fields because of a gcc bug +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61414. +namespace align { +enum type { none, left, right, center, numeric }; +} +using align_t = align::type; +namespace sign { +enum type { none, minus, plus, space }; +} +using sign_t = sign::type; + +FMT_BEGIN_DETAIL_NAMESPACE + +// Workaround an array initialization issue in gcc 4.8. +template <typename Char> struct fill_t { + private: + enum { max_size = 4 }; + Char data_[max_size] = {Char(' '), Char(0), Char(0), Char(0)}; + unsigned char size_ = 1; + + public: + FMT_CONSTEXPR void operator=(basic_string_view<Char> s) { + auto size = s.size(); + if (size > max_size) return throw_format_error("invalid fill"); + for (size_t i = 0; i < size; ++i) data_[i] = s[i]; + size_ = static_cast<unsigned char>(size); + } + + constexpr auto size() const -> size_t { return size_; } + constexpr auto data() const -> const Char* { return data_; } + + FMT_CONSTEXPR auto operator[](size_t index) -> Char& { return data_[index]; } + FMT_CONSTEXPR auto operator[](size_t index) const -> const Char& { + return data_[index]; + } +}; +FMT_END_DETAIL_NAMESPACE + +enum class presentation_type : unsigned char { + none, + // Integer types should go first, + dec, // 'd' + oct, // 'o' + hex_lower, // 'x' + hex_upper, // 'X' + bin_lower, // 'b' + bin_upper, // 'B' + hexfloat_lower, // 'a' + hexfloat_upper, // 'A' + exp_lower, // 'e' + exp_upper, // 'E' + fixed_lower, // 'f' + fixed_upper, // 'F' + general_lower, // 'g' + general_upper, // 'G' + chr, // 'c' + string, // 's' + pointer // 'p' +}; + +// Format specifiers for built-in and string types. +template <typename Char> struct basic_format_specs { + int width; + int precision; + presentation_type type; + align_t align : 4; + sign_t sign : 3; + bool alt : 1; // Alternate form ('#'). + bool localized : 1; + detail::fill_t<Char> fill; + + constexpr basic_format_specs() + : width(0), + precision(-1), + type(presentation_type::none), + align(align::none), + sign(sign::none), + alt(false), + localized(false) {} +}; + +using format_specs = basic_format_specs<char>; + +FMT_BEGIN_DETAIL_NAMESPACE + +enum class arg_id_kind { none, index, name }; + +// An argument reference. +template <typename Char> struct arg_ref { + FMT_CONSTEXPR arg_ref() : kind(arg_id_kind::none), val() {} + + FMT_CONSTEXPR explicit arg_ref(int index) + : kind(arg_id_kind::index), val(index) {} + FMT_CONSTEXPR explicit arg_ref(basic_string_view<Char> name) + : kind(arg_id_kind::name), val(name) {} + + FMT_CONSTEXPR auto operator=(int idx) -> arg_ref& { + kind = arg_id_kind::index; + val.index = idx; + return *this; + } + + arg_id_kind kind; + union value { + FMT_CONSTEXPR value(int id = 0) : index{id} {} + FMT_CONSTEXPR value(basic_string_view<Char> n) : name(n) {} + + int index; + basic_string_view<Char> name; + } val; +}; + +// Format specifiers with width and precision resolved at formatting rather +// than parsing time to allow re-using the same parsed specifiers with +// different sets of arguments (precompilation of format strings). +template <typename Char> +struct dynamic_format_specs : basic_format_specs<Char> { + arg_ref<Char> width_ref; + arg_ref<Char> precision_ref; +}; + +struct auto_id {}; + +// A format specifier handler that sets fields in basic_format_specs. +template <typename Char> class specs_setter { + protected: + basic_format_specs<Char>& specs_; + + public: + explicit FMT_CONSTEXPR specs_setter(basic_format_specs<Char>& specs) + : specs_(specs) {} + + FMT_CONSTEXPR specs_setter(const specs_setter& other) + : specs_(other.specs_) {} + + FMT_CONSTEXPR void on_align(align_t align) { specs_.align = align; } + FMT_CONSTEXPR void on_fill(basic_string_view<Char> fill) { + specs_.fill = fill; + } + FMT_CONSTEXPR void on_sign(sign_t s) { specs_.sign = s; } + FMT_CONSTEXPR void on_hash() { specs_.alt = true; } + FMT_CONSTEXPR void on_localized() { specs_.localized = true; } + + FMT_CONSTEXPR void on_zero() { + if (specs_.align == align::none) specs_.align = align::numeric; + specs_.fill[0] = Char('0'); + } + + FMT_CONSTEXPR void on_width(int width) { specs_.width = width; } + FMT_CONSTEXPR void on_precision(int precision) { + specs_.precision = precision; + } + FMT_CONSTEXPR void end_precision() {} + + FMT_CONSTEXPR void on_type(presentation_type type) { specs_.type = type; } +}; + +// Format spec handler that saves references to arguments representing dynamic +// width and precision to be resolved at formatting time. +template <typename ParseContext> +class dynamic_specs_handler + : public specs_setter<typename ParseContext::char_type> { + public: + using char_type = typename ParseContext::char_type; + + FMT_CONSTEXPR dynamic_specs_handler(dynamic_format_specs<char_type>& specs, + ParseContext& ctx) + : specs_setter<char_type>(specs), specs_(specs), context_(ctx) {} + + FMT_CONSTEXPR dynamic_specs_handler(const dynamic_specs_handler& other) + : specs_setter<char_type>(other), + specs_(other.specs_), + context_(other.context_) {} + + template <typename Id> FMT_CONSTEXPR void on_dynamic_width(Id arg_id) { + specs_.width_ref = make_arg_ref(arg_id); + } + + template <typename Id> FMT_CONSTEXPR void on_dynamic_precision(Id arg_id) { + specs_.precision_ref = make_arg_ref(arg_id); + } + + FMT_CONSTEXPR void on_error(const char* message) { + context_.on_error(message); + } + + private: + dynamic_format_specs<char_type>& specs_; + ParseContext& context_; + + using arg_ref_type = arg_ref<char_type>; + + FMT_CONSTEXPR auto make_arg_ref(int arg_id) -> arg_ref_type { + context_.check_arg_id(arg_id); + return arg_ref_type(arg_id); + } + + FMT_CONSTEXPR auto make_arg_ref(auto_id) -> arg_ref_type { + return arg_ref_type(context_.next_arg_id()); + } + + FMT_CONSTEXPR auto make_arg_ref(basic_string_view<char_type> arg_id) + -> arg_ref_type { + context_.check_arg_id(arg_id); + basic_string_view<char_type> format_str( + context_.begin(), to_unsigned(context_.end() - context_.begin())); + return arg_ref_type(arg_id); + } +}; + +template <typename Char> constexpr bool is_ascii_letter(Char c) { + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); +} + +// Converts a character to ASCII. Returns a number > 127 on conversion failure. +template <typename Char, FMT_ENABLE_IF(std::is_integral<Char>::value)> +constexpr auto to_ascii(Char value) -> Char { + return value; +} +template <typename Char, FMT_ENABLE_IF(std::is_enum<Char>::value)> +constexpr auto to_ascii(Char value) -> + typename std::underlying_type<Char>::type { + return value; +} + +template <typename Char> +FMT_CONSTEXPR auto code_point_length(const Char* begin) -> int { + if (const_check(sizeof(Char) != 1)) return 1; + auto lengths = + "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\0\0\0\0\0\0\0\0\2\2\2\2\3\3\4"; + int len = lengths[static_cast<unsigned char>(*begin) >> 3]; + + // Compute the pointer to the next character early so that the next + // iteration can start working on the next character. Neither Clang + // nor GCC figure out this reordering on their own. + return len + !len; +} + +// Return the result via the out param to workaround gcc bug 77539. +template <bool IS_CONSTEXPR, typename T, typename Ptr = const T*> +FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr& out) -> bool { + for (out = first; out != last; ++out) { + if (*out == value) return true; + } + return false; +} + +template <> +inline auto find<false, char>(const char* first, const char* last, char value, + const char*& out) -> bool { + out = static_cast<const char*>( + std::memchr(first, value, to_unsigned(last - first))); + return out != nullptr; +} + +// Parses the range [begin, end) as an unsigned integer. This function assumes +// that the range is non-empty and the first character is a digit. +template <typename Char> +FMT_CONSTEXPR auto parse_nonnegative_int(const Char*& begin, const Char* end, + int error_value) noexcept -> int { + FMT_ASSERT(begin != end && '0' <= *begin && *begin <= '9', ""); + unsigned value = 0, prev = 0; + auto p = begin; + do { + prev = value; + value = value * 10 + unsigned(*p - '0'); + ++p; + } while (p != end && '0' <= *p && *p <= '9'); + auto num_digits = p - begin; + begin = p; + if (num_digits <= std::numeric_limits<int>::digits10) + return static_cast<int>(value); + // Check for overflow. + const unsigned max = to_unsigned((std::numeric_limits<int>::max)()); + return num_digits == std::numeric_limits<int>::digits10 + 1 && + prev * 10ull + unsigned(p[-1] - '0') <= max + ? static_cast<int>(value) + : error_value; +} + +// Parses fill and alignment. +template <typename Char, typename Handler> +FMT_CONSTEXPR auto parse_align(const Char* begin, const Char* end, + Handler&& handler) -> const Char* { + FMT_ASSERT(begin != end, ""); + auto align = align::none; + auto p = begin + code_point_length(begin); + if (p >= end) p = begin; + for (;;) { + switch (to_ascii(*p)) { + case '<': + align = align::left; + break; + case '>': + align = align::right; + break; + case '^': + align = align::center; + break; + default: + break; + } + if (align != align::none) { + if (p != begin) { + auto c = *begin; + if (c == '{') + return handler.on_error("invalid fill character '{'"), begin; + handler.on_fill(basic_string_view<Char>(begin, to_unsigned(p - begin))); + begin = p + 1; + } else + ++begin; + handler.on_align(align); + break; + } else if (p == begin) { + break; + } + p = begin; + } + return begin; +} + +template <typename Char> FMT_CONSTEXPR bool is_name_start(Char c) { + return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || '_' == c; +} + +template <typename Char, typename IDHandler> +FMT_CONSTEXPR auto do_parse_arg_id(const Char* begin, const Char* end, + IDHandler&& handler) -> const Char* { + FMT_ASSERT(begin != end, ""); + Char c = *begin; + if (c >= '0' && c <= '9') { + int index = 0; + if (c != '0') + index = + parse_nonnegative_int(begin, end, (std::numeric_limits<int>::max)()); + else + ++begin; + if (begin == end || (*begin != '}' && *begin != ':')) + handler.on_error("invalid format string"); + else + handler(index); + return begin; + } + if (!is_name_start(c)) { + handler.on_error("invalid format string"); + return begin; + } + auto it = begin; + do { + ++it; + } while (it != end && (is_name_start(c = *it) || ('0' <= c && c <= '9'))); + handler(basic_string_view<Char>(begin, to_unsigned(it - begin))); + return it; +} + +template <typename Char, typename IDHandler> +FMT_CONSTEXPR FMT_INLINE auto parse_arg_id(const Char* begin, const Char* end, + IDHandler&& handler) -> const Char* { + Char c = *begin; + if (c != '}' && c != ':') return do_parse_arg_id(begin, end, handler); + handler(); + return begin; +} + +template <typename Char, typename Handler> +FMT_CONSTEXPR auto parse_width(const Char* begin, const Char* end, + Handler&& handler) -> const Char* { + using detail::auto_id; + struct width_adapter { + Handler& handler; + + FMT_CONSTEXPR void operator()() { handler.on_dynamic_width(auto_id()); } + FMT_CONSTEXPR void operator()(int id) { handler.on_dynamic_width(id); } + FMT_CONSTEXPR void operator()(basic_string_view<Char> id) { + handler.on_dynamic_width(id); + } + FMT_CONSTEXPR void on_error(const char* message) { + if (message) handler.on_error(message); + } + }; + + FMT_ASSERT(begin != end, ""); + if ('0' <= *begin && *begin <= '9') { + int width = parse_nonnegative_int(begin, end, -1); + if (width != -1) + handler.on_width(width); + else + handler.on_error("number is too big"); + } else if (*begin == '{') { + ++begin; + if (begin != end) begin = parse_arg_id(begin, end, width_adapter{handler}); + if (begin == end || *begin != '}') + return handler.on_error("invalid format string"), begin; + ++begin; + } + return begin; +} + +template <typename Char, typename Handler> +FMT_CONSTEXPR auto parse_precision(const Char* begin, const Char* end, + Handler&& handler) -> const Char* { + using detail::auto_id; + struct precision_adapter { + Handler& handler; + + FMT_CONSTEXPR void operator()() { handler.on_dynamic_precision(auto_id()); } + FMT_CONSTEXPR void operator()(int id) { handler.on_dynamic_precision(id); } + FMT_CONSTEXPR void operator()(basic_string_view<Char> id) { + handler.on_dynamic_precision(id); + } + FMT_CONSTEXPR void on_error(const char* message) { + if (message) handler.on_error(message); + } + }; + + ++begin; + auto c = begin != end ? *begin : Char(); + if ('0' <= c && c <= '9') { + auto precision = parse_nonnegative_int(begin, end, -1); + if (precision != -1) + handler.on_precision(precision); + else + handler.on_error("number is too big"); + } else if (c == '{') { + ++begin; + if (begin != end) + begin = parse_arg_id(begin, end, precision_adapter{handler}); + if (begin == end || *begin++ != '}') + return handler.on_error("invalid format string"), begin; + } else { + return handler.on_error("missing precision specifier"), begin; + } + handler.end_precision(); + return begin; +} + +template <typename Char> +FMT_CONSTEXPR auto parse_presentation_type(Char type) -> presentation_type { + switch (to_ascii(type)) { + case 'd': + return presentation_type::dec; + case 'o': + return presentation_type::oct; + case 'x': + return presentation_type::hex_lower; + case 'X': + return presentation_type::hex_upper; + case 'b': + return presentation_type::bin_lower; + case 'B': + return presentation_type::bin_upper; + case 'a': + return presentation_type::hexfloat_lower; + case 'A': + return presentation_type::hexfloat_upper; + case 'e': + return presentation_type::exp_lower; + case 'E': + return presentation_type::exp_upper; + case 'f': + return presentation_type::fixed_lower; + case 'F': + return presentation_type::fixed_upper; + case 'g': + return presentation_type::general_lower; + case 'G': + return presentation_type::general_upper; + case 'c': + return presentation_type::chr; + case 's': + return presentation_type::string; + case 'p': + return presentation_type::pointer; + default: + return presentation_type::none; + } +} + +// Parses standard format specifiers and sends notifications about parsed +// components to handler. +template <typename Char, typename SpecHandler> +FMT_CONSTEXPR FMT_INLINE auto parse_format_specs(const Char* begin, + const Char* end, + SpecHandler&& handler) + -> const Char* { + if (1 < end - begin && begin[1] == '}' && is_ascii_letter(*begin) && + *begin != 'L') { + presentation_type type = parse_presentation_type(*begin++); + if (type == presentation_type::none) + handler.on_error("invalid type specifier"); + handler.on_type(type); + return begin; + } + + if (begin == end) return begin; + + begin = parse_align(begin, end, handler); + if (begin == end) return begin; + + // Parse sign. + switch (to_ascii(*begin)) { + case '+': + handler.on_sign(sign::plus); + ++begin; + break; + case '-': + handler.on_sign(sign::minus); + ++begin; + break; + case ' ': + handler.on_sign(sign::space); + ++begin; + break; + default: + break; + } + if (begin == end) return begin; + + if (*begin == '#') { + handler.on_hash(); + if (++begin == end) return begin; + } + + // Parse zero flag. + if (*begin == '0') { + handler.on_zero(); + if (++begin == end) return begin; + } + + begin = parse_width(begin, end, handler); + if (begin == end) return begin; + + // Parse precision. + if (*begin == '.') { + begin = parse_precision(begin, end, handler); + if (begin == end) return begin; + } + + if (*begin == 'L') { + handler.on_localized(); + ++begin; + } + + // Parse type. + if (begin != end && *begin != '}') { + presentation_type type = parse_presentation_type(*begin++); + if (type == presentation_type::none) + handler.on_error("invalid type specifier"); + handler.on_type(type); + } + return begin; +} + +template <typename Char, typename Handler> +FMT_CONSTEXPR auto parse_replacement_field(const Char* begin, const Char* end, + Handler&& handler) -> const Char* { + struct id_adapter { + Handler& handler; + int arg_id; + + FMT_CONSTEXPR void operator()() { arg_id = handler.on_arg_id(); } + FMT_CONSTEXPR void operator()(int id) { arg_id = handler.on_arg_id(id); } + FMT_CONSTEXPR void operator()(basic_string_view<Char> id) { + arg_id = handler.on_arg_id(id); + } + FMT_CONSTEXPR void on_error(const char* message) { + if (message) handler.on_error(message); + } + }; + + ++begin; + if (begin == end) return handler.on_error("invalid format string"), end; + if (*begin == '}') { + handler.on_replacement_field(handler.on_arg_id(), begin); + } else if (*begin == '{') { + handler.on_text(begin, begin + 1); + } else { + auto adapter = id_adapter{handler, 0}; + begin = parse_arg_id(begin, end, adapter); + Char c = begin != end ? *begin : Char(); + if (c == '}') { + handler.on_replacement_field(adapter.arg_id, begin); + } else if (c == ':') { + begin = handler.on_format_specs(adapter.arg_id, begin + 1, end); + if (begin == end || *begin != '}') + return handler.on_error("unknown format specifier"), end; + } else { + return handler.on_error("missing '}' in format string"), end; + } + } + return begin + 1; +} + +template <bool IS_CONSTEXPR, typename Char, typename Handler> +FMT_CONSTEXPR FMT_INLINE void parse_format_string( + basic_string_view<Char> format_str, Handler&& handler) { + // Workaround a name-lookup bug in MSVC's modules implementation. + using detail::find; + + auto begin = format_str.data(); + auto end = begin + format_str.size(); + if (end - begin < 32) { + // Use a simple loop instead of memchr for small strings. + const Char* p = begin; + while (p != end) { + auto c = *p++; + if (c == '{') { + handler.on_text(begin, p - 1); + begin = p = parse_replacement_field(p - 1, end, handler); + } else if (c == '}') { + if (p == end || *p != '}') + return handler.on_error("unmatched '}' in format string"); + handler.on_text(begin, p); + begin = ++p; + } + } + handler.on_text(begin, end); + return; + } + struct writer { + FMT_CONSTEXPR void operator()(const Char* pbegin, const Char* pend) { + if (pbegin == pend) return; + for (;;) { + const Char* p = nullptr; + if (!find<IS_CONSTEXPR>(pbegin, pend, Char('}'), p)) + return handler_.on_text(pbegin, pend); + ++p; + if (p == pend || *p != '}') + return handler_.on_error("unmatched '}' in format string"); + handler_.on_text(pbegin, p); + pbegin = p + 1; + } + } + Handler& handler_; + } write{handler}; + while (begin != end) { + // Doing two passes with memchr (one for '{' and another for '}') is up to + // 2.5x faster than the naive one-pass implementation on big format strings. + const Char* p = begin; + if (*begin != '{' && !find<IS_CONSTEXPR>(begin + 1, end, Char('{'), p)) + return write(begin, end); + write(begin, p); + begin = parse_replacement_field(p, end, handler); + } +} + +template <typename T, typename ParseContext> +FMT_CONSTEXPR auto parse_format_specs(ParseContext& ctx) + -> decltype(ctx.begin()) { + using char_type = typename ParseContext::char_type; + using context = buffer_context<char_type>; + using mapped_type = conditional_t< + mapped_type_constant<T, context>::value != type::custom_type, + decltype(arg_mapper<context>().map(std::declval<const T&>())), T>; + auto f = conditional_t<has_formatter<mapped_type, context>::value, + formatter<mapped_type, char_type>, + fallback_formatter<T, char_type>>(); + return f.parse(ctx); +} + +// A parse context with extra argument id checks. It is only used at compile +// time because adding checks at runtime would introduce substantial overhead +// and would be redundant since argument ids are checked when arguments are +// retrieved anyway. +template <typename Char, typename ErrorHandler = error_handler> +class compile_parse_context + : public basic_format_parse_context<Char, ErrorHandler> { + private: + int num_args_; + using base = basic_format_parse_context<Char, ErrorHandler>; + + public: + explicit FMT_CONSTEXPR compile_parse_context( + basic_string_view<Char> format_str, + int num_args = (std::numeric_limits<int>::max)(), ErrorHandler eh = {}) + : base(format_str, eh), num_args_(num_args) {} + + FMT_CONSTEXPR auto next_arg_id() -> int { + int id = base::next_arg_id(); + if (id >= num_args_) this->on_error("argument not found"); + return id; + } + + FMT_CONSTEXPR void check_arg_id(int id) { + base::check_arg_id(id); + if (id >= num_args_) this->on_error("argument not found"); + } + using base::check_arg_id; +}; + +template <typename ErrorHandler> +FMT_CONSTEXPR void check_int_type_spec(presentation_type type, + ErrorHandler&& eh) { + if (type > presentation_type::bin_upper && type != presentation_type::chr) + eh.on_error("invalid type specifier"); +} + +// Checks char specs and returns true if the type spec is char (and not int). +template <typename Char, typename ErrorHandler = error_handler> +FMT_CONSTEXPR auto check_char_specs(const basic_format_specs<Char>& specs, + ErrorHandler&& eh = {}) -> bool { + if (specs.type != presentation_type::none && + specs.type != presentation_type::chr) { + check_int_type_spec(specs.type, eh); + return false; + } + if (specs.align == align::numeric || specs.sign != sign::none || specs.alt) + eh.on_error("invalid format specifier for char"); + return true; +} + +// A floating-point presentation format. +enum class float_format : unsigned char { + general, // General: exponent notation or fixed point based on magnitude. + exp, // Exponent notation with the default precision of 6, e.g. 1.2e-3. + fixed, // Fixed point with the default precision of 6, e.g. 0.0012. + hex +}; + +struct float_specs { + int precision; + float_format format : 8; + sign_t sign : 8; + bool upper : 1; + bool locale : 1; + bool binary32 : 1; + bool fallback : 1; + bool showpoint : 1; +}; + +template <typename ErrorHandler = error_handler, typename Char> +FMT_CONSTEXPR auto parse_float_type_spec(const basic_format_specs<Char>& specs, + ErrorHandler&& eh = {}) + -> float_specs { + auto result = float_specs(); + result.showpoint = specs.alt; + result.locale = specs.localized; + switch (specs.type) { + case presentation_type::none: + result.format = float_format::general; + break; + case presentation_type::general_upper: + result.upper = true; + FMT_FALLTHROUGH; + case presentation_type::general_lower: + result.format = float_format::general; + break; + case presentation_type::exp_upper: + result.upper = true; + FMT_FALLTHROUGH; + case presentation_type::exp_lower: + result.format = float_format::exp; + result.showpoint |= specs.precision != 0; + break; + case presentation_type::fixed_upper: + result.upper = true; + FMT_FALLTHROUGH; + case presentation_type::fixed_lower: + result.format = float_format::fixed; + result.showpoint |= specs.precision != 0; + break; + case presentation_type::hexfloat_upper: + result.upper = true; + FMT_FALLTHROUGH; + case presentation_type::hexfloat_lower: + result.format = float_format::hex; + break; + default: + eh.on_error("invalid type specifier"); + break; + } + return result; +} + +template <typename ErrorHandler = error_handler> +FMT_CONSTEXPR auto check_cstring_type_spec(presentation_type type, + ErrorHandler&& eh = {}) -> bool { + if (type == presentation_type::none || type == presentation_type::string) + return true; + if (type != presentation_type::pointer) eh.on_error("invalid type specifier"); + return false; +} + +template <typename ErrorHandler = error_handler> +FMT_CONSTEXPR void check_string_type_spec(presentation_type type, + ErrorHandler&& eh = {}) { + if (type != presentation_type::none && type != presentation_type::string) + eh.on_error("invalid type specifier"); +} + +template <typename ErrorHandler> +FMT_CONSTEXPR void check_pointer_type_spec(presentation_type type, + ErrorHandler&& eh) { + if (type != presentation_type::none && type != presentation_type::pointer) + eh.on_error("invalid type specifier"); +} + +// A parse_format_specs handler that checks if specifiers are consistent with +// the argument type. +template <typename Handler> class specs_checker : public Handler { + private: + detail::type arg_type_; + + FMT_CONSTEXPR void require_numeric_argument() { + if (!is_arithmetic_type(arg_type_)) + this->on_error("format specifier requires numeric argument"); + } + + public: + FMT_CONSTEXPR specs_checker(const Handler& handler, detail::type arg_type) + : Handler(handler), arg_type_(arg_type) {} + + FMT_CONSTEXPR void on_align(align_t align) { + if (align == align::numeric) require_numeric_argument(); + Handler::on_align(align); + } + + FMT_CONSTEXPR void on_sign(sign_t s) { + require_numeric_argument(); + if (is_integral_type(arg_type_) && arg_type_ != type::int_type && + arg_type_ != type::long_long_type && arg_type_ != type::char_type) { + this->on_error("format specifier requires signed argument"); + } + Handler::on_sign(s); + } + + FMT_CONSTEXPR void on_hash() { + require_numeric_argument(); + Handler::on_hash(); + } + + FMT_CONSTEXPR void on_localized() { + require_numeric_argument(); + Handler::on_localized(); + } + + FMT_CONSTEXPR void on_zero() { + require_numeric_argument(); + Handler::on_zero(); + } + + FMT_CONSTEXPR void end_precision() { + if (is_integral_type(arg_type_) || arg_type_ == type::pointer_type) + this->on_error("precision not allowed for this argument type"); + } +}; + +constexpr int invalid_arg_index = -1; + +#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS +template <int N, typename T, typename... Args, typename Char> +constexpr auto get_arg_index_by_name(basic_string_view<Char> name) -> int { + if constexpr (detail::is_statically_named_arg<T>()) { + if (name == T::name) return N; + } + if constexpr (sizeof...(Args) > 0) + return get_arg_index_by_name<N + 1, Args...>(name); + (void)name; // Workaround an MSVC bug about "unused" parameter. + return invalid_arg_index; +} +#endif + +template <typename... Args, typename Char> +FMT_CONSTEXPR auto get_arg_index_by_name(basic_string_view<Char> name) -> int { +#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS + if constexpr (sizeof...(Args) > 0) + return get_arg_index_by_name<0, Args...>(name); +#endif + (void)name; + return invalid_arg_index; +} + +template <typename Char, typename ErrorHandler, typename... Args> +class format_string_checker { + private: + using parse_context_type = compile_parse_context<Char, ErrorHandler>; + enum { num_args = sizeof...(Args) }; + + // Format specifier parsing function. + using parse_func = const Char* (*)(parse_context_type&); + + parse_context_type context_; + parse_func parse_funcs_[num_args > 0 ? num_args : 1]; + + public: + explicit FMT_CONSTEXPR format_string_checker( + basic_string_view<Char> format_str, ErrorHandler eh) + : context_(format_str, num_args, eh), + parse_funcs_{&parse_format_specs<Args, parse_context_type>...} {} + + FMT_CONSTEXPR void on_text(const Char*, const Char*) {} + + FMT_CONSTEXPR auto on_arg_id() -> int { return context_.next_arg_id(); } + FMT_CONSTEXPR auto on_arg_id(int id) -> int { + return context_.check_arg_id(id), id; + } + FMT_CONSTEXPR auto on_arg_id(basic_string_view<Char> id) -> int { +#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS + auto index = get_arg_index_by_name<Args...>(id); + if (index == invalid_arg_index) on_error("named argument is not found"); + return context_.check_arg_id(index), index; +#else + (void)id; + on_error("compile-time checks for named arguments require C++20 support"); + return 0; +#endif + } + + FMT_CONSTEXPR void on_replacement_field(int, const Char*) {} + + FMT_CONSTEXPR auto on_format_specs(int id, const Char* begin, const Char*) + -> const Char* { + context_.advance_to(context_.begin() + (begin - &*context_.begin())); + // id >= 0 check is a workaround for gcc 10 bug (#2065). + return id >= 0 && id < num_args ? parse_funcs_[id](context_) : begin; + } + + FMT_CONSTEXPR void on_error(const char* message) { + context_.on_error(message); + } +}; + +template <typename... Args, typename S, + enable_if_t<(is_compile_string<S>::value), int>> +void check_format_string(S format_str) { + FMT_CONSTEXPR auto s = to_string_view(format_str); + using checker = format_string_checker<typename S::char_type, error_handler, + remove_cvref_t<Args>...>; + FMT_CONSTEXPR bool invalid_format = + (parse_format_string<true>(s, checker(s, {})), true); + ignore_unused(invalid_format); +} + +template <typename Char> +void vformat_to( + buffer<Char>& buf, basic_string_view<Char> fmt, + basic_format_args<FMT_BUFFER_CONTEXT(type_identity_t<Char>)> args, + locale_ref loc = {}); + +FMT_API void vprint_mojibake(std::FILE*, string_view, format_args); +#ifndef _WIN32 +inline void vprint_mojibake(std::FILE*, string_view, format_args) {} +#endif +FMT_END_DETAIL_NAMESPACE + +// A formatter specialization for the core types corresponding to detail::type +// constants. +template <typename T, typename Char> +struct formatter<T, Char, + enable_if_t<detail::type_constant<T, Char>::value != + detail::type::custom_type>> { + private: + detail::dynamic_format_specs<Char> specs_; + + public: + // Parses format specifiers stopping either at the end of the range or at the + // terminating '}'. + template <typename ParseContext> + FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { + auto begin = ctx.begin(), end = ctx.end(); + if (begin == end) return begin; + using handler_type = detail::dynamic_specs_handler<ParseContext>; + auto type = detail::type_constant<T, Char>::value; + auto checker = + detail::specs_checker<handler_type>(handler_type(specs_, ctx), type); + auto it = detail::parse_format_specs(begin, end, checker); + auto eh = ctx.error_handler(); + switch (type) { + case detail::type::none_type: + FMT_ASSERT(false, "invalid argument type"); + break; + case detail::type::bool_type: + if (specs_.type == presentation_type::none || + specs_.type == presentation_type::string) { + break; + } + FMT_FALLTHROUGH; + case detail::type::int_type: + case detail::type::uint_type: + case detail::type::long_long_type: + case detail::type::ulong_long_type: + case detail::type::int128_type: + case detail::type::uint128_type: + detail::check_int_type_spec(specs_.type, eh); + break; + case detail::type::char_type: + detail::check_char_specs(specs_, eh); + break; + case detail::type::float_type: + if (detail::const_check(FMT_USE_FLOAT)) + detail::parse_float_type_spec(specs_, eh); + else + FMT_ASSERT(false, "float support disabled"); + break; + case detail::type::double_type: + if (detail::const_check(FMT_USE_DOUBLE)) + detail::parse_float_type_spec(specs_, eh); + else + FMT_ASSERT(false, "double support disabled"); + break; + case detail::type::long_double_type: + if (detail::const_check(FMT_USE_LONG_DOUBLE)) + detail::parse_float_type_spec(specs_, eh); + else + FMT_ASSERT(false, "long double support disabled"); + break; + case detail::type::cstring_type: + detail::check_cstring_type_spec(specs_.type, eh); + break; + case detail::type::string_type: + detail::check_string_type_spec(specs_.type, eh); + break; + case detail::type::pointer_type: + detail::check_pointer_type_spec(specs_.type, eh); + break; + case detail::type::custom_type: + // Custom format specifiers are checked in parse functions of + // formatter specializations. + break; + } + return it; + } + + template <typename FormatContext> + FMT_CONSTEXPR auto format(const T& val, FormatContext& ctx) const + -> decltype(ctx.out()); +}; + +template <typename Char> struct basic_runtime { basic_string_view<Char> str; }; + +/** A compile-time format string. */ +template <typename Char, typename... Args> class basic_format_string { + private: + basic_string_view<Char> str_; + + public: + template <typename S, + FMT_ENABLE_IF( + std::is_convertible<const S&, basic_string_view<Char>>::value)> + FMT_CONSTEVAL FMT_INLINE basic_format_string(const S& s) : str_(s) { + static_assert( + detail::count< + (std::is_base_of<detail::view, remove_reference_t<Args>>::value && + std::is_reference<Args>::value)...>() == 0, + "passing views as lvalues is disallowed"); +#ifdef FMT_HAS_CONSTEVAL + if constexpr (detail::count_named_args<Args...>() == + detail::count_statically_named_args<Args...>()) { + using checker = detail::format_string_checker<Char, detail::error_handler, + remove_cvref_t<Args>...>; + detail::parse_format_string<true>(str_, checker(s, {})); + } +#else + detail::check_format_string<Args...>(s); +#endif + } + basic_format_string(basic_runtime<Char> r) : str_(r.str) {} + + FMT_INLINE operator basic_string_view<Char>() const { return str_; } +}; + +#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409 +// Workaround broken conversion on older gcc. +template <typename... Args> using format_string = string_view; +template <typename S> auto runtime(const S& s) -> basic_string_view<char_t<S>> { + return s; +} +#else +template <typename... Args> +using format_string = basic_format_string<char, type_identity_t<Args>...>; +/** + \rst + Creates a runtime format string. + + **Example**:: + + // Check format string at runtime instead of compile-time. + fmt::print(fmt::runtime("{:d}"), "I am not a number"); + \endrst + */ +template <typename S> auto runtime(const S& s) -> basic_runtime<char_t<S>> { + return {{s}}; +} +#endif + +FMT_API auto vformat(string_view fmt, format_args args) -> std::string; + +/** + \rst + Formats ``args`` according to specifications in ``fmt`` and returns the result + as a string. + + **Example**:: + + #include <fmt/core.h> + std::string message = fmt::format("The answer is {}.", 42); + \endrst +*/ +template <typename... T> +FMT_NODISCARD FMT_INLINE auto format(format_string<T...> fmt, T&&... args) + -> std::string { + return vformat(fmt, fmt::make_format_args(args...)); +} + +/** Formats a string and writes the output to ``out``. */ +template <typename OutputIt, + FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)> +auto vformat_to(OutputIt out, string_view fmt, format_args args) -> OutputIt { + using detail::get_buffer; + auto&& buf = get_buffer<char>(out); + detail::vformat_to(buf, fmt, args, {}); + return detail::get_iterator(buf); +} + +/** + \rst + Formats ``args`` according to specifications in ``fmt``, writes the result to + the output iterator ``out`` and returns the iterator past the end of the output + range. `format_to` does not append a terminating null character. + + **Example**:: + + auto out = std::vector<char>(); + fmt::format_to(std::back_inserter(out), "{}", 42); + \endrst + */ +template <typename OutputIt, typename... T, + FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)> +FMT_INLINE auto format_to(OutputIt out, format_string<T...> fmt, T&&... args) + -> OutputIt { + return vformat_to(out, fmt, fmt::make_format_args(args...)); +} + +template <typename OutputIt> struct format_to_n_result { + /** Iterator past the end of the output range. */ + OutputIt out; + /** Total (not truncated) output size. */ + size_t size; +}; + +template <typename OutputIt, typename... T, + FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)> +auto vformat_to_n(OutputIt out, size_t n, string_view fmt, format_args args) + -> format_to_n_result<OutputIt> { + using traits = detail::fixed_buffer_traits; + auto buf = detail::iterator_buffer<OutputIt, char, traits>(out, n); + detail::vformat_to(buf, fmt, args, {}); + return {buf.out(), buf.count()}; +} + +/** + \rst + Formats ``args`` according to specifications in ``fmt``, writes up to ``n`` + characters of the result to the output iterator ``out`` and returns the total + (not truncated) output size and the iterator past the end of the output range. + `format_to_n` does not append a terminating null character. + \endrst + */ +template <typename OutputIt, typename... T, + FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)> +FMT_INLINE auto format_to_n(OutputIt out, size_t n, format_string<T...> fmt, + T&&... args) -> format_to_n_result<OutputIt> { + return vformat_to_n(out, n, fmt, fmt::make_format_args(args...)); +} + +/** Returns the number of chars in the output of ``format(fmt, args...)``. */ +template <typename... T> +FMT_NODISCARD FMT_INLINE auto formatted_size(format_string<T...> fmt, + T&&... args) -> size_t { + auto buf = detail::counting_buffer<>(); + detail::vformat_to(buf, string_view(fmt), fmt::make_format_args(args...), {}); + return buf.count(); +} + +FMT_API void vprint(string_view fmt, format_args args); +FMT_API void vprint(std::FILE* f, string_view fmt, format_args args); + +/** + \rst + Formats ``args`` according to specifications in ``fmt`` and writes the output + to ``stdout``. + + **Example**:: + + fmt::print("Elapsed time: {0:.2f} seconds", 1.23); + \endrst + */ +template <typename... T> +FMT_INLINE void print(format_string<T...> fmt, T&&... args) { + const auto& vargs = fmt::make_format_args(args...); + return detail::is_utf8() ? vprint(fmt, vargs) + : detail::vprint_mojibake(stdout, fmt, vargs); +} + +/** + \rst + Formats ``args`` according to specifications in ``fmt`` and writes the + output to the file ``f``. + + **Example**:: + + fmt::print(stderr, "Don't {}!", "panic"); + \endrst + */ +template <typename... T> +FMT_INLINE void print(std::FILE* f, format_string<T...> fmt, T&&... args) { + const auto& vargs = fmt::make_format_args(args...); + return detail::is_utf8() ? vprint(f, fmt, vargs) + : detail::vprint_mojibake(f, fmt, vargs); +} + +FMT_MODULE_EXPORT_END +FMT_GCC_PRAGMA("GCC pop_options") +FMT_END_NAMESPACE + +#ifdef FMT_HEADER_ONLY +# include "format.h" +#endif +#endif // FMT_CORE_H_ diff --git a/extern/fmtlib/include/fmt/format-inl.h b/extern/fmtlib/include/fmt/format-inl.h new file mode 100644 index 00000000000..2c51c50aeb2 --- /dev/null +++ b/extern/fmtlib/include/fmt/format-inl.h @@ -0,0 +1,2643 @@ +// Formatting library for C++ - implementation +// +// Copyright (c) 2012 - 2016, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#ifndef FMT_FORMAT_INL_H_ +#define FMT_FORMAT_INL_H_ + +#include <algorithm> +#include <cctype> +#include <cerrno> // errno +#include <climits> +#include <cmath> +#include <cstdarg> +#include <cstring> // std::memmove +#include <cwchar> +#include <exception> + +#ifndef FMT_STATIC_THOUSANDS_SEPARATOR +# include <locale> +#endif + +#ifdef _WIN32 +# include <io.h> // _isatty +#endif + +#include "format.h" + +FMT_BEGIN_NAMESPACE +namespace detail { + +FMT_FUNC void assert_fail(const char* file, int line, const char* message) { + // Use unchecked std::fprintf to avoid triggering another assertion when + // writing to stderr fails + std::fprintf(stderr, "%s:%d: assertion failed: %s", file, line, message); + // Chosen instead of std::abort to satisfy Clang in CUDA mode during device + // code pass. + std::terminate(); +} + +FMT_FUNC void throw_format_error(const char* message) { + FMT_THROW(format_error(message)); +} + +#ifndef _MSC_VER +# define FMT_SNPRINTF snprintf +#else // _MSC_VER +inline int fmt_snprintf(char* buffer, size_t size, const char* format, ...) { + va_list args; + va_start(args, format); + int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args); + va_end(args); + return result; +} +# define FMT_SNPRINTF fmt_snprintf +#endif // _MSC_VER + +FMT_FUNC void format_error_code(detail::buffer<char>& out, int error_code, + string_view message) FMT_NOEXCEPT { + // Report error code making sure that the output fits into + // inline_buffer_size to avoid dynamic memory allocation and potential + // bad_alloc. + out.try_resize(0); + static const char SEP[] = ": "; + static const char ERROR_STR[] = "error "; + // Subtract 2 to account for terminating null characters in SEP and ERROR_STR. + size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2; + auto abs_value = static_cast<uint32_or_64_or_128_t<int>>(error_code); + if (detail::is_negative(error_code)) { + abs_value = 0 - abs_value; + ++error_code_size; + } + error_code_size += detail::to_unsigned(detail::count_digits(abs_value)); + auto it = buffer_appender<char>(out); + if (message.size() <= inline_buffer_size - error_code_size) + format_to(it, FMT_STRING("{}{}"), message, SEP); + format_to(it, FMT_STRING("{}{}"), ERROR_STR, error_code); + FMT_ASSERT(out.size() <= inline_buffer_size, ""); +} + +FMT_FUNC void report_error(format_func func, int error_code, + const char* message) FMT_NOEXCEPT { + memory_buffer full_message; + func(full_message, error_code, message); + // Don't use fwrite_fully because the latter may throw. + if (std::fwrite(full_message.data(), full_message.size(), 1, stderr) > 0) + std::fputc('\n', stderr); +} + +// A wrapper around fwrite that throws on error. +inline void fwrite_fully(const void* ptr, size_t size, size_t count, + FILE* stream) { + size_t written = std::fwrite(ptr, size, count, stream); + if (written < count) FMT_THROW(system_error(errno, "cannot write to file")); +} + +#ifndef FMT_STATIC_THOUSANDS_SEPARATOR +template <typename Locale> +locale_ref::locale_ref(const Locale& loc) : locale_(&loc) { + static_assert(std::is_same<Locale, std::locale>::value, ""); +} + +template <typename Locale> Locale locale_ref::get() const { + static_assert(std::is_same<Locale, std::locale>::value, ""); + return locale_ ? *static_cast<const std::locale*>(locale_) : std::locale(); +} + +template <typename Char> +FMT_FUNC auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result<Char> { + auto& facet = std::use_facet<std::numpunct<Char>>(loc.get<std::locale>()); + auto grouping = facet.grouping(); + auto thousands_sep = grouping.empty() ? Char() : facet.thousands_sep(); + return {std::move(grouping), thousands_sep}; +} +template <typename Char> FMT_FUNC Char decimal_point_impl(locale_ref loc) { + return std::use_facet<std::numpunct<Char>>(loc.get<std::locale>()) + .decimal_point(); +} +#else +template <typename Char> +FMT_FUNC auto thousands_sep_impl(locale_ref) -> thousands_sep_result<Char> { + return {"\03", FMT_STATIC_THOUSANDS_SEPARATOR}; +} +template <typename Char> FMT_FUNC Char decimal_point_impl(locale_ref) { + return '.'; +} +#endif +} // namespace detail + +#if !FMT_MSC_VER +FMT_API FMT_FUNC format_error::~format_error() FMT_NOEXCEPT = default; +#endif + +FMT_FUNC std::system_error vsystem_error(int error_code, string_view format_str, + format_args args) { + auto ec = std::error_code(error_code, std::generic_category()); + return std::system_error(ec, vformat(format_str, args)); +} + +namespace detail { + +template <> FMT_FUNC int count_digits<4>(detail::fallback_uintptr n) { + // fallback_uintptr is always stored in little endian. + int i = static_cast<int>(sizeof(void*)) - 1; + while (i > 0 && n.value[i] == 0) --i; + auto char_digits = std::numeric_limits<unsigned char>::digits / 4; + return i >= 0 ? i * char_digits + count_digits<4, unsigned>(n.value[i]) : 1; +} + +// log10(2) = 0x0.4d104d427de7fbcc... +static constexpr uint64_t log10_2_significand = 0x4d104d427de7fbcc; + +template <typename T = void> struct basic_impl_data { + // Normalized 64-bit significands of pow(10, k), for k = -348, -340, ..., 340. + // These are generated by support/compute-powers.py. + static constexpr uint64_t pow10_significands[87] = { + 0xfa8fd5a0081c0288, 0xbaaee17fa23ebf76, 0x8b16fb203055ac76, + 0xcf42894a5dce35ea, 0x9a6bb0aa55653b2d, 0xe61acf033d1a45df, + 0xab70fe17c79ac6ca, 0xff77b1fcbebcdc4f, 0xbe5691ef416bd60c, + 0x8dd01fad907ffc3c, 0xd3515c2831559a83, 0x9d71ac8fada6c9b5, + 0xea9c227723ee8bcb, 0xaecc49914078536d, 0x823c12795db6ce57, + 0xc21094364dfb5637, 0x9096ea6f3848984f, 0xd77485cb25823ac7, + 0xa086cfcd97bf97f4, 0xef340a98172aace5, 0xb23867fb2a35b28e, + 0x84c8d4dfd2c63f3b, 0xc5dd44271ad3cdba, 0x936b9fcebb25c996, + 0xdbac6c247d62a584, 0xa3ab66580d5fdaf6, 0xf3e2f893dec3f126, + 0xb5b5ada8aaff80b8, 0x87625f056c7c4a8b, 0xc9bcff6034c13053, + 0x964e858c91ba2655, 0xdff9772470297ebd, 0xa6dfbd9fb8e5b88f, + 0xf8a95fcf88747d94, 0xb94470938fa89bcf, 0x8a08f0f8bf0f156b, + 0xcdb02555653131b6, 0x993fe2c6d07b7fac, 0xe45c10c42a2b3b06, + 0xaa242499697392d3, 0xfd87b5f28300ca0e, 0xbce5086492111aeb, + 0x8cbccc096f5088cc, 0xd1b71758e219652c, 0x9c40000000000000, + 0xe8d4a51000000000, 0xad78ebc5ac620000, 0x813f3978f8940984, + 0xc097ce7bc90715b3, 0x8f7e32ce7bea5c70, 0xd5d238a4abe98068, + 0x9f4f2726179a2245, 0xed63a231d4c4fb27, 0xb0de65388cc8ada8, + 0x83c7088e1aab65db, 0xc45d1df942711d9a, 0x924d692ca61be758, + 0xda01ee641a708dea, 0xa26da3999aef774a, 0xf209787bb47d6b85, + 0xb454e4a179dd1877, 0x865b86925b9bc5c2, 0xc83553c5c8965d3d, + 0x952ab45cfa97a0b3, 0xde469fbd99a05fe3, 0xa59bc234db398c25, + 0xf6c69a72a3989f5c, 0xb7dcbf5354e9bece, 0x88fcf317f22241e2, + 0xcc20ce9bd35c78a5, 0x98165af37b2153df, 0xe2a0b5dc971f303a, + 0xa8d9d1535ce3b396, 0xfb9b7cd9a4a7443c, 0xbb764c4ca7a44410, + 0x8bab8eefb6409c1a, 0xd01fef10a657842c, 0x9b10a4e5e9913129, + 0xe7109bfba19c0c9d, 0xac2820d9623bf429, 0x80444b5e7aa7cf85, + 0xbf21e44003acdd2d, 0x8e679c2f5e44ff8f, 0xd433179d9c8cb841, + 0x9e19db92b4e31ba9, 0xeb96bf6ebadf77d9, 0xaf87023b9bf0ee6b, + }; + +#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wnarrowing" +#endif + // Binary exponents of pow(10, k), for k = -348, -340, ..., 340, corresponding + // to significands above. + static constexpr int16_t pow10_exponents[87] = { + -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, -954, + -927, -901, -874, -847, -821, -794, -768, -741, -715, -688, -661, + -635, -608, -582, -555, -529, -502, -475, -449, -422, -396, -369, + -343, -316, -289, -263, -236, -210, -183, -157, -130, -103, -77, + -50, -24, 3, 30, 56, 83, 109, 136, 162, 189, 216, + 242, 269, 295, 322, 348, 375, 402, 428, 455, 481, 508, + 534, 561, 588, 614, 641, 667, 694, 720, 747, 774, 800, + 827, 853, 880, 907, 933, 960, 986, 1013, 1039, 1066}; +#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409 +# pragma GCC diagnostic pop +#endif + + static constexpr uint64_t power_of_10_64[20] = { + 1, FMT_POWERS_OF_10(1ULL), FMT_POWERS_OF_10(1000000000ULL), + 10000000000000000000ULL}; +}; + +// This is a struct rather than an alias to avoid shadowing warnings in gcc. +struct impl_data : basic_impl_data<> {}; + +#if __cplusplus < 201703L +template <typename T> +constexpr uint64_t basic_impl_data<T>::pow10_significands[]; +template <typename T> constexpr int16_t basic_impl_data<T>::pow10_exponents[]; +template <typename T> constexpr uint64_t basic_impl_data<T>::power_of_10_64[]; +#endif + +template <typename T> struct bits { + static FMT_CONSTEXPR_DECL const int value = + static_cast<int>(sizeof(T) * std::numeric_limits<unsigned char>::digits); +}; + +// Returns the number of significand bits in Float excluding the implicit bit. +template <typename Float> constexpr int num_significand_bits() { + // Subtract 1 to account for an implicit most significant bit in the + // normalized form. + return std::numeric_limits<Float>::digits - 1; +} + +// A floating-point number f * pow(2, e). +struct fp { + uint64_t f; + int e; + + static constexpr const int num_significand_bits = bits<decltype(f)>::value; + + constexpr fp() : f(0), e(0) {} + constexpr fp(uint64_t f_val, int e_val) : f(f_val), e(e_val) {} + + // Constructs fp from an IEEE754 floating-point number. It is a template to + // prevent compile errors on systems where n is not IEEE754. + template <typename Float> explicit FMT_CONSTEXPR fp(Float n) { assign(n); } + + template <typename Float> + using is_supported = bool_constant<sizeof(Float) == sizeof(uint64_t) || + sizeof(Float) == sizeof(uint32_t)>; + + // Assigns d to this and return true iff predecessor is closer than successor. + template <typename Float, FMT_ENABLE_IF(is_supported<Float>::value)> + FMT_CONSTEXPR bool assign(Float n) { + // Assume float is in the format [sign][exponent][significand]. + const int num_float_significand_bits = + detail::num_significand_bits<Float>(); + const uint64_t implicit_bit = 1ULL << num_float_significand_bits; + const uint64_t significand_mask = implicit_bit - 1; + constexpr bool is_double = sizeof(Float) == sizeof(uint64_t); + auto u = bit_cast<conditional_t<is_double, uint64_t, uint32_t>>(n); + f = u & significand_mask; + const uint64_t exponent_mask = (~0ULL >> 1) & ~significand_mask; + int biased_e = + static_cast<int>((u & exponent_mask) >> num_float_significand_bits); + // The predecessor is closer if n is a normalized power of 2 (f == 0) other + // than the smallest normalized number (biased_e > 1). + bool is_predecessor_closer = f == 0 && biased_e > 1; + if (biased_e != 0) + f += implicit_bit; + else + biased_e = 1; // Subnormals use biased exponent 1 (min exponent). + const int exponent_bias = std::numeric_limits<Float>::max_exponent - 1; + e = biased_e - exponent_bias - num_float_significand_bits; + return is_predecessor_closer; + } + + template <typename Float, FMT_ENABLE_IF(!is_supported<Float>::value)> + bool assign(Float) { + FMT_ASSERT(false, ""); + return false; + } +}; + +// Normalizes the value converted from double and multiplied by (1 << SHIFT). +template <int SHIFT = 0> FMT_CONSTEXPR fp normalize(fp value) { + // Handle subnormals. + const uint64_t implicit_bit = 1ULL << num_significand_bits<double>(); + const auto shifted_implicit_bit = implicit_bit << SHIFT; + while ((value.f & shifted_implicit_bit) == 0) { + value.f <<= 1; + --value.e; + } + // Subtract 1 to account for hidden bit. + const auto offset = + fp::num_significand_bits - num_significand_bits<double>() - SHIFT - 1; + value.f <<= offset; + value.e -= offset; + return value; +} + +inline bool operator==(fp x, fp y) { return x.f == y.f && x.e == y.e; } + +// Computes lhs * rhs / pow(2, 64) rounded to nearest with half-up tie breaking. +FMT_CONSTEXPR inline uint64_t multiply(uint64_t lhs, uint64_t rhs) { +#if FMT_USE_INT128 + auto product = static_cast<__uint128_t>(lhs) * rhs; + auto f = static_cast<uint64_t>(product >> 64); + return (static_cast<uint64_t>(product) & (1ULL << 63)) != 0 ? f + 1 : f; +#else + // Multiply 32-bit parts of significands. + uint64_t mask = (1ULL << 32) - 1; + uint64_t a = lhs >> 32, b = lhs & mask; + uint64_t c = rhs >> 32, d = rhs & mask; + uint64_t ac = a * c, bc = b * c, ad = a * d, bd = b * d; + // Compute mid 64-bit of result and round. + uint64_t mid = (bd >> 32) + (ad & mask) + (bc & mask) + (1U << 31); + return ac + (ad >> 32) + (bc >> 32) + (mid >> 32); +#endif +} + +FMT_CONSTEXPR inline fp operator*(fp x, fp y) { + return {multiply(x.f, y.f), x.e + y.e + 64}; +} + +// Returns a cached power of 10 `c_k = c_k.f * pow(2, c_k.e)` such that its +// (binary) exponent satisfies `min_exponent <= c_k.e <= min_exponent + 28`. +FMT_CONSTEXPR inline fp get_cached_power(int min_exponent, + int& pow10_exponent) { + const int shift = 32; + const auto significand = static_cast<int64_t>(log10_2_significand); + int index = static_cast<int>( + ((min_exponent + fp::num_significand_bits - 1) * (significand >> shift) + + ((int64_t(1) << shift) - 1)) // ceil + >> 32 // arithmetic shift + ); + // Decimal exponent of the first (smallest) cached power of 10. + const int first_dec_exp = -348; + // Difference between 2 consecutive decimal exponents in cached powers of 10. + const int dec_exp_step = 8; + index = (index - first_dec_exp - 1) / dec_exp_step + 1; + pow10_exponent = first_dec_exp + index * dec_exp_step; + return {impl_data::pow10_significands[index], + impl_data::pow10_exponents[index]}; +} + +// A simple accumulator to hold the sums of terms in bigint::square if uint128_t +// is not available. +struct accumulator { + uint64_t lower; + uint64_t upper; + + constexpr accumulator() : lower(0), upper(0) {} + constexpr explicit operator uint32_t() const { + return static_cast<uint32_t>(lower); + } + + FMT_CONSTEXPR void operator+=(uint64_t n) { + lower += n; + if (lower < n) ++upper; + } + FMT_CONSTEXPR void operator>>=(int shift) { + FMT_ASSERT(shift == 32, ""); + (void)shift; + lower = (upper << 32) | (lower >> 32); + upper >>= 32; + } +}; + +class bigint { + private: + // A bigint is stored as an array of bigits (big digits), with bigit at index + // 0 being the least significant one. + using bigit = uint32_t; + using double_bigit = uint64_t; + enum { bigits_capacity = 32 }; + basic_memory_buffer<bigit, bigits_capacity> bigits_; + int exp_; + + FMT_CONSTEXPR20 bigit operator[](int index) const { + return bigits_[to_unsigned(index)]; + } + FMT_CONSTEXPR20 bigit& operator[](int index) { + return bigits_[to_unsigned(index)]; + } + + static FMT_CONSTEXPR_DECL const int bigit_bits = bits<bigit>::value; + + friend struct formatter<bigint>; + + FMT_CONSTEXPR20 void subtract_bigits(int index, bigit other, bigit& borrow) { + auto result = static_cast<double_bigit>((*this)[index]) - other - borrow; + (*this)[index] = static_cast<bigit>(result); + borrow = static_cast<bigit>(result >> (bigit_bits * 2 - 1)); + } + + FMT_CONSTEXPR20 void remove_leading_zeros() { + int num_bigits = static_cast<int>(bigits_.size()) - 1; + while (num_bigits > 0 && (*this)[num_bigits] == 0) --num_bigits; + bigits_.resize(to_unsigned(num_bigits + 1)); + } + + // Computes *this -= other assuming aligned bigints and *this >= other. + FMT_CONSTEXPR20 void subtract_aligned(const bigint& other) { + FMT_ASSERT(other.exp_ >= exp_, "unaligned bigints"); + FMT_ASSERT(compare(*this, other) >= 0, ""); + bigit borrow = 0; + int i = other.exp_ - exp_; + for (size_t j = 0, n = other.bigits_.size(); j != n; ++i, ++j) + subtract_bigits(i, other.bigits_[j], borrow); + while (borrow > 0) subtract_bigits(i, 0, borrow); + remove_leading_zeros(); + } + + FMT_CONSTEXPR20 void multiply(uint32_t value) { + const double_bigit wide_value = value; + bigit carry = 0; + for (size_t i = 0, n = bigits_.size(); i < n; ++i) { + double_bigit result = bigits_[i] * wide_value + carry; + bigits_[i] = static_cast<bigit>(result); + carry = static_cast<bigit>(result >> bigit_bits); + } + if (carry != 0) bigits_.push_back(carry); + } + + FMT_CONSTEXPR20 void multiply(uint64_t value) { + const bigit mask = ~bigit(0); + const double_bigit lower = value & mask; + const double_bigit upper = value >> bigit_bits; + double_bigit carry = 0; + for (size_t i = 0, n = bigits_.size(); i < n; ++i) { + double_bigit result = bigits_[i] * lower + (carry & mask); + carry = + bigits_[i] * upper + (result >> bigit_bits) + (carry >> bigit_bits); + bigits_[i] = static_cast<bigit>(result); + } + while (carry != 0) { + bigits_.push_back(carry & mask); + carry >>= bigit_bits; + } + } + + public: + FMT_CONSTEXPR20 bigint() : exp_(0) {} + explicit bigint(uint64_t n) { assign(n); } + FMT_CONSTEXPR20 ~bigint() { + FMT_ASSERT(bigits_.capacity() <= bigits_capacity, ""); + } + + bigint(const bigint&) = delete; + void operator=(const bigint&) = delete; + + FMT_CONSTEXPR20 void assign(const bigint& other) { + auto size = other.bigits_.size(); + bigits_.resize(size); + auto data = other.bigits_.data(); + std::copy(data, data + size, make_checked(bigits_.data(), size)); + exp_ = other.exp_; + } + + FMT_CONSTEXPR20 void assign(uint64_t n) { + size_t num_bigits = 0; + do { + bigits_[num_bigits++] = n & ~bigit(0); + n >>= bigit_bits; + } while (n != 0); + bigits_.resize(num_bigits); + exp_ = 0; + } + + FMT_CONSTEXPR20 int num_bigits() const { + return static_cast<int>(bigits_.size()) + exp_; + } + + FMT_NOINLINE FMT_CONSTEXPR20 bigint& operator<<=(int shift) { + FMT_ASSERT(shift >= 0, ""); + exp_ += shift / bigit_bits; + shift %= bigit_bits; + if (shift == 0) return *this; + bigit carry = 0; + for (size_t i = 0, n = bigits_.size(); i < n; ++i) { + bigit c = bigits_[i] >> (bigit_bits - shift); + bigits_[i] = (bigits_[i] << shift) + carry; + carry = c; + } + if (carry != 0) bigits_.push_back(carry); + return *this; + } + + template <typename Int> FMT_CONSTEXPR20 bigint& operator*=(Int value) { + FMT_ASSERT(value > 0, ""); + multiply(uint32_or_64_or_128_t<Int>(value)); + return *this; + } + + friend FMT_CONSTEXPR20 int compare(const bigint& lhs, const bigint& rhs) { + int num_lhs_bigits = lhs.num_bigits(), num_rhs_bigits = rhs.num_bigits(); + if (num_lhs_bigits != num_rhs_bigits) + return num_lhs_bigits > num_rhs_bigits ? 1 : -1; + int i = static_cast<int>(lhs.bigits_.size()) - 1; + int j = static_cast<int>(rhs.bigits_.size()) - 1; + int end = i - j; + if (end < 0) end = 0; + for (; i >= end; --i, --j) { + bigit lhs_bigit = lhs[i], rhs_bigit = rhs[j]; + if (lhs_bigit != rhs_bigit) return lhs_bigit > rhs_bigit ? 1 : -1; + } + if (i != j) return i > j ? 1 : -1; + return 0; + } + + // Returns compare(lhs1 + lhs2, rhs). + friend FMT_CONSTEXPR20 int add_compare(const bigint& lhs1, const bigint& lhs2, + const bigint& rhs) { + int max_lhs_bigits = (std::max)(lhs1.num_bigits(), lhs2.num_bigits()); + int num_rhs_bigits = rhs.num_bigits(); + if (max_lhs_bigits + 1 < num_rhs_bigits) return -1; + if (max_lhs_bigits > num_rhs_bigits) return 1; + auto get_bigit = [](const bigint& n, int i) -> bigit { + return i >= n.exp_ && i < n.num_bigits() ? n[i - n.exp_] : 0; + }; + double_bigit borrow = 0; + int min_exp = (std::min)((std::min)(lhs1.exp_, lhs2.exp_), rhs.exp_); + for (int i = num_rhs_bigits - 1; i >= min_exp; --i) { + double_bigit sum = + static_cast<double_bigit>(get_bigit(lhs1, i)) + get_bigit(lhs2, i); + bigit rhs_bigit = get_bigit(rhs, i); + if (sum > rhs_bigit + borrow) return 1; + borrow = rhs_bigit + borrow - sum; + if (borrow > 1) return -1; + borrow <<= bigit_bits; + } + return borrow != 0 ? -1 : 0; + } + + // Assigns pow(10, exp) to this bigint. + FMT_CONSTEXPR20 void assign_pow10(int exp) { + FMT_ASSERT(exp >= 0, ""); + if (exp == 0) return assign(1); + // Find the top bit. + int bitmask = 1; + while (exp >= bitmask) bitmask <<= 1; + bitmask >>= 1; + // pow(10, exp) = pow(5, exp) * pow(2, exp). First compute pow(5, exp) by + // repeated squaring and multiplication. + assign(5); + bitmask >>= 1; + while (bitmask != 0) { + square(); + if ((exp & bitmask) != 0) *this *= 5; + bitmask >>= 1; + } + *this <<= exp; // Multiply by pow(2, exp) by shifting. + } + + FMT_CONSTEXPR20 void square() { + int num_bigits = static_cast<int>(bigits_.size()); + int num_result_bigits = 2 * num_bigits; + basic_memory_buffer<bigit, bigits_capacity> n(std::move(bigits_)); + bigits_.resize(to_unsigned(num_result_bigits)); + using accumulator_t = conditional_t<FMT_USE_INT128, uint128_t, accumulator>; + auto sum = accumulator_t(); + for (int bigit_index = 0; bigit_index < num_bigits; ++bigit_index) { + // Compute bigit at position bigit_index of the result by adding + // cross-product terms n[i] * n[j] such that i + j == bigit_index. + for (int i = 0, j = bigit_index; j >= 0; ++i, --j) { + // Most terms are multiplied twice which can be optimized in the future. + sum += static_cast<double_bigit>(n[i]) * n[j]; + } + (*this)[bigit_index] = static_cast<bigit>(sum); + sum >>= bits<bigit>::value; // Compute the carry. + } + // Do the same for the top half. + for (int bigit_index = num_bigits; bigit_index < num_result_bigits; + ++bigit_index) { + for (int j = num_bigits - 1, i = bigit_index - j; i < num_bigits;) + sum += static_cast<double_bigit>(n[i++]) * n[j--]; + (*this)[bigit_index] = static_cast<bigit>(sum); + sum >>= bits<bigit>::value; + } + remove_leading_zeros(); + exp_ *= 2; + } + + // If this bigint has a bigger exponent than other, adds trailing zero to make + // exponents equal. This simplifies some operations such as subtraction. + FMT_CONSTEXPR20 void align(const bigint& other) { + int exp_difference = exp_ - other.exp_; + if (exp_difference <= 0) return; + int num_bigits = static_cast<int>(bigits_.size()); + bigits_.resize(to_unsigned(num_bigits + exp_difference)); + for (int i = num_bigits - 1, j = i + exp_difference; i >= 0; --i, --j) + bigits_[j] = bigits_[i]; + std::uninitialized_fill_n(bigits_.data(), exp_difference, 0); + exp_ -= exp_difference; + } + + // Divides this bignum by divisor, assigning the remainder to this and + // returning the quotient. + FMT_CONSTEXPR20 int divmod_assign(const bigint& divisor) { + FMT_ASSERT(this != &divisor, ""); + if (compare(*this, divisor) < 0) return 0; + FMT_ASSERT(divisor.bigits_[divisor.bigits_.size() - 1u] != 0, ""); + align(divisor); + int quotient = 0; + do { + subtract_aligned(divisor); + ++quotient; + } while (compare(*this, divisor) >= 0); + return quotient; + } +}; + +enum class round_direction { unknown, up, down }; + +// Given the divisor (normally a power of 10), the remainder = v % divisor for +// some number v and the error, returns whether v should be rounded up, down, or +// whether the rounding direction can't be determined due to error. +// error should be less than divisor / 2. +FMT_CONSTEXPR inline round_direction get_round_direction(uint64_t divisor, + uint64_t remainder, + uint64_t error) { + FMT_ASSERT(remainder < divisor, ""); // divisor - remainder won't overflow. + FMT_ASSERT(error < divisor, ""); // divisor - error won't overflow. + FMT_ASSERT(error < divisor - error, ""); // error * 2 won't overflow. + // Round down if (remainder + error) * 2 <= divisor. + if (remainder <= divisor - remainder && error * 2 <= divisor - remainder * 2) + return round_direction::down; + // Round up if (remainder - error) * 2 >= divisor. + if (remainder >= error && + remainder - error >= divisor - (remainder - error)) { + return round_direction::up; + } + return round_direction::unknown; +} + +namespace digits { +enum result { + more, // Generate more digits. + done, // Done generating digits. + error // Digit generation cancelled due to an error. +}; +} + +struct gen_digits_handler { + char* buf; + int size; + int precision; + int exp10; + bool fixed; + + FMT_CONSTEXPR digits::result on_digit(char digit, uint64_t divisor, + uint64_t remainder, uint64_t error, + bool integral) { + FMT_ASSERT(remainder < divisor, ""); + buf[size++] = digit; + if (!integral && error >= remainder) return digits::error; + if (size < precision) return digits::more; + if (!integral) { + // Check if error * 2 < divisor with overflow prevention. + // The check is not needed for the integral part because error = 1 + // and divisor > (1 << 32) there. + if (error >= divisor || error >= divisor - error) return digits::error; + } else { + FMT_ASSERT(error == 1 && divisor > 2, ""); + } + auto dir = get_round_direction(divisor, remainder, error); + if (dir != round_direction::up) + return dir == round_direction::down ? digits::done : digits::error; + ++buf[size - 1]; + for (int i = size - 1; i > 0 && buf[i] > '9'; --i) { + buf[i] = '0'; + ++buf[i - 1]; + } + if (buf[0] > '9') { + buf[0] = '1'; + if (fixed) + buf[size++] = '0'; + else + ++exp10; + } + return digits::done; + } +}; + +// Generates output using the Grisu digit-gen algorithm. +// error: the size of the region (lower, upper) outside of which numbers +// definitely do not round to value (Delta in Grisu3). +FMT_INLINE FMT_CONSTEXPR20 digits::result grisu_gen_digits( + fp value, uint64_t error, int& exp, gen_digits_handler& handler) { + const fp one(1ULL << -value.e, value.e); + // The integral part of scaled value (p1 in Grisu) = value / one. It cannot be + // zero because it contains a product of two 64-bit numbers with MSB set (due + // to normalization) - 1, shifted right by at most 60 bits. + auto integral = static_cast<uint32_t>(value.f >> -one.e); + FMT_ASSERT(integral != 0, ""); + FMT_ASSERT(integral == value.f >> -one.e, ""); + // The fractional part of scaled value (p2 in Grisu) c = value % one. + uint64_t fractional = value.f & (one.f - 1); + exp = count_digits(integral); // kappa in Grisu. + // Non-fixed formats require at least one digit and no precision adjustment. + if (handler.fixed) { + // Adjust fixed precision by exponent because it is relative to decimal + // point. + int precision_offset = exp + handler.exp10; + if (precision_offset > 0 && + handler.precision > max_value<int>() - precision_offset) { + FMT_THROW(format_error("number is too big")); + } + handler.precision += precision_offset; + // Check if precision is satisfied just by leading zeros, e.g. + // format("{:.2f}", 0.001) gives "0.00" without generating any digits. + if (handler.precision <= 0) { + if (handler.precision < 0) return digits::done; + // Divide by 10 to prevent overflow. + uint64_t divisor = impl_data::power_of_10_64[exp - 1] << -one.e; + auto dir = get_round_direction(divisor, value.f / 10, error * 10); + if (dir == round_direction::unknown) return digits::error; + handler.buf[handler.size++] = dir == round_direction::up ? '1' : '0'; + return digits::done; + } + } + // Generate digits for the integral part. This can produce up to 10 digits. + do { + uint32_t digit = 0; + auto divmod_integral = [&](uint32_t divisor) { + digit = integral / divisor; + integral %= divisor; + }; + // This optimization by Milo Yip reduces the number of integer divisions by + // one per iteration. + switch (exp) { + case 10: + divmod_integral(1000000000); + break; + case 9: + divmod_integral(100000000); + break; + case 8: + divmod_integral(10000000); + break; + case 7: + divmod_integral(1000000); + break; + case 6: + divmod_integral(100000); + break; + case 5: + divmod_integral(10000); + break; + case 4: + divmod_integral(1000); + break; + case 3: + divmod_integral(100); + break; + case 2: + divmod_integral(10); + break; + case 1: + digit = integral; + integral = 0; + break; + default: + FMT_ASSERT(false, "invalid number of digits"); + } + --exp; + auto remainder = (static_cast<uint64_t>(integral) << -one.e) + fractional; + auto result = handler.on_digit(static_cast<char>('0' + digit), + impl_data::power_of_10_64[exp] << -one.e, + remainder, error, true); + if (result != digits::more) return result; + } while (exp > 0); + // Generate digits for the fractional part. + for (;;) { + fractional *= 10; + error *= 10; + char digit = static_cast<char>('0' + (fractional >> -one.e)); + fractional &= one.f - 1; + --exp; + auto result = handler.on_digit(digit, one.f, fractional, error, false); + if (result != digits::more) return result; + } +} + +// A 128-bit integer type used internally, +struct uint128_wrapper { + uint128_wrapper() = default; + +#if FMT_USE_INT128 + uint128_t internal_; + + constexpr uint128_wrapper(uint64_t high, uint64_t low) FMT_NOEXCEPT + : internal_{static_cast<uint128_t>(low) | + (static_cast<uint128_t>(high) << 64)} {} + + constexpr uint128_wrapper(uint128_t u) : internal_{u} {} + + constexpr uint64_t high() const FMT_NOEXCEPT { + return uint64_t(internal_ >> 64); + } + constexpr uint64_t low() const FMT_NOEXCEPT { return uint64_t(internal_); } + + uint128_wrapper& operator+=(uint64_t n) FMT_NOEXCEPT { + internal_ += n; + return *this; + } +#else + uint64_t high_; + uint64_t low_; + + constexpr uint128_wrapper(uint64_t high, uint64_t low) FMT_NOEXCEPT + : high_{high}, + low_{low} {} + + constexpr uint64_t high() const FMT_NOEXCEPT { return high_; } + constexpr uint64_t low() const FMT_NOEXCEPT { return low_; } + + uint128_wrapper& operator+=(uint64_t n) FMT_NOEXCEPT { +# if defined(_MSC_VER) && defined(_M_X64) + unsigned char carry = _addcarry_u64(0, low_, n, &low_); + _addcarry_u64(carry, high_, 0, &high_); + return *this; +# else + uint64_t sum = low_ + n; + high_ += (sum < low_ ? 1 : 0); + low_ = sum; + return *this; +# endif + } +#endif +}; + +// Implementation of Dragonbox algorithm: https://github.com/jk-jeon/dragonbox. +namespace dragonbox { +// Computes 128-bit result of multiplication of two 64-bit unsigned integers. +inline uint128_wrapper umul128(uint64_t x, uint64_t y) FMT_NOEXCEPT { +#if FMT_USE_INT128 + return static_cast<uint128_t>(x) * static_cast<uint128_t>(y); +#elif defined(_MSC_VER) && defined(_M_X64) + uint128_wrapper result; + result.low_ = _umul128(x, y, &result.high_); + return result; +#else + const uint64_t mask = (uint64_t(1) << 32) - uint64_t(1); + + uint64_t a = x >> 32; + uint64_t b = x & mask; + uint64_t c = y >> 32; + uint64_t d = y & mask; + + uint64_t ac = a * c; + uint64_t bc = b * c; + uint64_t ad = a * d; + uint64_t bd = b * d; + + uint64_t intermediate = (bd >> 32) + (ad & mask) + (bc & mask); + + return {ac + (intermediate >> 32) + (ad >> 32) + (bc >> 32), + (intermediate << 32) + (bd & mask)}; +#endif +} + +// Computes upper 64 bits of multiplication of two 64-bit unsigned integers. +inline uint64_t umul128_upper64(uint64_t x, uint64_t y) FMT_NOEXCEPT { +#if FMT_USE_INT128 + auto p = static_cast<uint128_t>(x) * static_cast<uint128_t>(y); + return static_cast<uint64_t>(p >> 64); +#elif defined(_MSC_VER) && defined(_M_X64) + return __umulh(x, y); +#else + return umul128(x, y).high(); +#endif +} + +// Computes upper 64 bits of multiplication of a 64-bit unsigned integer and a +// 128-bit unsigned integer. +inline uint64_t umul192_upper64(uint64_t x, uint128_wrapper y) FMT_NOEXCEPT { + uint128_wrapper g0 = umul128(x, y.high()); + g0 += umul128_upper64(x, y.low()); + return g0.high(); +} + +// Computes upper 32 bits of multiplication of a 32-bit unsigned integer and a +// 64-bit unsigned integer. +inline uint32_t umul96_upper32(uint32_t x, uint64_t y) FMT_NOEXCEPT { + return static_cast<uint32_t>(umul128_upper64(x, y)); +} + +// Computes middle 64 bits of multiplication of a 64-bit unsigned integer and a +// 128-bit unsigned integer. +inline uint64_t umul192_middle64(uint64_t x, uint128_wrapper y) FMT_NOEXCEPT { + uint64_t g01 = x * y.high(); + uint64_t g10 = umul128_upper64(x, y.low()); + return g01 + g10; +} + +// Computes lower 64 bits of multiplication of a 32-bit unsigned integer and a +// 64-bit unsigned integer. +inline uint64_t umul96_lower64(uint32_t x, uint64_t y) FMT_NOEXCEPT { + return x * y; +} + +// Computes floor(log10(pow(2, e))) for e in [-1700, 1700] using the method from +// https://fmt.dev/papers/Grisu-Exact.pdf#page=5, section 3.4. +inline int floor_log10_pow2(int e) FMT_NOEXCEPT { + FMT_ASSERT(e <= 1700 && e >= -1700, "too large exponent"); + const int shift = 22; + return (e * static_cast<int>(log10_2_significand >> (64 - shift))) >> shift; +} + +// Various fast log computations. +inline int floor_log2_pow10(int e) FMT_NOEXCEPT { + FMT_ASSERT(e <= 1233 && e >= -1233, "too large exponent"); + const uint64_t log2_10_integer_part = 3; + const uint64_t log2_10_fractional_digits = 0x5269e12f346e2bf9; + const int shift_amount = 19; + return (e * static_cast<int>( + (log2_10_integer_part << shift_amount) | + (log2_10_fractional_digits >> (64 - shift_amount)))) >> + shift_amount; +} +inline int floor_log10_pow2_minus_log10_4_over_3(int e) FMT_NOEXCEPT { + FMT_ASSERT(e <= 1700 && e >= -1700, "too large exponent"); + const uint64_t log10_4_over_3_fractional_digits = 0x1ffbfc2bbc780375; + const int shift_amount = 22; + return (e * static_cast<int>(log10_2_significand >> (64 - shift_amount)) - + static_cast<int>(log10_4_over_3_fractional_digits >> + (64 - shift_amount))) >> + shift_amount; +} + +// Returns true iff x is divisible by pow(2, exp). +inline bool divisible_by_power_of_2(uint32_t x, int exp) FMT_NOEXCEPT { + FMT_ASSERT(exp >= 1, ""); + FMT_ASSERT(x != 0, ""); +#ifdef FMT_BUILTIN_CTZ + return FMT_BUILTIN_CTZ(x) >= exp; +#else + return exp < num_bits<uint32_t>() && x == ((x >> exp) << exp); +#endif +} +inline bool divisible_by_power_of_2(uint64_t x, int exp) FMT_NOEXCEPT { + FMT_ASSERT(exp >= 1, ""); + FMT_ASSERT(x != 0, ""); +#ifdef FMT_BUILTIN_CTZLL + return FMT_BUILTIN_CTZLL(x) >= exp; +#else + return exp < num_bits<uint64_t>() && x == ((x >> exp) << exp); +#endif +} + +// Table entry type for divisibility test. +template <typename T> struct divtest_table_entry { + T mod_inv; + T max_quotient; +}; + +// Returns true iff x is divisible by pow(5, exp). +inline bool divisible_by_power_of_5(uint32_t x, int exp) FMT_NOEXCEPT { + FMT_ASSERT(exp <= 10, "too large exponent"); + static constexpr const divtest_table_entry<uint32_t> divtest_table[] = { + {0x00000001, 0xffffffff}, {0xcccccccd, 0x33333333}, + {0xc28f5c29, 0x0a3d70a3}, {0x26e978d5, 0x020c49ba}, + {0x3afb7e91, 0x0068db8b}, {0x0bcbe61d, 0x0014f8b5}, + {0x68c26139, 0x000431bd}, {0xae8d46a5, 0x0000d6bf}, + {0x22e90e21, 0x00002af3}, {0x3a2e9c6d, 0x00000897}, + {0x3ed61f49, 0x000001b7}}; + return x * divtest_table[exp].mod_inv <= divtest_table[exp].max_quotient; +} +inline bool divisible_by_power_of_5(uint64_t x, int exp) FMT_NOEXCEPT { + FMT_ASSERT(exp <= 23, "too large exponent"); + static constexpr const divtest_table_entry<uint64_t> divtest_table[] = { + {0x0000000000000001, 0xffffffffffffffff}, + {0xcccccccccccccccd, 0x3333333333333333}, + {0x8f5c28f5c28f5c29, 0x0a3d70a3d70a3d70}, + {0x1cac083126e978d5, 0x020c49ba5e353f7c}, + {0xd288ce703afb7e91, 0x0068db8bac710cb2}, + {0x5d4e8fb00bcbe61d, 0x0014f8b588e368f0}, + {0x790fb65668c26139, 0x000431bde82d7b63}, + {0xe5032477ae8d46a5, 0x0000d6bf94d5e57a}, + {0xc767074b22e90e21, 0x00002af31dc46118}, + {0x8e47ce423a2e9c6d, 0x0000089705f4136b}, + {0x4fa7f60d3ed61f49, 0x000001b7cdfd9d7b}, + {0x0fee64690c913975, 0x00000057f5ff85e5}, + {0x3662e0e1cf503eb1, 0x000000119799812d}, + {0xa47a2cf9f6433fbd, 0x0000000384b84d09}, + {0x54186f653140a659, 0x00000000b424dc35}, + {0x7738164770402145, 0x0000000024075f3d}, + {0xe4a4d1417cd9a041, 0x000000000734aca5}, + {0xc75429d9e5c5200d, 0x000000000170ef54}, + {0xc1773b91fac10669, 0x000000000049c977}, + {0x26b172506559ce15, 0x00000000000ec1e4}, + {0xd489e3a9addec2d1, 0x000000000002f394}, + {0x90e860bb892c8d5d, 0x000000000000971d}, + {0x502e79bf1b6f4f79, 0x0000000000001e39}, + {0xdcd618596be30fe5, 0x000000000000060b}}; + return x * divtest_table[exp].mod_inv <= divtest_table[exp].max_quotient; +} + +// Replaces n by floor(n / pow(5, N)) returning true if and only if n is +// divisible by pow(5, N). +// Precondition: n <= 2 * pow(5, N + 1). +template <int N> +bool check_divisibility_and_divide_by_pow5(uint32_t& n) FMT_NOEXCEPT { + static constexpr struct { + uint32_t magic_number; + int bits_for_comparison; + uint32_t threshold; + int shift_amount; + } infos[] = {{0xcccd, 16, 0x3333, 18}, {0xa429, 8, 0x0a, 20}}; + constexpr auto info = infos[N - 1]; + n *= info.magic_number; + const uint32_t comparison_mask = (1u << info.bits_for_comparison) - 1; + bool result = (n & comparison_mask) <= info.threshold; + n >>= info.shift_amount; + return result; +} + +// Computes floor(n / pow(10, N)) for small n and N. +// Precondition: n <= pow(10, N + 1). +template <int N> uint32_t small_division_by_pow10(uint32_t n) FMT_NOEXCEPT { + static constexpr struct { + uint32_t magic_number; + int shift_amount; + uint32_t divisor_times_10; + } infos[] = {{0xcccd, 19, 100}, {0xa3d8, 22, 1000}}; + constexpr auto info = infos[N - 1]; + FMT_ASSERT(n <= info.divisor_times_10, "n is too large"); + return n * info.magic_number >> info.shift_amount; +} + +// Computes floor(n / 10^(kappa + 1)) (float) +inline uint32_t divide_by_10_to_kappa_plus_1(uint32_t n) FMT_NOEXCEPT { + return n / float_info<float>::big_divisor; +} +// Computes floor(n / 10^(kappa + 1)) (double) +inline uint64_t divide_by_10_to_kappa_plus_1(uint64_t n) FMT_NOEXCEPT { + return umul128_upper64(n, 0x83126e978d4fdf3c) >> 9; +} + +// Various subroutines using pow10 cache +template <class T> struct cache_accessor; + +template <> struct cache_accessor<float> { + using carrier_uint = float_info<float>::carrier_uint; + using cache_entry_type = uint64_t; + + static uint64_t get_cached_power(int k) FMT_NOEXCEPT { + FMT_ASSERT(k >= float_info<float>::min_k && k <= float_info<float>::max_k, + "k is out of range"); + static constexpr const uint64_t pow10_significands[] = { + 0x81ceb32c4b43fcf5, 0xa2425ff75e14fc32, 0xcad2f7f5359a3b3f, + 0xfd87b5f28300ca0e, 0x9e74d1b791e07e49, 0xc612062576589ddb, + 0xf79687aed3eec552, 0x9abe14cd44753b53, 0xc16d9a0095928a28, + 0xf1c90080baf72cb2, 0x971da05074da7bef, 0xbce5086492111aeb, + 0xec1e4a7db69561a6, 0x9392ee8e921d5d08, 0xb877aa3236a4b44a, + 0xe69594bec44de15c, 0x901d7cf73ab0acda, 0xb424dc35095cd810, + 0xe12e13424bb40e14, 0x8cbccc096f5088cc, 0xafebff0bcb24aaff, + 0xdbe6fecebdedd5bf, 0x89705f4136b4a598, 0xabcc77118461cefd, + 0xd6bf94d5e57a42bd, 0x8637bd05af6c69b6, 0xa7c5ac471b478424, + 0xd1b71758e219652c, 0x83126e978d4fdf3c, 0xa3d70a3d70a3d70b, + 0xcccccccccccccccd, 0x8000000000000000, 0xa000000000000000, + 0xc800000000000000, 0xfa00000000000000, 0x9c40000000000000, + 0xc350000000000000, 0xf424000000000000, 0x9896800000000000, + 0xbebc200000000000, 0xee6b280000000000, 0x9502f90000000000, + 0xba43b74000000000, 0xe8d4a51000000000, 0x9184e72a00000000, + 0xb5e620f480000000, 0xe35fa931a0000000, 0x8e1bc9bf04000000, + 0xb1a2bc2ec5000000, 0xde0b6b3a76400000, 0x8ac7230489e80000, + 0xad78ebc5ac620000, 0xd8d726b7177a8000, 0x878678326eac9000, + 0xa968163f0a57b400, 0xd3c21bcecceda100, 0x84595161401484a0, + 0xa56fa5b99019a5c8, 0xcecb8f27f4200f3a, 0x813f3978f8940984, + 0xa18f07d736b90be5, 0xc9f2c9cd04674ede, 0xfc6f7c4045812296, + 0x9dc5ada82b70b59d, 0xc5371912364ce305, 0xf684df56c3e01bc6, + 0x9a130b963a6c115c, 0xc097ce7bc90715b3, 0xf0bdc21abb48db20, + 0x96769950b50d88f4, 0xbc143fa4e250eb31, 0xeb194f8e1ae525fd, + 0x92efd1b8d0cf37be, 0xb7abc627050305ad, 0xe596b7b0c643c719, + 0x8f7e32ce7bea5c6f, 0xb35dbf821ae4f38b, 0xe0352f62a19e306e}; + return pow10_significands[k - float_info<float>::min_k]; + } + + static carrier_uint compute_mul(carrier_uint u, + const cache_entry_type& cache) FMT_NOEXCEPT { + return umul96_upper32(u, cache); + } + + static uint32_t compute_delta(const cache_entry_type& cache, + int beta_minus_1) FMT_NOEXCEPT { + return static_cast<uint32_t>(cache >> (64 - 1 - beta_minus_1)); + } + + static bool compute_mul_parity(carrier_uint two_f, + const cache_entry_type& cache, + int beta_minus_1) FMT_NOEXCEPT { + FMT_ASSERT(beta_minus_1 >= 1, ""); + FMT_ASSERT(beta_minus_1 < 64, ""); + + return ((umul96_lower64(two_f, cache) >> (64 - beta_minus_1)) & 1) != 0; + } + + static carrier_uint compute_left_endpoint_for_shorter_interval_case( + const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT { + return static_cast<carrier_uint>( + (cache - (cache >> (float_info<float>::significand_bits + 2))) >> + (64 - float_info<float>::significand_bits - 1 - beta_minus_1)); + } + + static carrier_uint compute_right_endpoint_for_shorter_interval_case( + const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT { + return static_cast<carrier_uint>( + (cache + (cache >> (float_info<float>::significand_bits + 1))) >> + (64 - float_info<float>::significand_bits - 1 - beta_minus_1)); + } + + static carrier_uint compute_round_up_for_shorter_interval_case( + const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT { + return (static_cast<carrier_uint>( + cache >> + (64 - float_info<float>::significand_bits - 2 - beta_minus_1)) + + 1) / + 2; + } +}; + +template <> struct cache_accessor<double> { + using carrier_uint = float_info<double>::carrier_uint; + using cache_entry_type = uint128_wrapper; + + static uint128_wrapper get_cached_power(int k) FMT_NOEXCEPT { + FMT_ASSERT(k >= float_info<double>::min_k && k <= float_info<double>::max_k, + "k is out of range"); + + static constexpr const uint128_wrapper pow10_significands[] = { +#if FMT_USE_FULL_CACHE_DRAGONBOX + {0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7b}, + {0x9faacf3df73609b1, 0x77b191618c54e9ad}, + {0xc795830d75038c1d, 0xd59df5b9ef6a2418}, + {0xf97ae3d0d2446f25, 0x4b0573286b44ad1e}, + {0x9becce62836ac577, 0x4ee367f9430aec33}, + {0xc2e801fb244576d5, 0x229c41f793cda740}, + {0xf3a20279ed56d48a, 0x6b43527578c11110}, + {0x9845418c345644d6, 0x830a13896b78aaaa}, + {0xbe5691ef416bd60c, 0x23cc986bc656d554}, + {0xedec366b11c6cb8f, 0x2cbfbe86b7ec8aa9}, + {0x94b3a202eb1c3f39, 0x7bf7d71432f3d6aa}, + {0xb9e08a83a5e34f07, 0xdaf5ccd93fb0cc54}, + {0xe858ad248f5c22c9, 0xd1b3400f8f9cff69}, + {0x91376c36d99995be, 0x23100809b9c21fa2}, + {0xb58547448ffffb2d, 0xabd40a0c2832a78b}, + {0xe2e69915b3fff9f9, 0x16c90c8f323f516d}, + {0x8dd01fad907ffc3b, 0xae3da7d97f6792e4}, + {0xb1442798f49ffb4a, 0x99cd11cfdf41779d}, + {0xdd95317f31c7fa1d, 0x40405643d711d584}, + {0x8a7d3eef7f1cfc52, 0x482835ea666b2573}, + {0xad1c8eab5ee43b66, 0xda3243650005eed0}, + {0xd863b256369d4a40, 0x90bed43e40076a83}, + {0x873e4f75e2224e68, 0x5a7744a6e804a292}, + {0xa90de3535aaae202, 0x711515d0a205cb37}, + {0xd3515c2831559a83, 0x0d5a5b44ca873e04}, + {0x8412d9991ed58091, 0xe858790afe9486c3}, + {0xa5178fff668ae0b6, 0x626e974dbe39a873}, + {0xce5d73ff402d98e3, 0xfb0a3d212dc81290}, + {0x80fa687f881c7f8e, 0x7ce66634bc9d0b9a}, + {0xa139029f6a239f72, 0x1c1fffc1ebc44e81}, + {0xc987434744ac874e, 0xa327ffb266b56221}, + {0xfbe9141915d7a922, 0x4bf1ff9f0062baa9}, + {0x9d71ac8fada6c9b5, 0x6f773fc3603db4aa}, + {0xc4ce17b399107c22, 0xcb550fb4384d21d4}, + {0xf6019da07f549b2b, 0x7e2a53a146606a49}, + {0x99c102844f94e0fb, 0x2eda7444cbfc426e}, + {0xc0314325637a1939, 0xfa911155fefb5309}, + {0xf03d93eebc589f88, 0x793555ab7eba27cb}, + {0x96267c7535b763b5, 0x4bc1558b2f3458df}, + {0xbbb01b9283253ca2, 0x9eb1aaedfb016f17}, + {0xea9c227723ee8bcb, 0x465e15a979c1cadd}, + {0x92a1958a7675175f, 0x0bfacd89ec191eca}, + {0xb749faed14125d36, 0xcef980ec671f667c}, + {0xe51c79a85916f484, 0x82b7e12780e7401b}, + {0x8f31cc0937ae58d2, 0xd1b2ecb8b0908811}, + {0xb2fe3f0b8599ef07, 0x861fa7e6dcb4aa16}, + {0xdfbdcece67006ac9, 0x67a791e093e1d49b}, + {0x8bd6a141006042bd, 0xe0c8bb2c5c6d24e1}, + {0xaecc49914078536d, 0x58fae9f773886e19}, + {0xda7f5bf590966848, 0xaf39a475506a899f}, + {0x888f99797a5e012d, 0x6d8406c952429604}, + {0xaab37fd7d8f58178, 0xc8e5087ba6d33b84}, + {0xd5605fcdcf32e1d6, 0xfb1e4a9a90880a65}, + {0x855c3be0a17fcd26, 0x5cf2eea09a550680}, + {0xa6b34ad8c9dfc06f, 0xf42faa48c0ea481f}, + {0xd0601d8efc57b08b, 0xf13b94daf124da27}, + {0x823c12795db6ce57, 0x76c53d08d6b70859}, + {0xa2cb1717b52481ed, 0x54768c4b0c64ca6f}, + {0xcb7ddcdda26da268, 0xa9942f5dcf7dfd0a}, + {0xfe5d54150b090b02, 0xd3f93b35435d7c4d}, + {0x9efa548d26e5a6e1, 0xc47bc5014a1a6db0}, + {0xc6b8e9b0709f109a, 0x359ab6419ca1091c}, + {0xf867241c8cc6d4c0, 0xc30163d203c94b63}, + {0x9b407691d7fc44f8, 0x79e0de63425dcf1e}, + {0xc21094364dfb5636, 0x985915fc12f542e5}, + {0xf294b943e17a2bc4, 0x3e6f5b7b17b2939e}, + {0x979cf3ca6cec5b5a, 0xa705992ceecf9c43}, + {0xbd8430bd08277231, 0x50c6ff782a838354}, + {0xece53cec4a314ebd, 0xa4f8bf5635246429}, + {0x940f4613ae5ed136, 0x871b7795e136be9a}, + {0xb913179899f68584, 0x28e2557b59846e40}, + {0xe757dd7ec07426e5, 0x331aeada2fe589d0}, + {0x9096ea6f3848984f, 0x3ff0d2c85def7622}, + {0xb4bca50b065abe63, 0x0fed077a756b53aa}, + {0xe1ebce4dc7f16dfb, 0xd3e8495912c62895}, + {0x8d3360f09cf6e4bd, 0x64712dd7abbbd95d}, + {0xb080392cc4349dec, 0xbd8d794d96aacfb4}, + {0xdca04777f541c567, 0xecf0d7a0fc5583a1}, + {0x89e42caaf9491b60, 0xf41686c49db57245}, + {0xac5d37d5b79b6239, 0x311c2875c522ced6}, + {0xd77485cb25823ac7, 0x7d633293366b828c}, + {0x86a8d39ef77164bc, 0xae5dff9c02033198}, + {0xa8530886b54dbdeb, 0xd9f57f830283fdfd}, + {0xd267caa862a12d66, 0xd072df63c324fd7c}, + {0x8380dea93da4bc60, 0x4247cb9e59f71e6e}, + {0xa46116538d0deb78, 0x52d9be85f074e609}, + {0xcd795be870516656, 0x67902e276c921f8c}, + {0x806bd9714632dff6, 0x00ba1cd8a3db53b7}, + {0xa086cfcd97bf97f3, 0x80e8a40eccd228a5}, + {0xc8a883c0fdaf7df0, 0x6122cd128006b2ce}, + {0xfad2a4b13d1b5d6c, 0x796b805720085f82}, + {0x9cc3a6eec6311a63, 0xcbe3303674053bb1}, + {0xc3f490aa77bd60fc, 0xbedbfc4411068a9d}, + {0xf4f1b4d515acb93b, 0xee92fb5515482d45}, + {0x991711052d8bf3c5, 0x751bdd152d4d1c4b}, + {0xbf5cd54678eef0b6, 0xd262d45a78a0635e}, + {0xef340a98172aace4, 0x86fb897116c87c35}, + {0x9580869f0e7aac0e, 0xd45d35e6ae3d4da1}, + {0xbae0a846d2195712, 0x8974836059cca10a}, + {0xe998d258869facd7, 0x2bd1a438703fc94c}, + {0x91ff83775423cc06, 0x7b6306a34627ddd0}, + {0xb67f6455292cbf08, 0x1a3bc84c17b1d543}, + {0xe41f3d6a7377eeca, 0x20caba5f1d9e4a94}, + {0x8e938662882af53e, 0x547eb47b7282ee9d}, + {0xb23867fb2a35b28d, 0xe99e619a4f23aa44}, + {0xdec681f9f4c31f31, 0x6405fa00e2ec94d5}, + {0x8b3c113c38f9f37e, 0xde83bc408dd3dd05}, + {0xae0b158b4738705e, 0x9624ab50b148d446}, + {0xd98ddaee19068c76, 0x3badd624dd9b0958}, + {0x87f8a8d4cfa417c9, 0xe54ca5d70a80e5d7}, + {0xa9f6d30a038d1dbc, 0x5e9fcf4ccd211f4d}, + {0xd47487cc8470652b, 0x7647c32000696720}, + {0x84c8d4dfd2c63f3b, 0x29ecd9f40041e074}, + {0xa5fb0a17c777cf09, 0xf468107100525891}, + {0xcf79cc9db955c2cc, 0x7182148d4066eeb5}, + {0x81ac1fe293d599bf, 0xc6f14cd848405531}, + {0xa21727db38cb002f, 0xb8ada00e5a506a7d}, + {0xca9cf1d206fdc03b, 0xa6d90811f0e4851d}, + {0xfd442e4688bd304a, 0x908f4a166d1da664}, + {0x9e4a9cec15763e2e, 0x9a598e4e043287ff}, + {0xc5dd44271ad3cdba, 0x40eff1e1853f29fe}, + {0xf7549530e188c128, 0xd12bee59e68ef47d}, + {0x9a94dd3e8cf578b9, 0x82bb74f8301958cf}, + {0xc13a148e3032d6e7, 0xe36a52363c1faf02}, + {0xf18899b1bc3f8ca1, 0xdc44e6c3cb279ac2}, + {0x96f5600f15a7b7e5, 0x29ab103a5ef8c0ba}, + {0xbcb2b812db11a5de, 0x7415d448f6b6f0e8}, + {0xebdf661791d60f56, 0x111b495b3464ad22}, + {0x936b9fcebb25c995, 0xcab10dd900beec35}, + {0xb84687c269ef3bfb, 0x3d5d514f40eea743}, + {0xe65829b3046b0afa, 0x0cb4a5a3112a5113}, + {0x8ff71a0fe2c2e6dc, 0x47f0e785eaba72ac}, + {0xb3f4e093db73a093, 0x59ed216765690f57}, + {0xe0f218b8d25088b8, 0x306869c13ec3532d}, + {0x8c974f7383725573, 0x1e414218c73a13fc}, + {0xafbd2350644eeacf, 0xe5d1929ef90898fb}, + {0xdbac6c247d62a583, 0xdf45f746b74abf3a}, + {0x894bc396ce5da772, 0x6b8bba8c328eb784}, + {0xab9eb47c81f5114f, 0x066ea92f3f326565}, + {0xd686619ba27255a2, 0xc80a537b0efefebe}, + {0x8613fd0145877585, 0xbd06742ce95f5f37}, + {0xa798fc4196e952e7, 0x2c48113823b73705}, + {0xd17f3b51fca3a7a0, 0xf75a15862ca504c6}, + {0x82ef85133de648c4, 0x9a984d73dbe722fc}, + {0xa3ab66580d5fdaf5, 0xc13e60d0d2e0ebbb}, + {0xcc963fee10b7d1b3, 0x318df905079926a9}, + {0xffbbcfe994e5c61f, 0xfdf17746497f7053}, + {0x9fd561f1fd0f9bd3, 0xfeb6ea8bedefa634}, + {0xc7caba6e7c5382c8, 0xfe64a52ee96b8fc1}, + {0xf9bd690a1b68637b, 0x3dfdce7aa3c673b1}, + {0x9c1661a651213e2d, 0x06bea10ca65c084f}, + {0xc31bfa0fe5698db8, 0x486e494fcff30a63}, + {0xf3e2f893dec3f126, 0x5a89dba3c3efccfb}, + {0x986ddb5c6b3a76b7, 0xf89629465a75e01d}, + {0xbe89523386091465, 0xf6bbb397f1135824}, + {0xee2ba6c0678b597f, 0x746aa07ded582e2d}, + {0x94db483840b717ef, 0xa8c2a44eb4571cdd}, + {0xba121a4650e4ddeb, 0x92f34d62616ce414}, + {0xe896a0d7e51e1566, 0x77b020baf9c81d18}, + {0x915e2486ef32cd60, 0x0ace1474dc1d122f}, + {0xb5b5ada8aaff80b8, 0x0d819992132456bb}, + {0xe3231912d5bf60e6, 0x10e1fff697ed6c6a}, + {0x8df5efabc5979c8f, 0xca8d3ffa1ef463c2}, + {0xb1736b96b6fd83b3, 0xbd308ff8a6b17cb3}, + {0xddd0467c64bce4a0, 0xac7cb3f6d05ddbdf}, + {0x8aa22c0dbef60ee4, 0x6bcdf07a423aa96c}, + {0xad4ab7112eb3929d, 0x86c16c98d2c953c7}, + {0xd89d64d57a607744, 0xe871c7bf077ba8b8}, + {0x87625f056c7c4a8b, 0x11471cd764ad4973}, + {0xa93af6c6c79b5d2d, 0xd598e40d3dd89bd0}, + {0xd389b47879823479, 0x4aff1d108d4ec2c4}, + {0x843610cb4bf160cb, 0xcedf722a585139bb}, + {0xa54394fe1eedb8fe, 0xc2974eb4ee658829}, + {0xce947a3da6a9273e, 0x733d226229feea33}, + {0x811ccc668829b887, 0x0806357d5a3f5260}, + {0xa163ff802a3426a8, 0xca07c2dcb0cf26f8}, + {0xc9bcff6034c13052, 0xfc89b393dd02f0b6}, + {0xfc2c3f3841f17c67, 0xbbac2078d443ace3}, + {0x9d9ba7832936edc0, 0xd54b944b84aa4c0e}, + {0xc5029163f384a931, 0x0a9e795e65d4df12}, + {0xf64335bcf065d37d, 0x4d4617b5ff4a16d6}, + {0x99ea0196163fa42e, 0x504bced1bf8e4e46}, + {0xc06481fb9bcf8d39, 0xe45ec2862f71e1d7}, + {0xf07da27a82c37088, 0x5d767327bb4e5a4d}, + {0x964e858c91ba2655, 0x3a6a07f8d510f870}, + {0xbbe226efb628afea, 0x890489f70a55368c}, + {0xeadab0aba3b2dbe5, 0x2b45ac74ccea842f}, + {0x92c8ae6b464fc96f, 0x3b0b8bc90012929e}, + {0xb77ada0617e3bbcb, 0x09ce6ebb40173745}, + {0xe55990879ddcaabd, 0xcc420a6a101d0516}, + {0x8f57fa54c2a9eab6, 0x9fa946824a12232e}, + {0xb32df8e9f3546564, 0x47939822dc96abfa}, + {0xdff9772470297ebd, 0x59787e2b93bc56f8}, + {0x8bfbea76c619ef36, 0x57eb4edb3c55b65b}, + {0xaefae51477a06b03, 0xede622920b6b23f2}, + {0xdab99e59958885c4, 0xe95fab368e45ecee}, + {0x88b402f7fd75539b, 0x11dbcb0218ebb415}, + {0xaae103b5fcd2a881, 0xd652bdc29f26a11a}, + {0xd59944a37c0752a2, 0x4be76d3346f04960}, + {0x857fcae62d8493a5, 0x6f70a4400c562ddc}, + {0xa6dfbd9fb8e5b88e, 0xcb4ccd500f6bb953}, + {0xd097ad07a71f26b2, 0x7e2000a41346a7a8}, + {0x825ecc24c873782f, 0x8ed400668c0c28c9}, + {0xa2f67f2dfa90563b, 0x728900802f0f32fb}, + {0xcbb41ef979346bca, 0x4f2b40a03ad2ffba}, + {0xfea126b7d78186bc, 0xe2f610c84987bfa9}, + {0x9f24b832e6b0f436, 0x0dd9ca7d2df4d7ca}, + {0xc6ede63fa05d3143, 0x91503d1c79720dbc}, + {0xf8a95fcf88747d94, 0x75a44c6397ce912b}, + {0x9b69dbe1b548ce7c, 0xc986afbe3ee11abb}, + {0xc24452da229b021b, 0xfbe85badce996169}, + {0xf2d56790ab41c2a2, 0xfae27299423fb9c4}, + {0x97c560ba6b0919a5, 0xdccd879fc967d41b}, + {0xbdb6b8e905cb600f, 0x5400e987bbc1c921}, + {0xed246723473e3813, 0x290123e9aab23b69}, + {0x9436c0760c86e30b, 0xf9a0b6720aaf6522}, + {0xb94470938fa89bce, 0xf808e40e8d5b3e6a}, + {0xe7958cb87392c2c2, 0xb60b1d1230b20e05}, + {0x90bd77f3483bb9b9, 0xb1c6f22b5e6f48c3}, + {0xb4ecd5f01a4aa828, 0x1e38aeb6360b1af4}, + {0xe2280b6c20dd5232, 0x25c6da63c38de1b1}, + {0x8d590723948a535f, 0x579c487e5a38ad0f}, + {0xb0af48ec79ace837, 0x2d835a9df0c6d852}, + {0xdcdb1b2798182244, 0xf8e431456cf88e66}, + {0x8a08f0f8bf0f156b, 0x1b8e9ecb641b5900}, + {0xac8b2d36eed2dac5, 0xe272467e3d222f40}, + {0xd7adf884aa879177, 0x5b0ed81dcc6abb10}, + {0x86ccbb52ea94baea, 0x98e947129fc2b4ea}, + {0xa87fea27a539e9a5, 0x3f2398d747b36225}, + {0xd29fe4b18e88640e, 0x8eec7f0d19a03aae}, + {0x83a3eeeef9153e89, 0x1953cf68300424ad}, + {0xa48ceaaab75a8e2b, 0x5fa8c3423c052dd8}, + {0xcdb02555653131b6, 0x3792f412cb06794e}, + {0x808e17555f3ebf11, 0xe2bbd88bbee40bd1}, + {0xa0b19d2ab70e6ed6, 0x5b6aceaeae9d0ec5}, + {0xc8de047564d20a8b, 0xf245825a5a445276}, + {0xfb158592be068d2e, 0xeed6e2f0f0d56713}, + {0x9ced737bb6c4183d, 0x55464dd69685606c}, + {0xc428d05aa4751e4c, 0xaa97e14c3c26b887}, + {0xf53304714d9265df, 0xd53dd99f4b3066a9}, + {0x993fe2c6d07b7fab, 0xe546a8038efe402a}, + {0xbf8fdb78849a5f96, 0xde98520472bdd034}, + {0xef73d256a5c0f77c, 0x963e66858f6d4441}, + {0x95a8637627989aad, 0xdde7001379a44aa9}, + {0xbb127c53b17ec159, 0x5560c018580d5d53}, + {0xe9d71b689dde71af, 0xaab8f01e6e10b4a7}, + {0x9226712162ab070d, 0xcab3961304ca70e9}, + {0xb6b00d69bb55c8d1, 0x3d607b97c5fd0d23}, + {0xe45c10c42a2b3b05, 0x8cb89a7db77c506b}, + {0x8eb98a7a9a5b04e3, 0x77f3608e92adb243}, + {0xb267ed1940f1c61c, 0x55f038b237591ed4}, + {0xdf01e85f912e37a3, 0x6b6c46dec52f6689}, + {0x8b61313bbabce2c6, 0x2323ac4b3b3da016}, + {0xae397d8aa96c1b77, 0xabec975e0a0d081b}, + {0xd9c7dced53c72255, 0x96e7bd358c904a22}, + {0x881cea14545c7575, 0x7e50d64177da2e55}, + {0xaa242499697392d2, 0xdde50bd1d5d0b9ea}, + {0xd4ad2dbfc3d07787, 0x955e4ec64b44e865}, + {0x84ec3c97da624ab4, 0xbd5af13bef0b113f}, + {0xa6274bbdd0fadd61, 0xecb1ad8aeacdd58f}, + {0xcfb11ead453994ba, 0x67de18eda5814af3}, + {0x81ceb32c4b43fcf4, 0x80eacf948770ced8}, + {0xa2425ff75e14fc31, 0xa1258379a94d028e}, + {0xcad2f7f5359a3b3e, 0x096ee45813a04331}, + {0xfd87b5f28300ca0d, 0x8bca9d6e188853fd}, + {0x9e74d1b791e07e48, 0x775ea264cf55347e}, + {0xc612062576589dda, 0x95364afe032a819e}, + {0xf79687aed3eec551, 0x3a83ddbd83f52205}, + {0x9abe14cd44753b52, 0xc4926a9672793543}, + {0xc16d9a0095928a27, 0x75b7053c0f178294}, + {0xf1c90080baf72cb1, 0x5324c68b12dd6339}, + {0x971da05074da7bee, 0xd3f6fc16ebca5e04}, + {0xbce5086492111aea, 0x88f4bb1ca6bcf585}, + {0xec1e4a7db69561a5, 0x2b31e9e3d06c32e6}, + {0x9392ee8e921d5d07, 0x3aff322e62439fd0}, + {0xb877aa3236a4b449, 0x09befeb9fad487c3}, + {0xe69594bec44de15b, 0x4c2ebe687989a9b4}, + {0x901d7cf73ab0acd9, 0x0f9d37014bf60a11}, + {0xb424dc35095cd80f, 0x538484c19ef38c95}, + {0xe12e13424bb40e13, 0x2865a5f206b06fba}, + {0x8cbccc096f5088cb, 0xf93f87b7442e45d4}, + {0xafebff0bcb24aafe, 0xf78f69a51539d749}, + {0xdbe6fecebdedd5be, 0xb573440e5a884d1c}, + {0x89705f4136b4a597, 0x31680a88f8953031}, + {0xabcc77118461cefc, 0xfdc20d2b36ba7c3e}, + {0xd6bf94d5e57a42bc, 0x3d32907604691b4d}, + {0x8637bd05af6c69b5, 0xa63f9a49c2c1b110}, + {0xa7c5ac471b478423, 0x0fcf80dc33721d54}, + {0xd1b71758e219652b, 0xd3c36113404ea4a9}, + {0x83126e978d4fdf3b, 0x645a1cac083126ea}, + {0xa3d70a3d70a3d70a, 0x3d70a3d70a3d70a4}, + {0xcccccccccccccccc, 0xcccccccccccccccd}, + {0x8000000000000000, 0x0000000000000000}, + {0xa000000000000000, 0x0000000000000000}, + {0xc800000000000000, 0x0000000000000000}, + {0xfa00000000000000, 0x0000000000000000}, + {0x9c40000000000000, 0x0000000000000000}, + {0xc350000000000000, 0x0000000000000000}, + {0xf424000000000000, 0x0000000000000000}, + {0x9896800000000000, 0x0000000000000000}, + {0xbebc200000000000, 0x0000000000000000}, + {0xee6b280000000000, 0x0000000000000000}, + {0x9502f90000000000, 0x0000000000000000}, + {0xba43b74000000000, 0x0000000000000000}, + {0xe8d4a51000000000, 0x0000000000000000}, + {0x9184e72a00000000, 0x0000000000000000}, + {0xb5e620f480000000, 0x0000000000000000}, + {0xe35fa931a0000000, 0x0000000000000000}, + {0x8e1bc9bf04000000, 0x0000000000000000}, + {0xb1a2bc2ec5000000, 0x0000000000000000}, + {0xde0b6b3a76400000, 0x0000000000000000}, + {0x8ac7230489e80000, 0x0000000000000000}, + {0xad78ebc5ac620000, 0x0000000000000000}, + {0xd8d726b7177a8000, 0x0000000000000000}, + {0x878678326eac9000, 0x0000000000000000}, + {0xa968163f0a57b400, 0x0000000000000000}, + {0xd3c21bcecceda100, 0x0000000000000000}, + {0x84595161401484a0, 0x0000000000000000}, + {0xa56fa5b99019a5c8, 0x0000000000000000}, + {0xcecb8f27f4200f3a, 0x0000000000000000}, + {0x813f3978f8940984, 0x4000000000000000}, + {0xa18f07d736b90be5, 0x5000000000000000}, + {0xc9f2c9cd04674ede, 0xa400000000000000}, + {0xfc6f7c4045812296, 0x4d00000000000000}, + {0x9dc5ada82b70b59d, 0xf020000000000000}, + {0xc5371912364ce305, 0x6c28000000000000}, + {0xf684df56c3e01bc6, 0xc732000000000000}, + {0x9a130b963a6c115c, 0x3c7f400000000000}, + {0xc097ce7bc90715b3, 0x4b9f100000000000}, + {0xf0bdc21abb48db20, 0x1e86d40000000000}, + {0x96769950b50d88f4, 0x1314448000000000}, + {0xbc143fa4e250eb31, 0x17d955a000000000}, + {0xeb194f8e1ae525fd, 0x5dcfab0800000000}, + {0x92efd1b8d0cf37be, 0x5aa1cae500000000}, + {0xb7abc627050305ad, 0xf14a3d9e40000000}, + {0xe596b7b0c643c719, 0x6d9ccd05d0000000}, + {0x8f7e32ce7bea5c6f, 0xe4820023a2000000}, + {0xb35dbf821ae4f38b, 0xdda2802c8a800000}, + {0xe0352f62a19e306e, 0xd50b2037ad200000}, + {0x8c213d9da502de45, 0x4526f422cc340000}, + {0xaf298d050e4395d6, 0x9670b12b7f410000}, + {0xdaf3f04651d47b4c, 0x3c0cdd765f114000}, + {0x88d8762bf324cd0f, 0xa5880a69fb6ac800}, + {0xab0e93b6efee0053, 0x8eea0d047a457a00}, + {0xd5d238a4abe98068, 0x72a4904598d6d880}, + {0x85a36366eb71f041, 0x47a6da2b7f864750}, + {0xa70c3c40a64e6c51, 0x999090b65f67d924}, + {0xd0cf4b50cfe20765, 0xfff4b4e3f741cf6d}, + {0x82818f1281ed449f, 0xbff8f10e7a8921a4}, + {0xa321f2d7226895c7, 0xaff72d52192b6a0d}, + {0xcbea6f8ceb02bb39, 0x9bf4f8a69f764490}, + {0xfee50b7025c36a08, 0x02f236d04753d5b4}, + {0x9f4f2726179a2245, 0x01d762422c946590}, + {0xc722f0ef9d80aad6, 0x424d3ad2b7b97ef5}, + {0xf8ebad2b84e0d58b, 0xd2e0898765a7deb2}, + {0x9b934c3b330c8577, 0x63cc55f49f88eb2f}, + {0xc2781f49ffcfa6d5, 0x3cbf6b71c76b25fb}, + {0xf316271c7fc3908a, 0x8bef464e3945ef7a}, + {0x97edd871cfda3a56, 0x97758bf0e3cbb5ac}, + {0xbde94e8e43d0c8ec, 0x3d52eeed1cbea317}, + {0xed63a231d4c4fb27, 0x4ca7aaa863ee4bdd}, + {0x945e455f24fb1cf8, 0x8fe8caa93e74ef6a}, + {0xb975d6b6ee39e436, 0xb3e2fd538e122b44}, + {0xe7d34c64a9c85d44, 0x60dbbca87196b616}, + {0x90e40fbeea1d3a4a, 0xbc8955e946fe31cd}, + {0xb51d13aea4a488dd, 0x6babab6398bdbe41}, + {0xe264589a4dcdab14, 0xc696963c7eed2dd1}, + {0x8d7eb76070a08aec, 0xfc1e1de5cf543ca2}, + {0xb0de65388cc8ada8, 0x3b25a55f43294bcb}, + {0xdd15fe86affad912, 0x49ef0eb713f39ebe}, + {0x8a2dbf142dfcc7ab, 0x6e3569326c784337}, + {0xacb92ed9397bf996, 0x49c2c37f07965404}, + {0xd7e77a8f87daf7fb, 0xdc33745ec97be906}, + {0x86f0ac99b4e8dafd, 0x69a028bb3ded71a3}, + {0xa8acd7c0222311bc, 0xc40832ea0d68ce0c}, + {0xd2d80db02aabd62b, 0xf50a3fa490c30190}, + {0x83c7088e1aab65db, 0x792667c6da79e0fa}, + {0xa4b8cab1a1563f52, 0x577001b891185938}, + {0xcde6fd5e09abcf26, 0xed4c0226b55e6f86}, + {0x80b05e5ac60b6178, 0x544f8158315b05b4}, + {0xa0dc75f1778e39d6, 0x696361ae3db1c721}, + {0xc913936dd571c84c, 0x03bc3a19cd1e38e9}, + {0xfb5878494ace3a5f, 0x04ab48a04065c723}, + {0x9d174b2dcec0e47b, 0x62eb0d64283f9c76}, + {0xc45d1df942711d9a, 0x3ba5d0bd324f8394}, + {0xf5746577930d6500, 0xca8f44ec7ee36479}, + {0x9968bf6abbe85f20, 0x7e998b13cf4e1ecb}, + {0xbfc2ef456ae276e8, 0x9e3fedd8c321a67e}, + {0xefb3ab16c59b14a2, 0xc5cfe94ef3ea101e}, + {0x95d04aee3b80ece5, 0xbba1f1d158724a12}, + {0xbb445da9ca61281f, 0x2a8a6e45ae8edc97}, + {0xea1575143cf97226, 0xf52d09d71a3293bd}, + {0x924d692ca61be758, 0x593c2626705f9c56}, + {0xb6e0c377cfa2e12e, 0x6f8b2fb00c77836c}, + {0xe498f455c38b997a, 0x0b6dfb9c0f956447}, + {0x8edf98b59a373fec, 0x4724bd4189bd5eac}, + {0xb2977ee300c50fe7, 0x58edec91ec2cb657}, + {0xdf3d5e9bc0f653e1, 0x2f2967b66737e3ed}, + {0x8b865b215899f46c, 0xbd79e0d20082ee74}, + {0xae67f1e9aec07187, 0xecd8590680a3aa11}, + {0xda01ee641a708de9, 0xe80e6f4820cc9495}, + {0x884134fe908658b2, 0x3109058d147fdcdd}, + {0xaa51823e34a7eede, 0xbd4b46f0599fd415}, + {0xd4e5e2cdc1d1ea96, 0x6c9e18ac7007c91a}, + {0x850fadc09923329e, 0x03e2cf6bc604ddb0}, + {0xa6539930bf6bff45, 0x84db8346b786151c}, + {0xcfe87f7cef46ff16, 0xe612641865679a63}, + {0x81f14fae158c5f6e, 0x4fcb7e8f3f60c07e}, + {0xa26da3999aef7749, 0xe3be5e330f38f09d}, + {0xcb090c8001ab551c, 0x5cadf5bfd3072cc5}, + {0xfdcb4fa002162a63, 0x73d9732fc7c8f7f6}, + {0x9e9f11c4014dda7e, 0x2867e7fddcdd9afa}, + {0xc646d63501a1511d, 0xb281e1fd541501b8}, + {0xf7d88bc24209a565, 0x1f225a7ca91a4226}, + {0x9ae757596946075f, 0x3375788de9b06958}, + {0xc1a12d2fc3978937, 0x0052d6b1641c83ae}, + {0xf209787bb47d6b84, 0xc0678c5dbd23a49a}, + {0x9745eb4d50ce6332, 0xf840b7ba963646e0}, + {0xbd176620a501fbff, 0xb650e5a93bc3d898}, + {0xec5d3fa8ce427aff, 0xa3e51f138ab4cebe}, + {0x93ba47c980e98cdf, 0xc66f336c36b10137}, + {0xb8a8d9bbe123f017, 0xb80b0047445d4184}, + {0xe6d3102ad96cec1d, 0xa60dc059157491e5}, + {0x9043ea1ac7e41392, 0x87c89837ad68db2f}, + {0xb454e4a179dd1877, 0x29babe4598c311fb}, + {0xe16a1dc9d8545e94, 0xf4296dd6fef3d67a}, + {0x8ce2529e2734bb1d, 0x1899e4a65f58660c}, + {0xb01ae745b101e9e4, 0x5ec05dcff72e7f8f}, + {0xdc21a1171d42645d, 0x76707543f4fa1f73}, + {0x899504ae72497eba, 0x6a06494a791c53a8}, + {0xabfa45da0edbde69, 0x0487db9d17636892}, + {0xd6f8d7509292d603, 0x45a9d2845d3c42b6}, + {0x865b86925b9bc5c2, 0x0b8a2392ba45a9b2}, + {0xa7f26836f282b732, 0x8e6cac7768d7141e}, + {0xd1ef0244af2364ff, 0x3207d795430cd926}, + {0x8335616aed761f1f, 0x7f44e6bd49e807b8}, + {0xa402b9c5a8d3a6e7, 0x5f16206c9c6209a6}, + {0xcd036837130890a1, 0x36dba887c37a8c0f}, + {0x802221226be55a64, 0xc2494954da2c9789}, + {0xa02aa96b06deb0fd, 0xf2db9baa10b7bd6c}, + {0xc83553c5c8965d3d, 0x6f92829494e5acc7}, + {0xfa42a8b73abbf48c, 0xcb772339ba1f17f9}, + {0x9c69a97284b578d7, 0xff2a760414536efb}, + {0xc38413cf25e2d70d, 0xfef5138519684aba}, + {0xf46518c2ef5b8cd1, 0x7eb258665fc25d69}, + {0x98bf2f79d5993802, 0xef2f773ffbd97a61}, + {0xbeeefb584aff8603, 0xaafb550ffacfd8fa}, + {0xeeaaba2e5dbf6784, 0x95ba2a53f983cf38}, + {0x952ab45cfa97a0b2, 0xdd945a747bf26183}, + {0xba756174393d88df, 0x94f971119aeef9e4}, + {0xe912b9d1478ceb17, 0x7a37cd5601aab85d}, + {0x91abb422ccb812ee, 0xac62e055c10ab33a}, + {0xb616a12b7fe617aa, 0x577b986b314d6009}, + {0xe39c49765fdf9d94, 0xed5a7e85fda0b80b}, + {0x8e41ade9fbebc27d, 0x14588f13be847307}, + {0xb1d219647ae6b31c, 0x596eb2d8ae258fc8}, + {0xde469fbd99a05fe3, 0x6fca5f8ed9aef3bb}, + {0x8aec23d680043bee, 0x25de7bb9480d5854}, + {0xada72ccc20054ae9, 0xaf561aa79a10ae6a}, + {0xd910f7ff28069da4, 0x1b2ba1518094da04}, + {0x87aa9aff79042286, 0x90fb44d2f05d0842}, + {0xa99541bf57452b28, 0x353a1607ac744a53}, + {0xd3fa922f2d1675f2, 0x42889b8997915ce8}, + {0x847c9b5d7c2e09b7, 0x69956135febada11}, + {0xa59bc234db398c25, 0x43fab9837e699095}, + {0xcf02b2c21207ef2e, 0x94f967e45e03f4bb}, + {0x8161afb94b44f57d, 0x1d1be0eebac278f5}, + {0xa1ba1ba79e1632dc, 0x6462d92a69731732}, + {0xca28a291859bbf93, 0x7d7b8f7503cfdcfe}, + {0xfcb2cb35e702af78, 0x5cda735244c3d43e}, + {0x9defbf01b061adab, 0x3a0888136afa64a7}, + {0xc56baec21c7a1916, 0x088aaa1845b8fdd0}, + {0xf6c69a72a3989f5b, 0x8aad549e57273d45}, + {0x9a3c2087a63f6399, 0x36ac54e2f678864b}, + {0xc0cb28a98fcf3c7f, 0x84576a1bb416a7dd}, + {0xf0fdf2d3f3c30b9f, 0x656d44a2a11c51d5}, + {0x969eb7c47859e743, 0x9f644ae5a4b1b325}, + {0xbc4665b596706114, 0x873d5d9f0dde1fee}, + {0xeb57ff22fc0c7959, 0xa90cb506d155a7ea}, + {0x9316ff75dd87cbd8, 0x09a7f12442d588f2}, + {0xb7dcbf5354e9bece, 0x0c11ed6d538aeb2f}, + {0xe5d3ef282a242e81, 0x8f1668c8a86da5fa}, + {0x8fa475791a569d10, 0xf96e017d694487bc}, + {0xb38d92d760ec4455, 0x37c981dcc395a9ac}, + {0xe070f78d3927556a, 0x85bbe253f47b1417}, + {0x8c469ab843b89562, 0x93956d7478ccec8e}, + {0xaf58416654a6babb, 0x387ac8d1970027b2}, + {0xdb2e51bfe9d0696a, 0x06997b05fcc0319e}, + {0x88fcf317f22241e2, 0x441fece3bdf81f03}, + {0xab3c2fddeeaad25a, 0xd527e81cad7626c3}, + {0xd60b3bd56a5586f1, 0x8a71e223d8d3b074}, + {0x85c7056562757456, 0xf6872d5667844e49}, + {0xa738c6bebb12d16c, 0xb428f8ac016561db}, + {0xd106f86e69d785c7, 0xe13336d701beba52}, + {0x82a45b450226b39c, 0xecc0024661173473}, + {0xa34d721642b06084, 0x27f002d7f95d0190}, + {0xcc20ce9bd35c78a5, 0x31ec038df7b441f4}, + {0xff290242c83396ce, 0x7e67047175a15271}, + {0x9f79a169bd203e41, 0x0f0062c6e984d386}, + {0xc75809c42c684dd1, 0x52c07b78a3e60868}, + {0xf92e0c3537826145, 0xa7709a56ccdf8a82}, + {0x9bbcc7a142b17ccb, 0x88a66076400bb691}, + {0xc2abf989935ddbfe, 0x6acff893d00ea435}, + {0xf356f7ebf83552fe, 0x0583f6b8c4124d43}, + {0x98165af37b2153de, 0xc3727a337a8b704a}, + {0xbe1bf1b059e9a8d6, 0x744f18c0592e4c5c}, + {0xeda2ee1c7064130c, 0x1162def06f79df73}, + {0x9485d4d1c63e8be7, 0x8addcb5645ac2ba8}, + {0xb9a74a0637ce2ee1, 0x6d953e2bd7173692}, + {0xe8111c87c5c1ba99, 0xc8fa8db6ccdd0437}, + {0x910ab1d4db9914a0, 0x1d9c9892400a22a2}, + {0xb54d5e4a127f59c8, 0x2503beb6d00cab4b}, + {0xe2a0b5dc971f303a, 0x2e44ae64840fd61d}, + {0x8da471a9de737e24, 0x5ceaecfed289e5d2}, + {0xb10d8e1456105dad, 0x7425a83e872c5f47}, + {0xdd50f1996b947518, 0xd12f124e28f77719}, + {0x8a5296ffe33cc92f, 0x82bd6b70d99aaa6f}, + {0xace73cbfdc0bfb7b, 0x636cc64d1001550b}, + {0xd8210befd30efa5a, 0x3c47f7e05401aa4e}, + {0x8714a775e3e95c78, 0x65acfaec34810a71}, + {0xa8d9d1535ce3b396, 0x7f1839a741a14d0d}, + {0xd31045a8341ca07c, 0x1ede48111209a050}, + {0x83ea2b892091e44d, 0x934aed0aab460432}, + {0xa4e4b66b68b65d60, 0xf81da84d5617853f}, + {0xce1de40642e3f4b9, 0x36251260ab9d668e}, + {0x80d2ae83e9ce78f3, 0xc1d72b7c6b426019}, + {0xa1075a24e4421730, 0xb24cf65b8612f81f}, + {0xc94930ae1d529cfc, 0xdee033f26797b627}, + {0xfb9b7cd9a4a7443c, 0x169840ef017da3b1}, + {0x9d412e0806e88aa5, 0x8e1f289560ee864e}, + {0xc491798a08a2ad4e, 0xf1a6f2bab92a27e2}, + {0xf5b5d7ec8acb58a2, 0xae10af696774b1db}, + {0x9991a6f3d6bf1765, 0xacca6da1e0a8ef29}, + {0xbff610b0cc6edd3f, 0x17fd090a58d32af3}, + {0xeff394dcff8a948e, 0xddfc4b4cef07f5b0}, + {0x95f83d0a1fb69cd9, 0x4abdaf101564f98e}, + {0xbb764c4ca7a4440f, 0x9d6d1ad41abe37f1}, + {0xea53df5fd18d5513, 0x84c86189216dc5ed}, + {0x92746b9be2f8552c, 0x32fd3cf5b4e49bb4}, + {0xb7118682dbb66a77, 0x3fbc8c33221dc2a1}, + {0xe4d5e82392a40515, 0x0fabaf3feaa5334a}, + {0x8f05b1163ba6832d, 0x29cb4d87f2a7400e}, + {0xb2c71d5bca9023f8, 0x743e20e9ef511012}, + {0xdf78e4b2bd342cf6, 0x914da9246b255416}, + {0x8bab8eefb6409c1a, 0x1ad089b6c2f7548e}, + {0xae9672aba3d0c320, 0xa184ac2473b529b1}, + {0xda3c0f568cc4f3e8, 0xc9e5d72d90a2741e}, + {0x8865899617fb1871, 0x7e2fa67c7a658892}, + {0xaa7eebfb9df9de8d, 0xddbb901b98feeab7}, + {0xd51ea6fa85785631, 0x552a74227f3ea565}, + {0x8533285c936b35de, 0xd53a88958f87275f}, + {0xa67ff273b8460356, 0x8a892abaf368f137}, + {0xd01fef10a657842c, 0x2d2b7569b0432d85}, + {0x8213f56a67f6b29b, 0x9c3b29620e29fc73}, + {0xa298f2c501f45f42, 0x8349f3ba91b47b8f}, + {0xcb3f2f7642717713, 0x241c70a936219a73}, + {0xfe0efb53d30dd4d7, 0xed238cd383aa0110}, + {0x9ec95d1463e8a506, 0xf4363804324a40aa}, + {0xc67bb4597ce2ce48, 0xb143c6053edcd0d5}, + {0xf81aa16fdc1b81da, 0xdd94b7868e94050a}, + {0x9b10a4e5e9913128, 0xca7cf2b4191c8326}, + {0xc1d4ce1f63f57d72, 0xfd1c2f611f63a3f0}, + {0xf24a01a73cf2dccf, 0xbc633b39673c8cec}, + {0x976e41088617ca01, 0xd5be0503e085d813}, + {0xbd49d14aa79dbc82, 0x4b2d8644d8a74e18}, + {0xec9c459d51852ba2, 0xddf8e7d60ed1219e}, + {0x93e1ab8252f33b45, 0xcabb90e5c942b503}, + {0xb8da1662e7b00a17, 0x3d6a751f3b936243}, + {0xe7109bfba19c0c9d, 0x0cc512670a783ad4}, + {0x906a617d450187e2, 0x27fb2b80668b24c5}, + {0xb484f9dc9641e9da, 0xb1f9f660802dedf6}, + {0xe1a63853bbd26451, 0x5e7873f8a0396973}, + {0x8d07e33455637eb2, 0xdb0b487b6423e1e8}, + {0xb049dc016abc5e5f, 0x91ce1a9a3d2cda62}, + {0xdc5c5301c56b75f7, 0x7641a140cc7810fb}, + {0x89b9b3e11b6329ba, 0xa9e904c87fcb0a9d}, + {0xac2820d9623bf429, 0x546345fa9fbdcd44}, + {0xd732290fbacaf133, 0xa97c177947ad4095}, + {0x867f59a9d4bed6c0, 0x49ed8eabcccc485d}, + {0xa81f301449ee8c70, 0x5c68f256bfff5a74}, + {0xd226fc195c6a2f8c, 0x73832eec6fff3111}, + {0x83585d8fd9c25db7, 0xc831fd53c5ff7eab}, + {0xa42e74f3d032f525, 0xba3e7ca8b77f5e55}, + {0xcd3a1230c43fb26f, 0x28ce1bd2e55f35eb}, + {0x80444b5e7aa7cf85, 0x7980d163cf5b81b3}, + {0xa0555e361951c366, 0xd7e105bcc332621f}, + {0xc86ab5c39fa63440, 0x8dd9472bf3fefaa7}, + {0xfa856334878fc150, 0xb14f98f6f0feb951}, + {0x9c935e00d4b9d8d2, 0x6ed1bf9a569f33d3}, + {0xc3b8358109e84f07, 0x0a862f80ec4700c8}, + {0xf4a642e14c6262c8, 0xcd27bb612758c0fa}, + {0x98e7e9cccfbd7dbd, 0x8038d51cb897789c}, + {0xbf21e44003acdd2c, 0xe0470a63e6bd56c3}, + {0xeeea5d5004981478, 0x1858ccfce06cac74}, + {0x95527a5202df0ccb, 0x0f37801e0c43ebc8}, + {0xbaa718e68396cffd, 0xd30560258f54e6ba}, + {0xe950df20247c83fd, 0x47c6b82ef32a2069}, + {0x91d28b7416cdd27e, 0x4cdc331d57fa5441}, + {0xb6472e511c81471d, 0xe0133fe4adf8e952}, + {0xe3d8f9e563a198e5, 0x58180fddd97723a6}, + {0x8e679c2f5e44ff8f, 0x570f09eaa7ea7648}, + {0xb201833b35d63f73, 0x2cd2cc6551e513da}, + {0xde81e40a034bcf4f, 0xf8077f7ea65e58d1}, + {0x8b112e86420f6191, 0xfb04afaf27faf782}, + {0xadd57a27d29339f6, 0x79c5db9af1f9b563}, + {0xd94ad8b1c7380874, 0x18375281ae7822bc}, + {0x87cec76f1c830548, 0x8f2293910d0b15b5}, + {0xa9c2794ae3a3c69a, 0xb2eb3875504ddb22}, + {0xd433179d9c8cb841, 0x5fa60692a46151eb}, + {0x849feec281d7f328, 0xdbc7c41ba6bcd333}, + {0xa5c7ea73224deff3, 0x12b9b522906c0800}, + {0xcf39e50feae16bef, 0xd768226b34870a00}, + {0x81842f29f2cce375, 0xe6a1158300d46640}, + {0xa1e53af46f801c53, 0x60495ae3c1097fd0}, + {0xca5e89b18b602368, 0x385bb19cb14bdfc4}, + {0xfcf62c1dee382c42, 0x46729e03dd9ed7b5}, + {0x9e19db92b4e31ba9, 0x6c07a2c26a8346d1}, + {0xc5a05277621be293, 0xc7098b7305241885}, + { 0xf70867153aa2db38, + 0xb8cbee4fc66d1ea7 } +#else + {0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7b}, + {0xce5d73ff402d98e3, 0xfb0a3d212dc81290}, + {0xa6b34ad8c9dfc06f, 0xf42faa48c0ea481f}, + {0x86a8d39ef77164bc, 0xae5dff9c02033198}, + {0xd98ddaee19068c76, 0x3badd624dd9b0958}, + {0xafbd2350644eeacf, 0xe5d1929ef90898fb}, + {0x8df5efabc5979c8f, 0xca8d3ffa1ef463c2}, + {0xe55990879ddcaabd, 0xcc420a6a101d0516}, + {0xb94470938fa89bce, 0xf808e40e8d5b3e6a}, + {0x95a8637627989aad, 0xdde7001379a44aa9}, + {0xf1c90080baf72cb1, 0x5324c68b12dd6339}, + {0xc350000000000000, 0x0000000000000000}, + {0x9dc5ada82b70b59d, 0xf020000000000000}, + {0xfee50b7025c36a08, 0x02f236d04753d5b4}, + {0xcde6fd5e09abcf26, 0xed4c0226b55e6f86}, + {0xa6539930bf6bff45, 0x84db8346b786151c}, + {0x865b86925b9bc5c2, 0x0b8a2392ba45a9b2}, + {0xd910f7ff28069da4, 0x1b2ba1518094da04}, + {0xaf58416654a6babb, 0x387ac8d1970027b2}, + {0x8da471a9de737e24, 0x5ceaecfed289e5d2}, + {0xe4d5e82392a40515, 0x0fabaf3feaa5334a}, + {0xb8da1662e7b00a17, 0x3d6a751f3b936243}, + { 0x95527a5202df0ccb, + 0x0f37801e0c43ebc8 } +#endif + }; + +#if FMT_USE_FULL_CACHE_DRAGONBOX + return pow10_significands[k - float_info<double>::min_k]; +#else + static constexpr const uint64_t powers_of_5_64[] = { + 0x0000000000000001, 0x0000000000000005, 0x0000000000000019, + 0x000000000000007d, 0x0000000000000271, 0x0000000000000c35, + 0x0000000000003d09, 0x000000000001312d, 0x000000000005f5e1, + 0x00000000001dcd65, 0x00000000009502f9, 0x0000000002e90edd, + 0x000000000e8d4a51, 0x0000000048c27395, 0x000000016bcc41e9, + 0x000000071afd498d, 0x0000002386f26fc1, 0x000000b1a2bc2ec5, + 0x000003782dace9d9, 0x00001158e460913d, 0x000056bc75e2d631, + 0x0001b1ae4d6e2ef5, 0x000878678326eac9, 0x002a5a058fc295ed, + 0x00d3c21bcecceda1, 0x0422ca8b0a00a425, 0x14adf4b7320334b9}; + + static constexpr const uint32_t pow10_recovery_errors[] = { + 0x50001400, 0x54044100, 0x54014555, 0x55954415, 0x54115555, 0x00000001, + 0x50000000, 0x00104000, 0x54010004, 0x05004001, 0x55555544, 0x41545555, + 0x54040551, 0x15445545, 0x51555514, 0x10000015, 0x00101100, 0x01100015, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x04450514, 0x45414110, + 0x55555145, 0x50544050, 0x15040155, 0x11054140, 0x50111514, 0x11451454, + 0x00400541, 0x00000000, 0x55555450, 0x10056551, 0x10054011, 0x55551014, + 0x69514555, 0x05151109, 0x00155555}; + + static const int compression_ratio = 27; + + // Compute base index. + int cache_index = (k - float_info<double>::min_k) / compression_ratio; + int kb = cache_index * compression_ratio + float_info<double>::min_k; + int offset = k - kb; + + // Get base cache. + uint128_wrapper base_cache = pow10_significands[cache_index]; + if (offset == 0) return base_cache; + + // Compute the required amount of bit-shift. + int alpha = floor_log2_pow10(kb + offset) - floor_log2_pow10(kb) - offset; + FMT_ASSERT(alpha > 0 && alpha < 64, "shifting error detected"); + + // Try to recover the real cache. + uint64_t pow5 = powers_of_5_64[offset]; + uint128_wrapper recovered_cache = umul128(base_cache.high(), pow5); + uint128_wrapper middle_low = + umul128(base_cache.low() - (kb < 0 ? 1u : 0u), pow5); + + recovered_cache += middle_low.high(); + + uint64_t high_to_middle = recovered_cache.high() << (64 - alpha); + uint64_t middle_to_low = recovered_cache.low() << (64 - alpha); + + recovered_cache = + uint128_wrapper{(recovered_cache.low() >> alpha) | high_to_middle, + ((middle_low.low() >> alpha) | middle_to_low)}; + + if (kb < 0) recovered_cache += 1; + + // Get error. + int error_idx = (k - float_info<double>::min_k) / 16; + uint32_t error = (pow10_recovery_errors[error_idx] >> + ((k - float_info<double>::min_k) % 16) * 2) & + 0x3; + + // Add the error back. + FMT_ASSERT(recovered_cache.low() + error >= recovered_cache.low(), ""); + return {recovered_cache.high(), recovered_cache.low() + error}; +#endif + } + + static carrier_uint compute_mul(carrier_uint u, + const cache_entry_type& cache) FMT_NOEXCEPT { + return umul192_upper64(u, cache); + } + + static uint32_t compute_delta(cache_entry_type const& cache, + int beta_minus_1) FMT_NOEXCEPT { + return static_cast<uint32_t>(cache.high() >> (64 - 1 - beta_minus_1)); + } + + static bool compute_mul_parity(carrier_uint two_f, + const cache_entry_type& cache, + int beta_minus_1) FMT_NOEXCEPT { + FMT_ASSERT(beta_minus_1 >= 1, ""); + FMT_ASSERT(beta_minus_1 < 64, ""); + + return ((umul192_middle64(two_f, cache) >> (64 - beta_minus_1)) & 1) != 0; + } + + static carrier_uint compute_left_endpoint_for_shorter_interval_case( + const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT { + return (cache.high() - + (cache.high() >> (float_info<double>::significand_bits + 2))) >> + (64 - float_info<double>::significand_bits - 1 - beta_minus_1); + } + + static carrier_uint compute_right_endpoint_for_shorter_interval_case( + const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT { + return (cache.high() + + (cache.high() >> (float_info<double>::significand_bits + 1))) >> + (64 - float_info<double>::significand_bits - 1 - beta_minus_1); + } + + static carrier_uint compute_round_up_for_shorter_interval_case( + const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT { + return ((cache.high() >> + (64 - float_info<double>::significand_bits - 2 - beta_minus_1)) + + 1) / + 2; + } +}; + +// Various integer checks +template <class T> +bool is_left_endpoint_integer_shorter_interval(int exponent) FMT_NOEXCEPT { + return exponent >= + float_info< + T>::case_shorter_interval_left_endpoint_lower_threshold && + exponent <= + float_info<T>::case_shorter_interval_left_endpoint_upper_threshold; +} +template <class T> +bool is_endpoint_integer(typename float_info<T>::carrier_uint two_f, + int exponent, int minus_k) FMT_NOEXCEPT { + if (exponent < float_info<T>::case_fc_pm_half_lower_threshold) return false; + // For k >= 0. + if (exponent <= float_info<T>::case_fc_pm_half_upper_threshold) return true; + // For k < 0. + if (exponent > float_info<T>::divisibility_check_by_5_threshold) return false; + return divisible_by_power_of_5(two_f, minus_k); +} + +template <class T> +bool is_center_integer(typename float_info<T>::carrier_uint two_f, int exponent, + int minus_k) FMT_NOEXCEPT { + // Exponent for 5 is negative. + if (exponent > float_info<T>::divisibility_check_by_5_threshold) return false; + if (exponent > float_info<T>::case_fc_upper_threshold) + return divisible_by_power_of_5(two_f, minus_k); + // Both exponents are nonnegative. + if (exponent >= float_info<T>::case_fc_lower_threshold) return true; + // Exponent for 2 is negative. + return divisible_by_power_of_2(two_f, minus_k - exponent + 1); +} + +// Remove trailing zeros from n and return the number of zeros removed (float) +FMT_INLINE int remove_trailing_zeros(uint32_t& n) FMT_NOEXCEPT { +#ifdef FMT_BUILTIN_CTZ + int t = FMT_BUILTIN_CTZ(n); +#else + int t = ctz(n); +#endif + if (t > float_info<float>::max_trailing_zeros) + t = float_info<float>::max_trailing_zeros; + + const uint32_t mod_inv1 = 0xcccccccd; + const uint32_t max_quotient1 = 0x33333333; + const uint32_t mod_inv2 = 0xc28f5c29; + const uint32_t max_quotient2 = 0x0a3d70a3; + + int s = 0; + for (; s < t - 1; s += 2) { + if (n * mod_inv2 > max_quotient2) break; + n *= mod_inv2; + } + if (s < t && n * mod_inv1 <= max_quotient1) { + n *= mod_inv1; + ++s; + } + n >>= s; + return s; +} + +// Removes trailing zeros and returns the number of zeros removed (double) +FMT_INLINE int remove_trailing_zeros(uint64_t& n) FMT_NOEXCEPT { +#ifdef FMT_BUILTIN_CTZLL + int t = FMT_BUILTIN_CTZLL(n); +#else + int t = ctzll(n); +#endif + if (t > float_info<double>::max_trailing_zeros) + t = float_info<double>::max_trailing_zeros; + // Divide by 10^8 and reduce to 32-bits + // Since ret_value.significand <= (2^64 - 1) / 1000 < 10^17, + // both of the quotient and the r should fit in 32-bits + + const uint32_t mod_inv1 = 0xcccccccd; + const uint32_t max_quotient1 = 0x33333333; + const uint64_t mod_inv8 = 0xc767074b22e90e21; + const uint64_t max_quotient8 = 0x00002af31dc46118; + + // If the number is divisible by 1'0000'0000, work with the quotient + if (t >= 8) { + auto quotient_candidate = n * mod_inv8; + + if (quotient_candidate <= max_quotient8) { + auto quotient = static_cast<uint32_t>(quotient_candidate >> 8); + + int s = 8; + for (; s < t; ++s) { + if (quotient * mod_inv1 > max_quotient1) break; + quotient *= mod_inv1; + } + quotient >>= (s - 8); + n = quotient; + return s; + } + } + + // Otherwise, work with the remainder + auto quotient = static_cast<uint32_t>(n / 100000000); + auto remainder = static_cast<uint32_t>(n - 100000000 * quotient); + + if (t == 0 || remainder * mod_inv1 > max_quotient1) { + return 0; + } + remainder *= mod_inv1; + + if (t == 1 || remainder * mod_inv1 > max_quotient1) { + n = (remainder >> 1) + quotient * 10000000ull; + return 1; + } + remainder *= mod_inv1; + + if (t == 2 || remainder * mod_inv1 > max_quotient1) { + n = (remainder >> 2) + quotient * 1000000ull; + return 2; + } + remainder *= mod_inv1; + + if (t == 3 || remainder * mod_inv1 > max_quotient1) { + n = (remainder >> 3) + quotient * 100000ull; + return 3; + } + remainder *= mod_inv1; + + if (t == 4 || remainder * mod_inv1 > max_quotient1) { + n = (remainder >> 4) + quotient * 10000ull; + return 4; + } + remainder *= mod_inv1; + + if (t == 5 || remainder * mod_inv1 > max_quotient1) { + n = (remainder >> 5) + quotient * 1000ull; + return 5; + } + remainder *= mod_inv1; + + if (t == 6 || remainder * mod_inv1 > max_quotient1) { + n = (remainder >> 6) + quotient * 100ull; + return 6; + } + remainder *= mod_inv1; + + n = (remainder >> 7) + quotient * 10ull; + return 7; +} + +// The main algorithm for shorter interval case +template <class T> +FMT_INLINE decimal_fp<T> shorter_interval_case(int exponent) FMT_NOEXCEPT { + decimal_fp<T> ret_value; + // Compute k and beta + const int minus_k = floor_log10_pow2_minus_log10_4_over_3(exponent); + const int beta_minus_1 = exponent + floor_log2_pow10(-minus_k); + + // Compute xi and zi + using cache_entry_type = typename cache_accessor<T>::cache_entry_type; + const cache_entry_type cache = cache_accessor<T>::get_cached_power(-minus_k); + + auto xi = cache_accessor<T>::compute_left_endpoint_for_shorter_interval_case( + cache, beta_minus_1); + auto zi = cache_accessor<T>::compute_right_endpoint_for_shorter_interval_case( + cache, beta_minus_1); + + // If the left endpoint is not an integer, increase it + if (!is_left_endpoint_integer_shorter_interval<T>(exponent)) ++xi; + + // Try bigger divisor + ret_value.significand = zi / 10; + + // If succeed, remove trailing zeros if necessary and return + if (ret_value.significand * 10 >= xi) { + ret_value.exponent = minus_k + 1; + ret_value.exponent += remove_trailing_zeros(ret_value.significand); + return ret_value; + } + + // Otherwise, compute the round-up of y + ret_value.significand = + cache_accessor<T>::compute_round_up_for_shorter_interval_case( + cache, beta_minus_1); + ret_value.exponent = minus_k; + + // When tie occurs, choose one of them according to the rule + if (exponent >= float_info<T>::shorter_interval_tie_lower_threshold && + exponent <= float_info<T>::shorter_interval_tie_upper_threshold) { + ret_value.significand = ret_value.significand % 2 == 0 + ? ret_value.significand + : ret_value.significand - 1; + } else if (ret_value.significand < xi) { + ++ret_value.significand; + } + return ret_value; +} + +template <typename T> decimal_fp<T> to_decimal(T x) FMT_NOEXCEPT { + // Step 1: integer promotion & Schubfach multiplier calculation. + + using carrier_uint = typename float_info<T>::carrier_uint; + using cache_entry_type = typename cache_accessor<T>::cache_entry_type; + auto br = bit_cast<carrier_uint>(x); + + // Extract significand bits and exponent bits. + const carrier_uint significand_mask = + (static_cast<carrier_uint>(1) << float_info<T>::significand_bits) - 1; + carrier_uint significand = (br & significand_mask); + int exponent = static_cast<int>((br & exponent_mask<T>()) >> + float_info<T>::significand_bits); + + if (exponent != 0) { // Check if normal. + exponent += float_info<T>::exponent_bias - float_info<T>::significand_bits; + + // Shorter interval case; proceed like Schubfach. + if (significand == 0) return shorter_interval_case<T>(exponent); + + significand |= + (static_cast<carrier_uint>(1) << float_info<T>::significand_bits); + } else { + // Subnormal case; the interval is always regular. + if (significand == 0) return {0, 0}; + exponent = float_info<T>::min_exponent - float_info<T>::significand_bits; + } + + const bool include_left_endpoint = (significand % 2 == 0); + const bool include_right_endpoint = include_left_endpoint; + + // Compute k and beta. + const int minus_k = floor_log10_pow2(exponent) - float_info<T>::kappa; + const cache_entry_type cache = cache_accessor<T>::get_cached_power(-minus_k); + const int beta_minus_1 = exponent + floor_log2_pow10(-minus_k); + + // Compute zi and deltai + // 10^kappa <= deltai < 10^(kappa + 1) + const uint32_t deltai = cache_accessor<T>::compute_delta(cache, beta_minus_1); + const carrier_uint two_fc = significand << 1; + const carrier_uint two_fr = two_fc | 1; + const carrier_uint zi = + cache_accessor<T>::compute_mul(two_fr << beta_minus_1, cache); + + // Step 2: Try larger divisor; remove trailing zeros if necessary + + // Using an upper bound on zi, we might be able to optimize the division + // better than the compiler; we are computing zi / big_divisor here + decimal_fp<T> ret_value; + ret_value.significand = divide_by_10_to_kappa_plus_1(zi); + uint32_t r = static_cast<uint32_t>(zi - float_info<T>::big_divisor * + ret_value.significand); + + if (r > deltai) { + goto small_divisor_case_label; + } else if (r < deltai) { + // Exclude the right endpoint if necessary + if (r == 0 && !include_right_endpoint && + is_endpoint_integer<T>(two_fr, exponent, minus_k)) { + --ret_value.significand; + r = float_info<T>::big_divisor; + goto small_divisor_case_label; + } + } else { + // r == deltai; compare fractional parts + // Check conditions in the order different from the paper + // to take advantage of short-circuiting + const carrier_uint two_fl = two_fc - 1; + if ((!include_left_endpoint || + !is_endpoint_integer<T>(two_fl, exponent, minus_k)) && + !cache_accessor<T>::compute_mul_parity(two_fl, cache, beta_minus_1)) { + goto small_divisor_case_label; + } + } + ret_value.exponent = minus_k + float_info<T>::kappa + 1; + + // We may need to remove trailing zeros + ret_value.exponent += remove_trailing_zeros(ret_value.significand); + return ret_value; + + // Step 3: Find the significand with the smaller divisor + +small_divisor_case_label: + ret_value.significand *= 10; + ret_value.exponent = minus_k + float_info<T>::kappa; + + const uint32_t mask = (1u << float_info<T>::kappa) - 1; + auto dist = r - (deltai / 2) + (float_info<T>::small_divisor / 2); + + // Is dist divisible by 2^kappa? + if ((dist & mask) == 0) { + const bool approx_y_parity = + ((dist ^ (float_info<T>::small_divisor / 2)) & 1) != 0; + dist >>= float_info<T>::kappa; + + // Is dist divisible by 5^kappa? + if (check_divisibility_and_divide_by_pow5<float_info<T>::kappa>(dist)) { + ret_value.significand += dist; + + // Check z^(f) >= epsilon^(f) + // We have either yi == zi - epsiloni or yi == (zi - epsiloni) - 1, + // where yi == zi - epsiloni if and only if z^(f) >= epsilon^(f) + // Since there are only 2 possibilities, we only need to care about the + // parity. Also, zi and r should have the same parity since the divisor + // is an even number + if (cache_accessor<T>::compute_mul_parity(two_fc, cache, beta_minus_1) != + approx_y_parity) { + --ret_value.significand; + } else { + // If z^(f) >= epsilon^(f), we might have a tie + // when z^(f) == epsilon^(f), or equivalently, when y is an integer + if (is_center_integer<T>(two_fc, exponent, minus_k)) { + ret_value.significand = ret_value.significand % 2 == 0 + ? ret_value.significand + : ret_value.significand - 1; + } + } + } + // Is dist not divisible by 5^kappa? + else { + ret_value.significand += dist; + } + } + // Is dist not divisible by 2^kappa? + else { + // Since we know dist is small, we might be able to optimize the division + // better than the compiler; we are computing dist / small_divisor here + ret_value.significand += + small_division_by_pow10<float_info<T>::kappa>(dist); + } + return ret_value; +} +} // namespace dragonbox + +// Formats a floating-point number using a variation of the Fixed-Precision +// Positive Floating-Point Printout ((FPP)^2) algorithm by Steele & White: +// https://fmt.dev/papers/p372-steele.pdf. +FMT_CONSTEXPR20 inline void format_dragon(fp value, bool is_predecessor_closer, + int num_digits, buffer<char>& buf, + int& exp10) { + bigint numerator; // 2 * R in (FPP)^2. + bigint denominator; // 2 * S in (FPP)^2. + // lower and upper are differences between value and corresponding boundaries. + bigint lower; // (M^- in (FPP)^2). + bigint upper_store; // upper's value if different from lower. + bigint* upper = nullptr; // (M^+ in (FPP)^2). + // Shift numerator and denominator by an extra bit or two (if lower boundary + // is closer) to make lower and upper integers. This eliminates multiplication + // by 2 during later computations. + int shift = is_predecessor_closer ? 2 : 1; + uint64_t significand = value.f << shift; + if (value.e >= 0) { + numerator.assign(significand); + numerator <<= value.e; + lower.assign(1); + lower <<= value.e; + if (shift != 1) { + upper_store.assign(1); + upper_store <<= value.e + 1; + upper = &upper_store; + } + denominator.assign_pow10(exp10); + denominator <<= shift; + } else if (exp10 < 0) { + numerator.assign_pow10(-exp10); + lower.assign(numerator); + if (shift != 1) { + upper_store.assign(numerator); + upper_store <<= 1; + upper = &upper_store; + } + numerator *= significand; + denominator.assign(1); + denominator <<= shift - value.e; + } else { + numerator.assign(significand); + denominator.assign_pow10(exp10); + denominator <<= shift - value.e; + lower.assign(1); + if (shift != 1) { + upper_store.assign(1ULL << 1); + upper = &upper_store; + } + } + // Invariant: value == (numerator / denominator) * pow(10, exp10). + if (num_digits < 0) { + // Generate the shortest representation. + if (!upper) upper = &lower; + bool even = (value.f & 1) == 0; + num_digits = 0; + char* data = buf.data(); + for (;;) { + int digit = numerator.divmod_assign(denominator); + bool low = compare(numerator, lower) - even < 0; // numerator <[=] lower. + // numerator + upper >[=] pow10: + bool high = add_compare(numerator, *upper, denominator) + even > 0; + data[num_digits++] = static_cast<char>('0' + digit); + if (low || high) { + if (!low) { + ++data[num_digits - 1]; + } else if (high) { + int result = add_compare(numerator, numerator, denominator); + // Round half to even. + if (result > 0 || (result == 0 && (digit % 2) != 0)) + ++data[num_digits - 1]; + } + buf.try_resize(to_unsigned(num_digits)); + exp10 -= num_digits - 1; + return; + } + numerator *= 10; + lower *= 10; + if (upper != &lower) *upper *= 10; + } + } + // Generate the given number of digits. + exp10 -= num_digits - 1; + if (num_digits == 0) { + denominator *= 10; + auto digit = add_compare(numerator, numerator, denominator) > 0 ? '1' : '0'; + buf.push_back(digit); + return; + } + buf.try_resize(to_unsigned(num_digits)); + for (int i = 0; i < num_digits - 1; ++i) { + int digit = numerator.divmod_assign(denominator); + buf[i] = static_cast<char>('0' + digit); + numerator *= 10; + } + int digit = numerator.divmod_assign(denominator); + auto result = add_compare(numerator, numerator, denominator); + if (result > 0 || (result == 0 && (digit % 2) != 0)) { + if (digit == 9) { + const auto overflow = '0' + 10; + buf[num_digits - 1] = overflow; + // Propagate the carry. + for (int i = num_digits - 1; i > 0 && buf[i] == overflow; --i) { + buf[i] = '0'; + ++buf[i - 1]; + } + if (buf[0] == overflow) { + buf[0] = '1'; + ++exp10; + } + return; + } + ++digit; + } + buf[num_digits - 1] = static_cast<char>('0' + digit); +} + +template <typename Float> +FMT_HEADER_ONLY_CONSTEXPR20 int format_float(Float value, int precision, + float_specs specs, + buffer<char>& buf) { + // float is passed as double to reduce the number of instantiations. + static_assert(!std::is_same<Float, float>::value, ""); + FMT_ASSERT(value >= 0, "value is negative"); + + const bool fixed = specs.format == float_format::fixed; + if (value <= 0) { // <= instead of == to silence a warning. + if (precision <= 0 || !fixed) { + buf.push_back('0'); + return 0; + } + buf.try_resize(to_unsigned(precision)); + fill_n(buf.data(), precision, '0'); + return -precision; + } + + if (specs.fallback) return snprintf_float(value, precision, specs, buf); + + if (!is_constant_evaluated() && precision < 0) { + // Use Dragonbox for the shortest format. + if (specs.binary32) { + auto dec = dragonbox::to_decimal(static_cast<float>(value)); + write<char>(buffer_appender<char>(buf), dec.significand); + return dec.exponent; + } + auto dec = dragonbox::to_decimal(static_cast<double>(value)); + write<char>(buffer_appender<char>(buf), dec.significand); + return dec.exponent; + } + + int exp = 0; + bool use_dragon = true; + if (is_fast_float<Float>()) { + // Use Grisu + Dragon4 for the given precision: + // https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf. + const int min_exp = -60; // alpha in Grisu. + int cached_exp10 = 0; // K in Grisu. + fp normalized = normalize(fp(value)); + const auto cached_pow = get_cached_power( + min_exp - (normalized.e + fp::num_significand_bits), cached_exp10); + normalized = normalized * cached_pow; + gen_digits_handler handler{buf.data(), 0, precision, -cached_exp10, fixed}; + if (grisu_gen_digits(normalized, 1, exp, handler) != digits::error && + !is_constant_evaluated()) { + exp += handler.exp10; + buf.try_resize(to_unsigned(handler.size)); + use_dragon = false; + } else { + exp += handler.size - cached_exp10 - 1; + precision = handler.precision; + } + } + if (use_dragon) { + auto f = fp(); + bool is_predecessor_closer = + specs.binary32 ? f.assign(static_cast<float>(value)) : f.assign(value); + // Limit precision to the maximum possible number of significant digits in + // an IEEE754 double because we don't need to generate zeros. + const int max_double_digits = 767; + if (precision > max_double_digits) precision = max_double_digits; + format_dragon(f, is_predecessor_closer, precision, buf, exp); + } + if (!fixed && !specs.showpoint) { + // Remove trailing zeros. + auto num_digits = buf.size(); + while (num_digits > 0 && buf[num_digits - 1] == '0') { + --num_digits; + ++exp; + } + buf.try_resize(num_digits); + } + return exp; +} + +template <typename T> +int snprintf_float(T value, int precision, float_specs specs, + buffer<char>& buf) { + // Buffer capacity must be non-zero, otherwise MSVC's vsnprintf_s will fail. + FMT_ASSERT(buf.capacity() > buf.size(), "empty buffer"); + static_assert(!std::is_same<T, float>::value, ""); + + // Subtract 1 to account for the difference in precision since we use %e for + // both general and exponent format. + if (specs.format == float_format::general || + specs.format == float_format::exp) + precision = (precision >= 0 ? precision : 6) - 1; + + // Build the format string. + enum { max_format_size = 7 }; // The longest format is "%#.*Le". + char format[max_format_size]; + char* format_ptr = format; + *format_ptr++ = '%'; + if (specs.showpoint && specs.format == float_format::hex) *format_ptr++ = '#'; + if (precision >= 0) { + *format_ptr++ = '.'; + *format_ptr++ = '*'; + } + if (std::is_same<T, long double>()) *format_ptr++ = 'L'; + *format_ptr++ = specs.format != float_format::hex + ? (specs.format == float_format::fixed ? 'f' : 'e') + : (specs.upper ? 'A' : 'a'); + *format_ptr = '\0'; + + // Format using snprintf. + auto offset = buf.size(); + for (;;) { + auto begin = buf.data() + offset; + auto capacity = buf.capacity() - offset; +#ifdef FMT_FUZZ + if (precision > 100000) + throw std::runtime_error( + "fuzz mode - avoid large allocation inside snprintf"); +#endif + // Suppress the warning about a nonliteral format string. + // Cannot use auto because of a bug in MinGW (#1532). + int (*snprintf_ptr)(char*, size_t, const char*, ...) = FMT_SNPRINTF; + int result = precision >= 0 + ? snprintf_ptr(begin, capacity, format, precision, value) + : snprintf_ptr(begin, capacity, format, value); + if (result < 0) { + // The buffer will grow exponentially. + buf.try_reserve(buf.capacity() + 1); + continue; + } + auto size = to_unsigned(result); + // Size equal to capacity means that the last character was truncated. + if (size >= capacity) { + buf.try_reserve(size + offset + 1); // Add 1 for the terminating '\0'. + continue; + } + auto is_digit = [](char c) { return c >= '0' && c <= '9'; }; + if (specs.format == float_format::fixed) { + if (precision == 0) { + buf.try_resize(size); + return 0; + } + // Find and remove the decimal point. + auto end = begin + size, p = end; + do { + --p; + } while (is_digit(*p)); + int fraction_size = static_cast<int>(end - p - 1); + std::memmove(p, p + 1, to_unsigned(fraction_size)); + buf.try_resize(size - 1); + return -fraction_size; + } + if (specs.format == float_format::hex) { + buf.try_resize(size + offset); + return 0; + } + // Find and parse the exponent. + auto end = begin + size, exp_pos = end; + do { + --exp_pos; + } while (*exp_pos != 'e'); + char sign = exp_pos[1]; + FMT_ASSERT(sign == '+' || sign == '-', ""); + int exp = 0; + auto p = exp_pos + 2; // Skip 'e' and sign. + do { + FMT_ASSERT(is_digit(*p), ""); + exp = exp * 10 + (*p++ - '0'); + } while (p != end); + if (sign == '-') exp = -exp; + int fraction_size = 0; + if (exp_pos != begin + 1) { + // Remove trailing zeros. + auto fraction_end = exp_pos - 1; + while (*fraction_end == '0') --fraction_end; + // Move the fractional part left to get rid of the decimal point. + fraction_size = static_cast<int>(fraction_end - begin - 1); + std::memmove(begin + 1, begin + 2, to_unsigned(fraction_size)); + } + buf.try_resize(to_unsigned(fraction_size) + offset + 1); + return exp - fraction_size; + } +} +} // namespace detail + +template <> struct formatter<detail::bigint> { + FMT_CONSTEXPR format_parse_context::iterator parse( + format_parse_context& ctx) { + return ctx.begin(); + } + + format_context::iterator format(const detail::bigint& n, + format_context& ctx) { + auto out = ctx.out(); + bool first = true; + for (auto i = n.bigits_.size(); i > 0; --i) { + auto value = n.bigits_[i - 1u]; + if (first) { + out = format_to(out, FMT_STRING("{:x}"), value); + first = false; + continue; + } + out = format_to(out, FMT_STRING("{:08x}"), value); + } + if (n.exp_ > 0) + out = format_to(out, FMT_STRING("p{}"), + n.exp_ * detail::bigint::bigit_bits); + return out; + } +}; + +FMT_FUNC detail::utf8_to_utf16::utf8_to_utf16(string_view s) { + for_each_codepoint(s, [this](uint32_t cp, string_view) { + if (cp == invalid_code_point) FMT_THROW(std::runtime_error("invalid utf8")); + if (cp <= 0xFFFF) { + buffer_.push_back(static_cast<wchar_t>(cp)); + } else { + cp -= 0x10000; + buffer_.push_back(static_cast<wchar_t>(0xD800 + (cp >> 10))); + buffer_.push_back(static_cast<wchar_t>(0xDC00 + (cp & 0x3FF))); + } + return true; + }); + buffer_.push_back(0); +} + +FMT_FUNC void format_system_error(detail::buffer<char>& out, int error_code, + const char* message) FMT_NOEXCEPT { + FMT_TRY { + auto ec = std::error_code(error_code, std::generic_category()); + write(std::back_inserter(out), std::system_error(ec, message).what()); + return; + } + FMT_CATCH(...) {} + format_error_code(out, error_code, message); +} + +FMT_FUNC void report_system_error(int error_code, + const char* message) FMT_NOEXCEPT { + report_error(format_system_error, error_code, message); +} + +// DEPRECATED! +// This function is defined here and not inline for ABI compatiblity. +FMT_FUNC void detail::error_handler::on_error(const char* message) { + throw_format_error(message); +} + +FMT_FUNC std::string vformat(string_view fmt, format_args args) { + // Don't optimize the "{}" case to keep the binary size small and because it + // can be better optimized in fmt::format anyway. + auto buffer = memory_buffer(); + detail::vformat_to(buffer, fmt, args); + return to_string(buffer); +} + +#ifdef _WIN32 +namespace detail { +using dword = conditional_t<sizeof(long) == 4, unsigned long, unsigned>; +extern "C" __declspec(dllimport) int __stdcall WriteConsoleW( // + void*, const void*, dword, dword*, void*); +} // namespace detail +#endif + +namespace detail { +FMT_FUNC void print(std::FILE* f, string_view text) { +#ifdef _WIN32 + auto fd = _fileno(f); + if (_isatty(fd)) { + detail::utf8_to_utf16 u16(string_view(text.data(), text.size())); + auto written = detail::dword(); + if (detail::WriteConsoleW(reinterpret_cast<void*>(_get_osfhandle(fd)), + u16.c_str(), static_cast<uint32_t>(u16.size()), + &written, nullptr)) { + return; + } + // Fallback to fwrite on failure. It can happen if the output has been + // redirected to NUL. + } +#endif + detail::fwrite_fully(text.data(), 1, text.size(), f); +} +} // namespace detail + +FMT_FUNC void vprint(std::FILE* f, string_view format_str, format_args args) { + memory_buffer buffer; + detail::vformat_to(buffer, format_str, args); + detail::print(f, {buffer.data(), buffer.size()}); +} + +#ifdef _WIN32 +// Print assuming legacy (non-Unicode) encoding. +FMT_FUNC void detail::vprint_mojibake(std::FILE* f, string_view format_str, + format_args args) { + memory_buffer buffer; + detail::vformat_to(buffer, format_str, + basic_format_args<buffer_context<char>>(args)); + fwrite_fully(buffer.data(), 1, buffer.size(), f); +} +#endif + +FMT_FUNC void vprint(string_view format_str, format_args args) { + vprint(stdout, format_str, args); +} + +FMT_END_NAMESPACE + +#endif // FMT_FORMAT_INL_H_ diff --git a/extern/fmtlib/include/fmt/format.h b/extern/fmtlib/include/fmt/format.h new file mode 100644 index 00000000000..ee69651ca54 --- /dev/null +++ b/extern/fmtlib/include/fmt/format.h @@ -0,0 +1,3104 @@ +/* + Formatting library for C++ + + Copyright (c) 2012 - present, Victor Zverovich + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + --- Optional exception to the license --- + + As an exception, if, as a result of your compiling your source code, portions + of this Software are embedded into a machine-executable object form of such + source code, you may redistribute such embedded portions in such object form + without including the above copyright and permission notices. + */ + +#ifndef FMT_FORMAT_H_ +#define FMT_FORMAT_H_ + +#include <cmath> // std::signbit +#include <cstdint> // uint32_t +#include <limits> // std::numeric_limits +#include <memory> // std::uninitialized_copy +#include <stdexcept> // std::runtime_error +#include <system_error> // std::system_error +#include <utility> // std::swap + +#ifdef __cpp_lib_bit_cast +# include <bit> // std::bitcast +#endif + +#include "core.h" + +#if FMT_GCC_VERSION +# define FMT_GCC_VISIBILITY_HIDDEN __attribute__((visibility("hidden"))) +#else +# define FMT_GCC_VISIBILITY_HIDDEN +#endif + +#ifdef __NVCC__ +# define FMT_CUDA_VERSION (__CUDACC_VER_MAJOR__ * 100 + __CUDACC_VER_MINOR__) +#else +# define FMT_CUDA_VERSION 0 +#endif + +#ifdef __has_builtin +# define FMT_HAS_BUILTIN(x) __has_builtin(x) +#else +# define FMT_HAS_BUILTIN(x) 0 +#endif + +#if FMT_GCC_VERSION || FMT_CLANG_VERSION +# define FMT_NOINLINE __attribute__((noinline)) +#else +# define FMT_NOINLINE +#endif + +#if FMT_MSC_VER +# define FMT_MSC_DEFAULT = default +#else +# define FMT_MSC_DEFAULT +#endif + +#ifndef FMT_THROW +# if FMT_EXCEPTIONS +# if FMT_MSC_VER || FMT_NVCC +FMT_BEGIN_NAMESPACE +namespace detail { +template <typename Exception> inline void do_throw(const Exception& x) { + // Silence unreachable code warnings in MSVC and NVCC because these + // are nearly impossible to fix in a generic code. + volatile bool b = true; + if (b) throw x; +} +} // namespace detail +FMT_END_NAMESPACE +# define FMT_THROW(x) detail::do_throw(x) +# else +# define FMT_THROW(x) throw x +# endif +# else +# define FMT_THROW(x) \ + do { \ + FMT_ASSERT(false, (x).what()); \ + } while (false) +# endif +#endif + +#if FMT_EXCEPTIONS +# define FMT_TRY try +# define FMT_CATCH(x) catch (x) +#else +# define FMT_TRY if (true) +# define FMT_CATCH(x) if (false) +#endif + +#ifndef FMT_MAYBE_UNUSED +# if FMT_HAS_CPP17_ATTRIBUTE(maybe_unused) +# define FMT_MAYBE_UNUSED [[maybe_unused]] +# else +# define FMT_MAYBE_UNUSED +# endif +#endif + +// Workaround broken [[deprecated]] in the Intel, PGI and NVCC compilers. +#if FMT_ICC_VERSION || defined(__PGI) || FMT_NVCC +# define FMT_DEPRECATED_ALIAS +#else +# define FMT_DEPRECATED_ALIAS FMT_DEPRECATED +#endif + +#ifndef FMT_USE_USER_DEFINED_LITERALS +// EDG based compilers (Intel, NVIDIA, Elbrus, etc), GCC and MSVC support UDLs. +# if (FMT_HAS_FEATURE(cxx_user_literals) || FMT_GCC_VERSION >= 407 || \ + FMT_MSC_VER >= 1900) && \ + (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= /* UDL feature */ 480) +# define FMT_USE_USER_DEFINED_LITERALS 1 +# else +# define FMT_USE_USER_DEFINED_LITERALS 0 +# endif +#endif + +// Defining FMT_REDUCE_INT_INSTANTIATIONS to 1, will reduce the number of +// integer formatter template instantiations to just one by only using the +// largest integer type. This results in a reduction in binary size but will +// cause a decrease in integer formatting performance. +#if !defined(FMT_REDUCE_INT_INSTANTIATIONS) +# define FMT_REDUCE_INT_INSTANTIATIONS 0 +#endif + +// __builtin_clz is broken in clang with Microsoft CodeGen: +// https://github.com/fmtlib/fmt/issues/519. +#if !FMT_MSC_VER +# if FMT_HAS_BUILTIN(__builtin_clz) || FMT_GCC_VERSION || FMT_ICC_VERSION +# define FMT_BUILTIN_CLZ(n) __builtin_clz(n) +# endif +# if FMT_HAS_BUILTIN(__builtin_clzll) || FMT_GCC_VERSION || FMT_ICC_VERSION +# define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n) +# endif +#endif + +// __builtin_ctz is broken in Intel Compiler Classic on Windows: +// https://github.com/fmtlib/fmt/issues/2510. +#ifndef __ICL +# if FMT_HAS_BUILTIN(__builtin_ctz) || FMT_GCC_VERSION || FMT_ICC_VERSION +# define FMT_BUILTIN_CTZ(n) __builtin_ctz(n) +# endif +# if FMT_HAS_BUILTIN(__builtin_ctzll) || FMT_GCC_VERSION || FMT_ICC_VERSION +# define FMT_BUILTIN_CTZLL(n) __builtin_ctzll(n) +# endif +#endif + +#if FMT_MSC_VER +# include <intrin.h> // _BitScanReverse[64], _BitScanForward[64], _umul128 +#endif + +// Some compilers masquerade as both MSVC and GCC-likes or otherwise support +// __builtin_clz and __builtin_clzll, so only define FMT_BUILTIN_CLZ using the +// MSVC intrinsics if the clz and clzll builtins are not available. +#if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL) && !defined(FMT_BUILTIN_CTZLL) +FMT_BEGIN_NAMESPACE +namespace detail { +// Avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning. +# if !defined(__clang__) +# pragma intrinsic(_BitScanForward) +# pragma intrinsic(_BitScanReverse) +# if defined(_WIN64) +# pragma intrinsic(_BitScanForward64) +# pragma intrinsic(_BitScanReverse64) +# endif +# endif + +inline auto clz(uint32_t x) -> int { + unsigned long r = 0; + _BitScanReverse(&r, x); + FMT_ASSERT(x != 0, ""); + // Static analysis complains about using uninitialized data + // "r", but the only way that can happen is if "x" is 0, + // which the callers guarantee to not happen. + FMT_MSC_WARNING(suppress : 6102) + return 31 ^ static_cast<int>(r); +} +# define FMT_BUILTIN_CLZ(n) detail::clz(n) + +inline auto clzll(uint64_t x) -> int { + unsigned long r = 0; +# ifdef _WIN64 + _BitScanReverse64(&r, x); +# else + // Scan the high 32 bits. + if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32))) return 63 ^ (r + 32); + // Scan the low 32 bits. + _BitScanReverse(&r, static_cast<uint32_t>(x)); +# endif + FMT_ASSERT(x != 0, ""); + FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning. + return 63 ^ static_cast<int>(r); +} +# define FMT_BUILTIN_CLZLL(n) detail::clzll(n) + +inline auto ctz(uint32_t x) -> int { + unsigned long r = 0; + _BitScanForward(&r, x); + FMT_ASSERT(x != 0, ""); + FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning. + return static_cast<int>(r); +} +# define FMT_BUILTIN_CTZ(n) detail::ctz(n) + +inline auto ctzll(uint64_t x) -> int { + unsigned long r = 0; + FMT_ASSERT(x != 0, ""); + FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning. +# ifdef _WIN64 + _BitScanForward64(&r, x); +# else + // Scan the low 32 bits. + if (_BitScanForward(&r, static_cast<uint32_t>(x))) return static_cast<int>(r); + // Scan the high 32 bits. + _BitScanForward(&r, static_cast<uint32_t>(x >> 32)); + r += 32; +# endif + return static_cast<int>(r); +} +# define FMT_BUILTIN_CTZLL(n) detail::ctzll(n) +} // namespace detail +FMT_END_NAMESPACE +#endif + +#ifdef FMT_HEADER_ONLY +# define FMT_HEADER_ONLY_CONSTEXPR20 FMT_CONSTEXPR20 +#else +# define FMT_HEADER_ONLY_CONSTEXPR20 +#endif + +FMT_BEGIN_NAMESPACE +namespace detail { + +template <typename Streambuf> class formatbuf : public Streambuf { + private: + using char_type = typename Streambuf::char_type; + using streamsize = decltype(std::declval<Streambuf>().sputn(nullptr, 0)); + using int_type = typename Streambuf::int_type; + using traits_type = typename Streambuf::traits_type; + + buffer<char_type>& buffer_; + + public: + explicit formatbuf(buffer<char_type>& buf) : buffer_(buf) {} + + protected: + // The put area is always empty. This makes the implementation simpler and has + // the advantage that the streambuf and the buffer are always in sync and + // sputc never writes into uninitialized memory. A disadvantage is that each + // call to sputc always results in a (virtual) call to overflow. There is no + // disadvantage here for sputn since this always results in a call to xsputn. + + auto overflow(int_type ch) -> int_type override { + if (!traits_type::eq_int_type(ch, traits_type::eof())) + buffer_.push_back(static_cast<char_type>(ch)); + return ch; + } + + auto xsputn(const char_type* s, streamsize count) -> streamsize override { + buffer_.append(s, s + count); + return count; + } +}; + +// Implementation of std::bit_cast for pre-C++20. +template <typename To, typename From> +FMT_CONSTEXPR20 auto bit_cast(const From& from) -> To { + static_assert(sizeof(To) == sizeof(From), "size mismatch"); +#ifdef __cpp_lib_bit_cast + if (is_constant_evaluated()) return std::bit_cast<To>(from); +#endif + auto to = To(); + std::memcpy(&to, &from, sizeof(to)); + return to; +} + +inline auto is_big_endian() -> bool { +#ifdef _WIN32 + return false; +#elif defined(__BIG_ENDIAN__) + return true; +#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) + return __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__; +#else + struct bytes { + char data[sizeof(int)]; + }; + return bit_cast<bytes>(1).data[0] == 0; +#endif +} + +// A fallback implementation of uintptr_t for systems that lack it. +struct fallback_uintptr { + unsigned char value[sizeof(void*)]; + + fallback_uintptr() = default; + explicit fallback_uintptr(const void* p) { + *this = bit_cast<fallback_uintptr>(p); + if (const_check(is_big_endian())) { + for (size_t i = 0, j = sizeof(void*) - 1; i < j; ++i, --j) + std::swap(value[i], value[j]); + } + } +}; +#ifdef UINTPTR_MAX +using uintptr_t = ::uintptr_t; +inline auto to_uintptr(const void* p) -> uintptr_t { + return bit_cast<uintptr_t>(p); +} +#else +using uintptr_t = fallback_uintptr; +inline auto to_uintptr(const void* p) -> fallback_uintptr { + return fallback_uintptr(p); +} +#endif + +// Returns the largest possible value for type T. Same as +// std::numeric_limits<T>::max() but shorter and not affected by the max macro. +template <typename T> constexpr auto max_value() -> T { + return (std::numeric_limits<T>::max)(); +} +template <typename T> constexpr auto num_bits() -> int { + return std::numeric_limits<T>::digits; +} +// std::numeric_limits<T>::digits may return 0 for 128-bit ints. +template <> constexpr auto num_bits<int128_t>() -> int { return 128; } +template <> constexpr auto num_bits<uint128_t>() -> int { return 128; } +template <> constexpr auto num_bits<fallback_uintptr>() -> int { + return static_cast<int>(sizeof(void*) * + std::numeric_limits<unsigned char>::digits); +} + +FMT_INLINE void assume(bool condition) { + (void)condition; +#if FMT_HAS_BUILTIN(__builtin_assume) + __builtin_assume(condition); +#endif +} + +// An approximation of iterator_t for pre-C++20 systems. +template <typename T> +using iterator_t = decltype(std::begin(std::declval<T&>())); +template <typename T> using sentinel_t = decltype(std::end(std::declval<T&>())); + +// A workaround for std::string not having mutable data() until C++17. +template <typename Char> +inline auto get_data(std::basic_string<Char>& s) -> Char* { + return &s[0]; +} +template <typename Container> +inline auto get_data(Container& c) -> typename Container::value_type* { + return c.data(); +} + +#if defined(_SECURE_SCL) && _SECURE_SCL +// Make a checked iterator to avoid MSVC warnings. +template <typename T> using checked_ptr = stdext::checked_array_iterator<T*>; +template <typename T> +constexpr auto make_checked(T* p, size_t size) -> checked_ptr<T> { + return {p, size}; +} +#else +template <typename T> using checked_ptr = T*; +template <typename T> constexpr auto make_checked(T* p, size_t) -> T* { + return p; +} +#endif + +// Attempts to reserve space for n extra characters in the output range. +// Returns a pointer to the reserved range or a reference to it. +template <typename Container, FMT_ENABLE_IF(is_contiguous<Container>::value)> +#if FMT_CLANG_VERSION >= 307 && !FMT_ICC_VERSION +__attribute__((no_sanitize("undefined"))) +#endif +inline auto +reserve(std::back_insert_iterator<Container> it, size_t n) + -> checked_ptr<typename Container::value_type> { + Container& c = get_container(it); + size_t size = c.size(); + c.resize(size + n); + return make_checked(get_data(c) + size, n); +} + +template <typename T> +inline auto reserve(buffer_appender<T> it, size_t n) -> buffer_appender<T> { + buffer<T>& buf = get_container(it); + buf.try_reserve(buf.size() + n); + return it; +} + +template <typename Iterator> +constexpr auto reserve(Iterator& it, size_t) -> Iterator& { + return it; +} + +template <typename OutputIt> +using reserve_iterator = + remove_reference_t<decltype(reserve(std::declval<OutputIt&>(), 0))>; + +template <typename T, typename OutputIt> +constexpr auto to_pointer(OutputIt, size_t) -> T* { + return nullptr; +} +template <typename T> auto to_pointer(buffer_appender<T> it, size_t n) -> T* { + buffer<T>& buf = get_container(it); + auto size = buf.size(); + if (buf.capacity() < size + n) return nullptr; + buf.try_resize(size + n); + return buf.data() + size; +} + +template <typename Container, FMT_ENABLE_IF(is_contiguous<Container>::value)> +inline auto base_iterator(std::back_insert_iterator<Container>& it, + checked_ptr<typename Container::value_type>) + -> std::back_insert_iterator<Container> { + return it; +} + +template <typename Iterator> +constexpr auto base_iterator(Iterator, Iterator it) -> Iterator { + return it; +} + +// <algorithm> is spectacularly slow to compile in C++20 so use a simple fill_n +// instead (#1998). +template <typename OutputIt, typename Size, typename T> +FMT_CONSTEXPR auto fill_n(OutputIt out, Size count, const T& value) + -> OutputIt { + for (Size i = 0; i < count; ++i) *out++ = value; + return out; +} +template <typename T, typename Size> +FMT_CONSTEXPR20 auto fill_n(T* out, Size count, char value) -> T* { + if (is_constant_evaluated()) { + return fill_n<T*, Size, T>(out, count, value); + } + std::memset(out, value, to_unsigned(count)); + return out + count; +} + +#ifdef __cpp_char8_t +using char8_type = char8_t; +#else +enum char8_type : unsigned char {}; +#endif + +template <typename OutChar, typename InputIt, typename OutputIt> +FMT_CONSTEXPR FMT_NOINLINE auto copy_str_noinline(InputIt begin, InputIt end, + OutputIt out) -> OutputIt { + return copy_str<OutChar>(begin, end, out); +} + +// A public domain branchless UTF-8 decoder by Christopher Wellons: +// https://github.com/skeeto/branchless-utf8 +/* Decode the next character, c, from s, reporting errors in e. + * + * Since this is a branchless decoder, four bytes will be read from the + * buffer regardless of the actual length of the next character. This + * means the buffer _must_ have at least three bytes of zero padding + * following the end of the data stream. + * + * Errors are reported in e, which will be non-zero if the parsed + * character was somehow invalid: invalid byte sequence, non-canonical + * encoding, or a surrogate half. + * + * The function returns a pointer to the next character. When an error + * occurs, this pointer will be a guess that depends on the particular + * error, but it will always advance at least one byte. + */ +FMT_CONSTEXPR inline auto utf8_decode(const char* s, uint32_t* c, int* e) + -> const char* { + constexpr const int masks[] = {0x00, 0x7f, 0x1f, 0x0f, 0x07}; + constexpr const uint32_t mins[] = {4194304, 0, 128, 2048, 65536}; + constexpr const int shiftc[] = {0, 18, 12, 6, 0}; + constexpr const int shifte[] = {0, 6, 4, 2, 0}; + + int len = code_point_length(s); + const char* next = s + len; + + // Assume a four-byte character and load four bytes. Unused bits are + // shifted out. + *c = uint32_t(s[0] & masks[len]) << 18; + *c |= uint32_t(s[1] & 0x3f) << 12; + *c |= uint32_t(s[2] & 0x3f) << 6; + *c |= uint32_t(s[3] & 0x3f) << 0; + *c >>= shiftc[len]; + + // Accumulate the various error conditions. + using uchar = unsigned char; + *e = (*c < mins[len]) << 6; // non-canonical encoding + *e |= ((*c >> 11) == 0x1b) << 7; // surrogate half? + *e |= (*c > 0x10FFFF) << 8; // out of range? + *e |= (uchar(s[1]) & 0xc0) >> 2; + *e |= (uchar(s[2]) & 0xc0) >> 4; + *e |= uchar(s[3]) >> 6; + *e ^= 0x2a; // top two bits of each tail byte correct? + *e >>= shifte[len]; + + return next; +} + +constexpr uint32_t invalid_code_point = ~uint32_t(); + +// Invokes f(cp, sv) for every code point cp in s with sv being the string view +// corresponding to the code point. cp is invalid_code_point on error. +template <typename F> +FMT_CONSTEXPR void for_each_codepoint(string_view s, F f) { + auto decode = [f](const char* buf_ptr, const char* ptr) { + auto cp = uint32_t(); + auto error = 0; + auto end = utf8_decode(buf_ptr, &cp, &error); + bool result = f(error ? invalid_code_point : cp, + string_view(ptr, to_unsigned(end - buf_ptr))); + return result ? end : nullptr; + }; + auto p = s.data(); + const size_t block_size = 4; // utf8_decode always reads blocks of 4 chars. + if (s.size() >= block_size) { + for (auto end = p + s.size() - block_size + 1; p < end;) { + p = decode(p, p); + if (!p) return; + } + } + if (auto num_chars_left = s.data() + s.size() - p) { + char buf[2 * block_size - 1] = {}; + copy_str<char>(p, p + num_chars_left, buf); + const char* buf_ptr = buf; + do { + auto end = decode(buf_ptr, p); + if (!end) return; + p += end - buf_ptr; + buf_ptr = end; + } while (buf_ptr - buf < num_chars_left); + } +} + +template <typename Char> +inline auto compute_width(basic_string_view<Char> s) -> size_t { + return s.size(); +} + +// Computes approximate display width of a UTF-8 string. +FMT_CONSTEXPR inline size_t compute_width(string_view s) { + size_t num_code_points = 0; + // It is not a lambda for compatibility with C++14. + struct count_code_points { + size_t* count; + FMT_CONSTEXPR auto operator()(uint32_t cp, string_view) const -> bool { + *count += detail::to_unsigned( + 1 + + (cp >= 0x1100 && + (cp <= 0x115f || // Hangul Jamo init. consonants + cp == 0x2329 || // LEFT-POINTING ANGLE BRACKET + cp == 0x232a || // RIGHT-POINTING ANGLE BRACKET + // CJK ... Yi except IDEOGRAPHIC HALF FILL SPACE: + (cp >= 0x2e80 && cp <= 0xa4cf && cp != 0x303f) || + (cp >= 0xac00 && cp <= 0xd7a3) || // Hangul Syllables + (cp >= 0xf900 && cp <= 0xfaff) || // CJK Compatibility Ideographs + (cp >= 0xfe10 && cp <= 0xfe19) || // Vertical Forms + (cp >= 0xfe30 && cp <= 0xfe6f) || // CJK Compatibility Forms + (cp >= 0xff00 && cp <= 0xff60) || // Fullwidth Forms + (cp >= 0xffe0 && cp <= 0xffe6) || // Fullwidth Forms + (cp >= 0x20000 && cp <= 0x2fffd) || // CJK + (cp >= 0x30000 && cp <= 0x3fffd) || + // Miscellaneous Symbols and Pictographs + Emoticons: + (cp >= 0x1f300 && cp <= 0x1f64f) || + // Supplemental Symbols and Pictographs: + (cp >= 0x1f900 && cp <= 0x1f9ff)))); + return true; + } + }; + for_each_codepoint(s, count_code_points{&num_code_points}); + return num_code_points; +} + +inline auto compute_width(basic_string_view<char8_type> s) -> size_t { + return compute_width(basic_string_view<char>( + reinterpret_cast<const char*>(s.data()), s.size())); +} + +template <typename Char> +inline auto code_point_index(basic_string_view<Char> s, size_t n) -> size_t { + size_t size = s.size(); + return n < size ? n : size; +} + +// Calculates the index of the nth code point in a UTF-8 string. +inline auto code_point_index(basic_string_view<char8_type> s, size_t n) + -> size_t { + const char8_type* data = s.data(); + size_t num_code_points = 0; + for (size_t i = 0, size = s.size(); i != size; ++i) { + if ((data[i] & 0xc0) != 0x80 && ++num_code_points > n) return i; + } + return s.size(); +} + +template <typename T, bool = std::is_floating_point<T>::value> +struct is_fast_float : bool_constant<std::numeric_limits<T>::is_iec559 && + sizeof(T) <= sizeof(double)> {}; +template <typename T> struct is_fast_float<T, false> : std::false_type {}; + +#ifndef FMT_USE_FULL_CACHE_DRAGONBOX +# define FMT_USE_FULL_CACHE_DRAGONBOX 0 +#endif + +template <typename T> +template <typename U> +void buffer<T>::append(const U* begin, const U* end) { + while (begin != end) { + auto count = to_unsigned(end - begin); + try_reserve(size_ + count); + auto free_cap = capacity_ - size_; + if (free_cap < count) count = free_cap; + std::uninitialized_copy_n(begin, count, make_checked(ptr_ + size_, count)); + size_ += count; + begin += count; + } +} + +template <typename T, typename Enable = void> +struct is_locale : std::false_type {}; +template <typename T> +struct is_locale<T, void_t<decltype(T::classic())>> : std::true_type {}; +} // namespace detail + +FMT_MODULE_EXPORT_BEGIN + +// The number of characters to store in the basic_memory_buffer object itself +// to avoid dynamic memory allocation. +enum { inline_buffer_size = 500 }; + +/** + \rst + A dynamically growing memory buffer for trivially copyable/constructible types + with the first ``SIZE`` elements stored in the object itself. + + You can use the ``memory_buffer`` type alias for ``char`` instead. + + **Example**:: + + auto out = fmt::memory_buffer(); + format_to(std::back_inserter(out), "The answer is {}.", 42); + + This will append the following output to the ``out`` object: + + .. code-block:: none + + The answer is 42. + + The output can be converted to an ``std::string`` with ``to_string(out)``. + \endrst + */ +template <typename T, size_t SIZE = inline_buffer_size, + typename Allocator = std::allocator<T>> +class basic_memory_buffer final : public detail::buffer<T> { + private: + T store_[SIZE]; + + // Don't inherit from Allocator avoid generating type_info for it. + Allocator alloc_; + + // Deallocate memory allocated by the buffer. + FMT_CONSTEXPR20 void deallocate() { + T* data = this->data(); + if (data != store_) alloc_.deallocate(data, this->capacity()); + } + + protected: + FMT_CONSTEXPR20 void grow(size_t size) override; + + public: + using value_type = T; + using const_reference = const T&; + + FMT_CONSTEXPR20 explicit basic_memory_buffer( + const Allocator& alloc = Allocator()) + : alloc_(alloc) { + this->set(store_, SIZE); + if (detail::is_constant_evaluated()) { + detail::fill_n(store_, SIZE, T{}); + } + } + FMT_CONSTEXPR20 ~basic_memory_buffer() { deallocate(); } + + private: + // Move data from other to this buffer. + FMT_CONSTEXPR20 void move(basic_memory_buffer& other) { + alloc_ = std::move(other.alloc_); + T* data = other.data(); + size_t size = other.size(), capacity = other.capacity(); + if (data == other.store_) { + this->set(store_, capacity); + if (detail::is_constant_evaluated()) { + detail::copy_str<T>(other.store_, other.store_ + size, + detail::make_checked(store_, capacity)); + } else { + std::uninitialized_copy(other.store_, other.store_ + size, + detail::make_checked(store_, capacity)); + } + } else { + this->set(data, capacity); + // Set pointer to the inline array so that delete is not called + // when deallocating. + other.set(other.store_, 0); + } + this->resize(size); + } + + public: + /** + \rst + Constructs a :class:`fmt::basic_memory_buffer` object moving the content + of the other object to it. + \endrst + */ + FMT_CONSTEXPR20 basic_memory_buffer(basic_memory_buffer&& other) + FMT_NOEXCEPT { + move(other); + } + + /** + \rst + Moves the content of the other ``basic_memory_buffer`` object to this one. + \endrst + */ + auto operator=(basic_memory_buffer&& other) FMT_NOEXCEPT + -> basic_memory_buffer& { + FMT_ASSERT(this != &other, ""); + deallocate(); + move(other); + return *this; + } + + // Returns a copy of the allocator associated with this buffer. + auto get_allocator() const -> Allocator { return alloc_; } + + /** + Resizes the buffer to contain *count* elements. If T is a POD type new + elements may not be initialized. + */ + FMT_CONSTEXPR20 void resize(size_t count) { this->try_resize(count); } + + /** Increases the buffer capacity to *new_capacity*. */ + void reserve(size_t new_capacity) { this->try_reserve(new_capacity); } + + // Directly append data into the buffer + using detail::buffer<T>::append; + template <typename ContiguousRange> + void append(const ContiguousRange& range) { + append(range.data(), range.data() + range.size()); + } +}; + +template <typename T, size_t SIZE, typename Allocator> +FMT_CONSTEXPR20 void basic_memory_buffer<T, SIZE, Allocator>::grow( + size_t size) { +#ifdef FMT_FUZZ + if (size > 5000) throw std::runtime_error("fuzz mode - won't grow that much"); +#endif + const size_t max_size = std::allocator_traits<Allocator>::max_size(alloc_); + size_t old_capacity = this->capacity(); + size_t new_capacity = old_capacity + old_capacity / 2; + if (size > new_capacity) + new_capacity = size; + else if (new_capacity > max_size) + new_capacity = size > max_size ? size : max_size; + T* old_data = this->data(); + T* new_data = + std::allocator_traits<Allocator>::allocate(alloc_, new_capacity); + // The following code doesn't throw, so the raw pointer above doesn't leak. + std::uninitialized_copy(old_data, old_data + this->size(), + detail::make_checked(new_data, new_capacity)); + this->set(new_data, new_capacity); + // deallocate must not throw according to the standard, but even if it does, + // the buffer already uses the new storage and will deallocate it in + // destructor. + if (old_data != store_) alloc_.deallocate(old_data, old_capacity); +} + +using memory_buffer = basic_memory_buffer<char>; + +template <typename T, size_t SIZE, typename Allocator> +struct is_contiguous<basic_memory_buffer<T, SIZE, Allocator>> : std::true_type { +}; + +namespace detail { +FMT_API void print(std::FILE*, string_view); +} + +/** A formatting error such as invalid format string. */ +FMT_CLASS_API +class FMT_API format_error : public std::runtime_error { + public: + explicit format_error(const char* message) : std::runtime_error(message) {} + explicit format_error(const std::string& message) + : std::runtime_error(message) {} + format_error(const format_error&) = default; + format_error& operator=(const format_error&) = default; + format_error(format_error&&) = default; + format_error& operator=(format_error&&) = default; + ~format_error() FMT_NOEXCEPT override FMT_MSC_DEFAULT; +}; + +/** + \rst + Constructs a `~fmt::format_arg_store` object that contains references + to arguments and can be implicitly converted to `~fmt::format_args`. + If ``fmt`` is a compile-time string then `make_args_checked` checks + its validity at compile time. + \endrst + */ +template <typename... Args, typename S, typename Char = char_t<S>> +FMT_INLINE auto make_args_checked(const S& fmt, + const remove_reference_t<Args>&... args) + -> format_arg_store<buffer_context<Char>, remove_reference_t<Args>...> { + static_assert( + detail::count<( + std::is_base_of<detail::view, remove_reference_t<Args>>::value && + std::is_reference<Args>::value)...>() == 0, + "passing views as lvalues is disallowed"); + detail::check_format_string<Args...>(fmt); + return {args...}; +} + +// compile-time support +namespace detail_exported { +#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS +template <typename Char, size_t N> struct fixed_string { + constexpr fixed_string(const Char (&str)[N]) { + detail::copy_str<Char, const Char*, Char*>(static_cast<const Char*>(str), + str + N, data); + } + Char data[N]{}; +}; +#endif + +// Converts a compile-time string to basic_string_view. +template <typename Char, size_t N> +constexpr auto compile_string_to_view(const Char (&s)[N]) + -> basic_string_view<Char> { + // Remove trailing NUL character if needed. Won't be present if this is used + // with a raw character array (i.e. not defined as a string). + return {s, N - (std::char_traits<Char>::to_int_type(s[N - 1]) == 0 ? 1 : 0)}; +} +template <typename Char> +constexpr auto compile_string_to_view(detail::std_string_view<Char> s) + -> basic_string_view<Char> { + return {s.data(), s.size()}; +} +} // namespace detail_exported + +FMT_BEGIN_DETAIL_NAMESPACE + +template <typename T> struct is_integral : std::is_integral<T> {}; +template <> struct is_integral<int128_t> : std::true_type {}; +template <> struct is_integral<uint128_t> : std::true_type {}; + +template <typename T> +using is_signed = + std::integral_constant<bool, std::numeric_limits<T>::is_signed || + std::is_same<T, int128_t>::value>; + +// Returns true if value is negative, false otherwise. +// Same as `value < 0` but doesn't produce warnings if T is an unsigned type. +template <typename T, FMT_ENABLE_IF(is_signed<T>::value)> +FMT_CONSTEXPR auto is_negative(T value) -> bool { + return value < 0; +} +template <typename T, FMT_ENABLE_IF(!is_signed<T>::value)> +FMT_CONSTEXPR auto is_negative(T) -> bool { + return false; +} + +template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)> +FMT_CONSTEXPR auto is_supported_floating_point(T) -> uint16_t { + return (std::is_same<T, float>::value && FMT_USE_FLOAT) || + (std::is_same<T, double>::value && FMT_USE_DOUBLE) || + (std::is_same<T, long double>::value && FMT_USE_LONG_DOUBLE); +} + +// Smallest of uint32_t, uint64_t, uint128_t that is large enough to +// represent all values of an integral type T. +template <typename T> +using uint32_or_64_or_128_t = + conditional_t<num_bits<T>() <= 32 && !FMT_REDUCE_INT_INSTANTIATIONS, + uint32_t, + conditional_t<num_bits<T>() <= 64, uint64_t, uint128_t>>; +template <typename T> +using uint64_or_128_t = conditional_t<num_bits<T>() <= 64, uint64_t, uint128_t>; + +#define FMT_POWERS_OF_10(factor) \ + factor * 10, (factor)*100, (factor)*1000, (factor)*10000, (factor)*100000, \ + (factor)*1000000, (factor)*10000000, (factor)*100000000, \ + (factor)*1000000000 + +// Converts value in the range [0, 100) to a string. +constexpr const char* digits2(size_t value) { + // GCC generates slightly better code when value is pointer-size. + return &"0001020304050607080910111213141516171819" + "2021222324252627282930313233343536373839" + "4041424344454647484950515253545556575859" + "6061626364656667686970717273747576777879" + "8081828384858687888990919293949596979899"[value * 2]; +} + +// Sign is a template parameter to workaround a bug in gcc 4.8. +template <typename Char, typename Sign> constexpr Char sign(Sign s) { +#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 604 + static_assert(std::is_same<Sign, sign_t>::value, ""); +#endif + return static_cast<Char>("\0-+ "[s]); +} + +template <typename T> FMT_CONSTEXPR auto count_digits_fallback(T n) -> int { + int count = 1; + for (;;) { + // Integer division is slow so do it for a group of four digits instead + // of for every digit. The idea comes from the talk by Alexandrescu + // "Three Optimization Tips for C++". See speed-test for a comparison. + if (n < 10) return count; + if (n < 100) return count + 1; + if (n < 1000) return count + 2; + if (n < 10000) return count + 3; + n /= 10000u; + count += 4; + } +} +#if FMT_USE_INT128 +FMT_CONSTEXPR inline auto count_digits(uint128_t n) -> int { + return count_digits_fallback(n); +} +#endif + +#ifdef FMT_BUILTIN_CLZLL +// It is a separate function rather than a part of count_digits to workaround +// the lack of static constexpr in constexpr functions. +inline auto do_count_digits(uint64_t n) -> int { + // This has comparable performance to the version by Kendall Willets + // (https://github.com/fmtlib/format-benchmark/blob/master/digits10) + // but uses smaller tables. + // Maps bsr(n) to ceil(log10(pow(2, bsr(n) + 1) - 1)). + static constexpr uint8_t bsr2log10[] = { + 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, + 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, + 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15, + 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20}; + auto t = bsr2log10[FMT_BUILTIN_CLZLL(n | 1) ^ 63]; + static constexpr const uint64_t zero_or_powers_of_10[] = { + 0, 0, FMT_POWERS_OF_10(1U), FMT_POWERS_OF_10(1000000000ULL), + 10000000000000000000ULL}; + return t - (n < zero_or_powers_of_10[t]); +} +#endif + +// Returns the number of decimal digits in n. Leading zeros are not counted +// except for n == 0 in which case count_digits returns 1. +FMT_CONSTEXPR20 inline auto count_digits(uint64_t n) -> int { +#ifdef FMT_BUILTIN_CLZLL + if (!is_constant_evaluated()) { + return do_count_digits(n); + } +#endif + return count_digits_fallback(n); +} + +// Counts the number of digits in n. BITS = log2(radix). +template <int BITS, typename UInt> +FMT_CONSTEXPR auto count_digits(UInt n) -> int { +#ifdef FMT_BUILTIN_CLZ + if (num_bits<UInt>() == 32) + return (FMT_BUILTIN_CLZ(static_cast<uint32_t>(n) | 1) ^ 31) / BITS + 1; +#endif + // Lambda avoids unreachable code warnings from NVHPC. + return [](UInt m) { + int num_digits = 0; + do { + ++num_digits; + } while ((m >>= BITS) != 0); + return num_digits; + }(n); +} + +template <> auto count_digits<4>(detail::fallback_uintptr n) -> int; + +#ifdef FMT_BUILTIN_CLZ +// It is a separate function rather than a part of count_digits to workaround +// the lack of static constexpr in constexpr functions. +FMT_INLINE auto do_count_digits(uint32_t n) -> int { +// An optimization by Kendall Willets from https://bit.ly/3uOIQrB. +// This increments the upper 32 bits (log10(T) - 1) when >= T is added. +# define FMT_INC(T) (((sizeof(# T) - 1ull) << 32) - T) + static constexpr uint64_t table[] = { + FMT_INC(0), FMT_INC(0), FMT_INC(0), // 8 + FMT_INC(10), FMT_INC(10), FMT_INC(10), // 64 + FMT_INC(100), FMT_INC(100), FMT_INC(100), // 512 + FMT_INC(1000), FMT_INC(1000), FMT_INC(1000), // 4096 + FMT_INC(10000), FMT_INC(10000), FMT_INC(10000), // 32k + FMT_INC(100000), FMT_INC(100000), FMT_INC(100000), // 256k + FMT_INC(1000000), FMT_INC(1000000), FMT_INC(1000000), // 2048k + FMT_INC(10000000), FMT_INC(10000000), FMT_INC(10000000), // 16M + FMT_INC(100000000), FMT_INC(100000000), FMT_INC(100000000), // 128M + FMT_INC(1000000000), FMT_INC(1000000000), FMT_INC(1000000000), // 1024M + FMT_INC(1000000000), FMT_INC(1000000000) // 4B + }; + auto inc = table[FMT_BUILTIN_CLZ(n | 1) ^ 31]; + return static_cast<int>((n + inc) >> 32); +} +#endif + +// Optional version of count_digits for better performance on 32-bit platforms. +FMT_CONSTEXPR20 inline auto count_digits(uint32_t n) -> int { +#ifdef FMT_BUILTIN_CLZ + if (!is_constant_evaluated()) { + return do_count_digits(n); + } +#endif + return count_digits_fallback(n); +} + +template <typename Int> constexpr auto digits10() FMT_NOEXCEPT -> int { + return std::numeric_limits<Int>::digits10; +} +template <> constexpr auto digits10<int128_t>() FMT_NOEXCEPT -> int { + return 38; +} +template <> constexpr auto digits10<uint128_t>() FMT_NOEXCEPT -> int { + return 38; +} + +template <typename Char> struct thousands_sep_result { + std::string grouping; + Char thousands_sep; +}; + +template <typename Char> +FMT_API auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result<Char>; +template <typename Char> +inline auto thousands_sep(locale_ref loc) -> thousands_sep_result<Char> { + auto result = thousands_sep_impl<char>(loc); + return {result.grouping, Char(result.thousands_sep)}; +} +template <> +inline auto thousands_sep(locale_ref loc) -> thousands_sep_result<wchar_t> { + return thousands_sep_impl<wchar_t>(loc); +} + +template <typename Char> +FMT_API auto decimal_point_impl(locale_ref loc) -> Char; +template <typename Char> inline auto decimal_point(locale_ref loc) -> Char { + return Char(decimal_point_impl<char>(loc)); +} +template <> inline auto decimal_point(locale_ref loc) -> wchar_t { + return decimal_point_impl<wchar_t>(loc); +} + +// Compares two characters for equality. +template <typename Char> auto equal2(const Char* lhs, const char* rhs) -> bool { + return lhs[0] == Char(rhs[0]) && lhs[1] == Char(rhs[1]); +} +inline auto equal2(const char* lhs, const char* rhs) -> bool { + return memcmp(lhs, rhs, 2) == 0; +} + +// Copies two characters from src to dst. +template <typename Char> +FMT_CONSTEXPR20 FMT_INLINE void copy2(Char* dst, const char* src) { + if (!is_constant_evaluated() && sizeof(Char) == sizeof(char)) { + memcpy(dst, src, 2); + return; + } + *dst++ = static_cast<Char>(*src++); + *dst = static_cast<Char>(*src); +} + +template <typename Iterator> struct format_decimal_result { + Iterator begin; + Iterator end; +}; + +// Formats a decimal unsigned integer value writing into out pointing to a +// buffer of specified size. The caller must ensure that the buffer is large +// enough. +template <typename Char, typename UInt> +FMT_CONSTEXPR20 auto format_decimal(Char* out, UInt value, int size) + -> format_decimal_result<Char*> { + FMT_ASSERT(size >= count_digits(value), "invalid digit count"); + out += size; + Char* end = out; + while (value >= 100) { + // Integer division is slow so do it for a group of two digits instead + // of for every digit. The idea comes from the talk by Alexandrescu + // "Three Optimization Tips for C++". See speed-test for a comparison. + out -= 2; + copy2(out, digits2(static_cast<size_t>(value % 100))); + value /= 100; + } + if (value < 10) { + *--out = static_cast<Char>('0' + value); + return {out, end}; + } + out -= 2; + copy2(out, digits2(static_cast<size_t>(value))); + return {out, end}; +} + +template <typename Char, typename UInt, typename Iterator, + FMT_ENABLE_IF(!std::is_pointer<remove_cvref_t<Iterator>>::value)> +inline auto format_decimal(Iterator out, UInt value, int size) + -> format_decimal_result<Iterator> { + // Buffer is large enough to hold all digits (digits10 + 1). + Char buffer[digits10<UInt>() + 1]; + auto end = format_decimal(buffer, value, size).end; + return {out, detail::copy_str_noinline<Char>(buffer, end, out)}; +} + +template <unsigned BASE_BITS, typename Char, typename UInt> +FMT_CONSTEXPR auto format_uint(Char* buffer, UInt value, int num_digits, + bool upper = false) -> Char* { + buffer += num_digits; + Char* end = buffer; + do { + const char* digits = upper ? "0123456789ABCDEF" : "0123456789abcdef"; + unsigned digit = (value & ((1 << BASE_BITS) - 1)); + *--buffer = static_cast<Char>(BASE_BITS < 4 ? static_cast<char>('0' + digit) + : digits[digit]); + } while ((value >>= BASE_BITS) != 0); + return end; +} + +template <unsigned BASE_BITS, typename Char> +auto format_uint(Char* buffer, detail::fallback_uintptr n, int num_digits, + bool = false) -> Char* { + auto char_digits = std::numeric_limits<unsigned char>::digits / 4; + int start = (num_digits + char_digits - 1) / char_digits - 1; + if (int start_digits = num_digits % char_digits) { + unsigned value = n.value[start--]; + buffer = format_uint<BASE_BITS>(buffer, value, start_digits); + } + for (; start >= 0; --start) { + unsigned value = n.value[start]; + buffer += char_digits; + auto p = buffer; + for (int i = 0; i < char_digits; ++i) { + unsigned digit = (value & ((1 << BASE_BITS) - 1)); + *--p = static_cast<Char>("0123456789abcdef"[digit]); + value >>= BASE_BITS; + } + } + return buffer; +} + +template <unsigned BASE_BITS, typename Char, typename It, typename UInt> +inline auto format_uint(It out, UInt value, int num_digits, bool upper = false) + -> It { + if (auto ptr = to_pointer<Char>(out, to_unsigned(num_digits))) { + format_uint<BASE_BITS>(ptr, value, num_digits, upper); + return out; + } + // Buffer should be large enough to hold all digits (digits / BASE_BITS + 1). + char buffer[num_bits<UInt>() / BASE_BITS + 1]; + format_uint<BASE_BITS>(buffer, value, num_digits, upper); + return detail::copy_str_noinline<Char>(buffer, buffer + num_digits, out); +} + +// A converter from UTF-8 to UTF-16. +class utf8_to_utf16 { + private: + basic_memory_buffer<wchar_t> buffer_; + + public: + FMT_API explicit utf8_to_utf16(string_view s); + operator basic_string_view<wchar_t>() const { return {&buffer_[0], size()}; } + auto size() const -> size_t { return buffer_.size() - 1; } + auto c_str() const -> const wchar_t* { return &buffer_[0]; } + auto str() const -> std::wstring { return {&buffer_[0], size()}; } +}; + +namespace dragonbox { + +// Type-specific information that Dragonbox uses. +template <class T> struct float_info; + +template <> struct float_info<float> { + using carrier_uint = uint32_t; + static const int significand_bits = 23; + static const int exponent_bits = 8; + static const int min_exponent = -126; + static const int max_exponent = 127; + static const int exponent_bias = -127; + static const int decimal_digits = 9; + static const int kappa = 1; + static const int big_divisor = 100; + static const int small_divisor = 10; + static const int min_k = -31; + static const int max_k = 46; + static const int cache_bits = 64; + static const int divisibility_check_by_5_threshold = 39; + static const int case_fc_pm_half_lower_threshold = -1; + static const int case_fc_pm_half_upper_threshold = 6; + static const int case_fc_lower_threshold = -2; + static const int case_fc_upper_threshold = 6; + static const int case_shorter_interval_left_endpoint_lower_threshold = 2; + static const int case_shorter_interval_left_endpoint_upper_threshold = 3; + static const int shorter_interval_tie_lower_threshold = -35; + static const int shorter_interval_tie_upper_threshold = -35; + static const int max_trailing_zeros = 7; +}; + +template <> struct float_info<double> { + using carrier_uint = uint64_t; + static const int significand_bits = 52; + static const int exponent_bits = 11; + static const int min_exponent = -1022; + static const int max_exponent = 1023; + static const int exponent_bias = -1023; + static const int decimal_digits = 17; + static const int kappa = 2; + static const int big_divisor = 1000; + static const int small_divisor = 100; + static const int min_k = -292; + static const int max_k = 326; + static const int cache_bits = 128; + static const int divisibility_check_by_5_threshold = 86; + static const int case_fc_pm_half_lower_threshold = -2; + static const int case_fc_pm_half_upper_threshold = 9; + static const int case_fc_lower_threshold = -4; + static const int case_fc_upper_threshold = 9; + static const int case_shorter_interval_left_endpoint_lower_threshold = 2; + static const int case_shorter_interval_left_endpoint_upper_threshold = 3; + static const int shorter_interval_tie_lower_threshold = -77; + static const int shorter_interval_tie_upper_threshold = -77; + static const int max_trailing_zeros = 16; +}; + +template <typename T> struct decimal_fp { + using significand_type = typename float_info<T>::carrier_uint; + significand_type significand; + int exponent; +}; + +template <typename T> +FMT_API auto to_decimal(T x) FMT_NOEXCEPT -> decimal_fp<T>; +} // namespace dragonbox + +template <typename T> +constexpr auto exponent_mask() -> + typename dragonbox::float_info<T>::carrier_uint { + using uint = typename dragonbox::float_info<T>::carrier_uint; + return ((uint(1) << dragonbox::float_info<T>::exponent_bits) - 1) + << dragonbox::float_info<T>::significand_bits; +} + +// Writes the exponent exp in the form "[+-]d{2,3}" to buffer. +template <typename Char, typename It> +FMT_CONSTEXPR auto write_exponent(int exp, It it) -> It { + FMT_ASSERT(-10000 < exp && exp < 10000, "exponent out of range"); + if (exp < 0) { + *it++ = static_cast<Char>('-'); + exp = -exp; + } else { + *it++ = static_cast<Char>('+'); + } + if (exp >= 100) { + const char* top = digits2(to_unsigned(exp / 100)); + if (exp >= 1000) *it++ = static_cast<Char>(top[0]); + *it++ = static_cast<Char>(top[1]); + exp %= 100; + } + const char* d = digits2(to_unsigned(exp)); + *it++ = static_cast<Char>(d[0]); + *it++ = static_cast<Char>(d[1]); + return it; +} + +template <typename T> +FMT_HEADER_ONLY_CONSTEXPR20 auto format_float(T value, int precision, + float_specs specs, + buffer<char>& buf) -> int; + +// Formats a floating-point number with snprintf. +template <typename T> +auto snprintf_float(T value, int precision, float_specs specs, + buffer<char>& buf) -> int; + +template <typename T> constexpr auto promote_float(T value) -> T { + return value; +} +constexpr auto promote_float(float value) -> double { + return static_cast<double>(value); +} + +template <typename OutputIt, typename Char> +FMT_NOINLINE FMT_CONSTEXPR auto fill(OutputIt it, size_t n, + const fill_t<Char>& fill) -> OutputIt { + auto fill_size = fill.size(); + if (fill_size == 1) return detail::fill_n(it, n, fill[0]); + auto data = fill.data(); + for (size_t i = 0; i < n; ++i) + it = copy_str<Char>(data, data + fill_size, it); + return it; +} + +// Writes the output of f, padded according to format specifications in specs. +// size: output size in code units. +// width: output display width in (terminal) column positions. +template <align::type align = align::left, typename OutputIt, typename Char, + typename F> +FMT_CONSTEXPR auto write_padded(OutputIt out, + const basic_format_specs<Char>& specs, + size_t size, size_t width, F&& f) -> OutputIt { + static_assert(align == align::left || align == align::right, ""); + unsigned spec_width = to_unsigned(specs.width); + size_t padding = spec_width > width ? spec_width - width : 0; + // Shifts are encoded as string literals because static constexpr is not + // supported in constexpr functions. + auto* shifts = align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01"; + size_t left_padding = padding >> shifts[specs.align]; + size_t right_padding = padding - left_padding; + auto it = reserve(out, size + padding * specs.fill.size()); + if (left_padding != 0) it = fill(it, left_padding, specs.fill); + it = f(it); + if (right_padding != 0) it = fill(it, right_padding, specs.fill); + return base_iterator(out, it); +} + +template <align::type align = align::left, typename OutputIt, typename Char, + typename F> +constexpr auto write_padded(OutputIt out, const basic_format_specs<Char>& specs, + size_t size, F&& f) -> OutputIt { + return write_padded<align>(out, specs, size, size, f); +} + +template <align::type align = align::left, typename Char, typename OutputIt> +FMT_CONSTEXPR auto write_bytes(OutputIt out, string_view bytes, + const basic_format_specs<Char>& specs) + -> OutputIt { + return write_padded<align>( + out, specs, bytes.size(), [bytes](reserve_iterator<OutputIt> it) { + const char* data = bytes.data(); + return copy_str<Char>(data, data + bytes.size(), it); + }); +} + +template <typename Char, typename OutputIt, typename UIntPtr> +auto write_ptr(OutputIt out, UIntPtr value, + const basic_format_specs<Char>* specs) -> OutputIt { + int num_digits = count_digits<4>(value); + auto size = to_unsigned(num_digits) + size_t(2); + auto write = [=](reserve_iterator<OutputIt> it) { + *it++ = static_cast<Char>('0'); + *it++ = static_cast<Char>('x'); + return format_uint<4, Char>(it, value, num_digits); + }; + return specs ? write_padded<align::right>(out, *specs, size, write) + : base_iterator(out, write(reserve(out, size))); +} + +template <typename Char, typename OutputIt> +FMT_CONSTEXPR auto write_char(OutputIt out, Char value, + const basic_format_specs<Char>& specs) + -> OutputIt { + return write_padded(out, specs, 1, [=](reserve_iterator<OutputIt> it) { + *it++ = value; + return it; + }); +} +template <typename Char, typename OutputIt> +FMT_CONSTEXPR auto write(OutputIt out, Char value, + const basic_format_specs<Char>& specs, + locale_ref loc = {}) -> OutputIt { + return check_char_specs(specs) + ? write_char(out, value, specs) + : write(out, static_cast<int>(value), specs, loc); +} + +// Data for write_int that doesn't depend on output iterator type. It is used to +// avoid template code bloat. +template <typename Char> struct write_int_data { + size_t size; + size_t padding; + + FMT_CONSTEXPR write_int_data(int num_digits, unsigned prefix, + const basic_format_specs<Char>& specs) + : size((prefix >> 24) + to_unsigned(num_digits)), padding(0) { + if (specs.align == align::numeric) { + auto width = to_unsigned(specs.width); + if (width > size) { + padding = width - size; + size = width; + } + } else if (specs.precision > num_digits) { + size = (prefix >> 24) + to_unsigned(specs.precision); + padding = to_unsigned(specs.precision - num_digits); + } + } +}; + +// Writes an integer in the format +// <left-padding><prefix><numeric-padding><digits><right-padding> +// where <digits> are written by write_digits(it). +// prefix contains chars in three lower bytes and the size in the fourth byte. +template <typename OutputIt, typename Char, typename W> +FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, int num_digits, + unsigned prefix, + const basic_format_specs<Char>& specs, + W write_digits) -> OutputIt { + // Slightly faster check for specs.width == 0 && specs.precision == -1. + if ((specs.width | (specs.precision + 1)) == 0) { + auto it = reserve(out, to_unsigned(num_digits) + (prefix >> 24)); + if (prefix != 0) { + for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8) + *it++ = static_cast<Char>(p & 0xff); + } + return base_iterator(out, write_digits(it)); + } + auto data = write_int_data<Char>(num_digits, prefix, specs); + return write_padded<align::right>( + out, specs, data.size, [=](reserve_iterator<OutputIt> it) { + for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8) + *it++ = static_cast<Char>(p & 0xff); + it = detail::fill_n(it, data.padding, static_cast<Char>('0')); + return write_digits(it); + }); +} + +template <typename Char> class digit_grouping { + private: + thousands_sep_result<Char> sep_; + + struct next_state { + std::string::const_iterator group; + int pos; + }; + next_state initial_state() const { return {sep_.grouping.begin(), 0}; } + + // Returns the next digit group separator position. + int next(next_state& state) const { + if (!sep_.thousands_sep) return max_value<int>(); + if (state.group == sep_.grouping.end()) + return state.pos += sep_.grouping.back(); + if (*state.group <= 0 || *state.group == max_value<char>()) + return max_value<int>(); + state.pos += *state.group++; + return state.pos; + } + + public: + explicit digit_grouping(locale_ref loc, bool localized = true) { + if (localized) + sep_ = thousands_sep<Char>(loc); + else + sep_.thousands_sep = Char(); + } + explicit digit_grouping(thousands_sep_result<Char> sep) : sep_(sep) {} + + Char separator() const { return sep_.thousands_sep; } + + int count_separators(int num_digits) const { + int count = 0; + auto state = initial_state(); + while (num_digits > next(state)) ++count; + return count; + } + + // Applies grouping to digits and write the output to out. + template <typename Out, typename C> + Out apply(Out out, basic_string_view<C> digits) const { + auto num_digits = static_cast<int>(digits.size()); + auto separators = basic_memory_buffer<int>(); + separators.push_back(0); + auto state = initial_state(); + while (int i = next(state)) { + if (i >= num_digits) break; + separators.push_back(i); + } + for (int i = 0, sep_index = static_cast<int>(separators.size() - 1); + i < num_digits; ++i) { + if (num_digits - i == separators[sep_index]) { + *out++ = separator(); + --sep_index; + } + *out++ = static_cast<Char>(digits[to_unsigned(i)]); + } + return out; + } +}; + +template <typename OutputIt, typename UInt, typename Char> +auto write_int_localized(OutputIt out, UInt value, unsigned prefix, + const basic_format_specs<Char>& specs, + const digit_grouping<Char>& grouping) -> OutputIt { + static_assert(std::is_same<uint64_or_128_t<UInt>, UInt>::value, ""); + int num_digits = count_digits(value); + char digits[40]; + format_decimal(digits, value, num_digits); + unsigned size = to_unsigned((prefix != 0 ? 1 : 0) + num_digits + + grouping.count_separators(num_digits)); + return write_padded<align::right>( + out, specs, size, size, [&](reserve_iterator<OutputIt> it) { + if (prefix != 0) *it++ = static_cast<Char>(prefix); + return grouping.apply(it, string_view(digits, to_unsigned(num_digits))); + }); +} + +template <typename OutputIt, typename UInt, typename Char> +auto write_int_localized(OutputIt& out, UInt value, unsigned prefix, + const basic_format_specs<Char>& specs, locale_ref loc) + -> bool { + auto grouping = digit_grouping<Char>(loc); + out = write_int_localized(out, value, prefix, specs, grouping); + return true; +} + +FMT_CONSTEXPR inline void prefix_append(unsigned& prefix, unsigned value) { + prefix |= prefix != 0 ? value << 8 : value; + prefix += (1u + (value > 0xff ? 1 : 0)) << 24; +} + +template <typename UInt> struct write_int_arg { + UInt abs_value; + unsigned prefix; +}; + +template <typename T> +FMT_CONSTEXPR auto make_write_int_arg(T value, sign_t sign) + -> write_int_arg<uint32_or_64_or_128_t<T>> { + auto prefix = 0u; + auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value); + if (is_negative(value)) { + prefix = 0x01000000 | '-'; + abs_value = 0 - abs_value; + } else { + constexpr const unsigned prefixes[4] = {0, 0, 0x1000000u | '+', + 0x1000000u | ' '}; + prefix = prefixes[sign]; + } + return {abs_value, prefix}; +} + +template <typename Char, typename OutputIt, typename T> +FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, write_int_arg<T> arg, + const basic_format_specs<Char>& specs, + locale_ref loc) -> OutputIt { + static_assert(std::is_same<T, uint32_or_64_or_128_t<T>>::value, ""); + auto abs_value = arg.abs_value; + auto prefix = arg.prefix; + switch (specs.type) { + case presentation_type::none: + case presentation_type::dec: { + if (specs.localized && + write_int_localized(out, static_cast<uint64_or_128_t<T>>(abs_value), + prefix, specs, loc)) { + return out; + } + auto num_digits = count_digits(abs_value); + return write_int( + out, num_digits, prefix, specs, [=](reserve_iterator<OutputIt> it) { + return format_decimal<Char>(it, abs_value, num_digits).end; + }); + } + case presentation_type::hex_lower: + case presentation_type::hex_upper: { + bool upper = specs.type == presentation_type::hex_upper; + if (specs.alt) + prefix_append(prefix, unsigned(upper ? 'X' : 'x') << 8 | '0'); + int num_digits = count_digits<4>(abs_value); + return write_int( + out, num_digits, prefix, specs, [=](reserve_iterator<OutputIt> it) { + return format_uint<4, Char>(it, abs_value, num_digits, upper); + }); + } + case presentation_type::bin_lower: + case presentation_type::bin_upper: { + bool upper = specs.type == presentation_type::bin_upper; + if (specs.alt) + prefix_append(prefix, unsigned(upper ? 'B' : 'b') << 8 | '0'); + int num_digits = count_digits<1>(abs_value); + return write_int(out, num_digits, prefix, specs, + [=](reserve_iterator<OutputIt> it) { + return format_uint<1, Char>(it, abs_value, num_digits); + }); + } + case presentation_type::oct: { + int num_digits = count_digits<3>(abs_value); + // Octal prefix '0' is counted as a digit, so only add it if precision + // is not greater than the number of digits. + if (specs.alt && specs.precision <= num_digits && abs_value != 0) + prefix_append(prefix, '0'); + return write_int(out, num_digits, prefix, specs, + [=](reserve_iterator<OutputIt> it) { + return format_uint<3, Char>(it, abs_value, num_digits); + }); + } + case presentation_type::chr: + return write_char(out, static_cast<Char>(abs_value), specs); + default: + throw_format_error("invalid type specifier"); + } + return out; +} +template <typename Char, typename OutputIt, typename T> +FMT_CONSTEXPR FMT_NOINLINE auto write_int_noinline( + OutputIt out, write_int_arg<T> arg, const basic_format_specs<Char>& specs, + locale_ref loc) -> OutputIt { + return write_int(out, arg, specs, loc); +} +template <typename Char, typename OutputIt, typename T, + FMT_ENABLE_IF(is_integral<T>::value && + !std::is_same<T, bool>::value && + std::is_same<OutputIt, buffer_appender<Char>>::value)> +FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value, + const basic_format_specs<Char>& specs, + locale_ref loc) -> OutputIt { + return write_int_noinline(out, make_write_int_arg(value, specs.sign), specs, + loc); +} +// An inlined version of write used in format string compilation. +template <typename Char, typename OutputIt, typename T, + FMT_ENABLE_IF(is_integral<T>::value && + !std::is_same<T, bool>::value && + !std::is_same<OutputIt, buffer_appender<Char>>::value)> +FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value, + const basic_format_specs<Char>& specs, + locale_ref loc) -> OutputIt { + return write_int(out, make_write_int_arg(value, specs.sign), specs, loc); +} + +template <typename Char, typename OutputIt> +FMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> s, + const basic_format_specs<Char>& specs) -> OutputIt { + auto data = s.data(); + auto size = s.size(); + if (specs.precision >= 0 && to_unsigned(specs.precision) < size) + size = code_point_index(s, to_unsigned(specs.precision)); + auto width = + specs.width != 0 ? compute_width(basic_string_view<Char>(data, size)) : 0; + return write_padded(out, specs, size, width, + [=](reserve_iterator<OutputIt> it) { + return copy_str<Char>(data, data + size, it); + }); +} +template <typename Char, typename OutputIt> +FMT_CONSTEXPR auto write(OutputIt out, + basic_string_view<type_identity_t<Char>> s, + const basic_format_specs<Char>& specs, locale_ref) + -> OutputIt { + check_string_type_spec(specs.type); + return write(out, s, specs); +} +template <typename Char, typename OutputIt> +FMT_CONSTEXPR auto write(OutputIt out, const Char* s, + const basic_format_specs<Char>& specs, locale_ref) + -> OutputIt { + return check_cstring_type_spec(specs.type) + ? write(out, basic_string_view<Char>(s), specs, {}) + : write_ptr<Char>(out, to_uintptr(s), &specs); +} + +template <typename Char, typename OutputIt> +FMT_CONSTEXPR20 auto write_nonfinite(OutputIt out, bool isinf, + basic_format_specs<Char> specs, + const float_specs& fspecs) -> OutputIt { + auto str = + isinf ? (fspecs.upper ? "INF" : "inf") : (fspecs.upper ? "NAN" : "nan"); + constexpr size_t str_size = 3; + auto sign = fspecs.sign; + auto size = str_size + (sign ? 1 : 0); + // Replace '0'-padding with space for non-finite values. + const bool is_zero_fill = + specs.fill.size() == 1 && *specs.fill.data() == static_cast<Char>('0'); + if (is_zero_fill) specs.fill[0] = static_cast<Char>(' '); + return write_padded(out, specs, size, [=](reserve_iterator<OutputIt> it) { + if (sign) *it++ = detail::sign<Char>(sign); + return copy_str<Char>(str, str + str_size, it); + }); +} + +// A decimal floating-point number significand * pow(10, exp). +struct big_decimal_fp { + const char* significand; + int significand_size; + int exponent; +}; + +constexpr auto get_significand_size(const big_decimal_fp& fp) -> int { + return fp.significand_size; +} +template <typename T> +inline auto get_significand_size(const dragonbox::decimal_fp<T>& fp) -> int { + return count_digits(fp.significand); +} + +template <typename Char, typename OutputIt> +constexpr auto write_significand(OutputIt out, const char* significand, + int significand_size) -> OutputIt { + return copy_str<Char>(significand, significand + significand_size, out); +} +template <typename Char, typename OutputIt, typename UInt> +inline auto write_significand(OutputIt out, UInt significand, + int significand_size) -> OutputIt { + return format_decimal<Char>(out, significand, significand_size).end; +} +template <typename Char, typename OutputIt, typename T, typename Grouping> +FMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand, + int significand_size, int exponent, + const Grouping& grouping) -> OutputIt { + if (!grouping.separator()) { + out = write_significand<Char>(out, significand, significand_size); + return detail::fill_n(out, exponent, static_cast<Char>('0')); + } + auto buffer = memory_buffer(); + write_significand<char>(appender(buffer), significand, significand_size); + detail::fill_n(appender(buffer), exponent, '0'); + return grouping.apply(out, string_view(buffer.data(), buffer.size())); +} + +template <typename Char, typename UInt, + FMT_ENABLE_IF(std::is_integral<UInt>::value)> +inline auto write_significand(Char* out, UInt significand, int significand_size, + int integral_size, Char decimal_point) -> Char* { + if (!decimal_point) + return format_decimal(out, significand, significand_size).end; + out += significand_size + 1; + Char* end = out; + int floating_size = significand_size - integral_size; + for (int i = floating_size / 2; i > 0; --i) { + out -= 2; + copy2(out, digits2(significand % 100)); + significand /= 100; + } + if (floating_size % 2 != 0) { + *--out = static_cast<Char>('0' + significand % 10); + significand /= 10; + } + *--out = decimal_point; + format_decimal(out - integral_size, significand, integral_size); + return end; +} + +template <typename OutputIt, typename UInt, typename Char, + FMT_ENABLE_IF(!std::is_pointer<remove_cvref_t<OutputIt>>::value)> +inline auto write_significand(OutputIt out, UInt significand, + int significand_size, int integral_size, + Char decimal_point) -> OutputIt { + // Buffer is large enough to hold digits (digits10 + 1) and a decimal point. + Char buffer[digits10<UInt>() + 2]; + auto end = write_significand(buffer, significand, significand_size, + integral_size, decimal_point); + return detail::copy_str_noinline<Char>(buffer, end, out); +} + +template <typename OutputIt, typename Char> +FMT_CONSTEXPR auto write_significand(OutputIt out, const char* significand, + int significand_size, int integral_size, + Char decimal_point) -> OutputIt { + out = detail::copy_str_noinline<Char>(significand, + significand + integral_size, out); + if (!decimal_point) return out; + *out++ = decimal_point; + return detail::copy_str_noinline<Char>(significand + integral_size, + significand + significand_size, out); +} + +template <typename OutputIt, typename Char, typename T, typename Grouping> +FMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand, + int significand_size, int integral_size, + Char decimal_point, + const Grouping& grouping) -> OutputIt { + if (!grouping.separator()) { + return write_significand(out, significand, significand_size, integral_size, + decimal_point); + } + auto buffer = basic_memory_buffer<Char>(); + write_significand(buffer_appender<Char>(buffer), significand, + significand_size, integral_size, decimal_point); + grouping.apply( + out, basic_string_view<Char>(buffer.data(), to_unsigned(integral_size))); + return detail::copy_str_noinline<Char>(buffer.data() + integral_size, + buffer.end(), out); +} + +template <typename OutputIt, typename DecimalFP, typename Char, + typename Grouping = digit_grouping<Char>> +FMT_CONSTEXPR20 auto do_write_float(OutputIt out, const DecimalFP& fp, + const basic_format_specs<Char>& specs, + float_specs fspecs, locale_ref loc) + -> OutputIt { + auto significand = fp.significand; + int significand_size = get_significand_size(fp); + constexpr Char zero = static_cast<Char>('0'); + auto sign = fspecs.sign; + size_t size = to_unsigned(significand_size) + (sign ? 1 : 0); + using iterator = reserve_iterator<OutputIt>; + + Char decimal_point = + fspecs.locale ? detail::decimal_point<Char>(loc) : static_cast<Char>('.'); + + int output_exp = fp.exponent + significand_size - 1; + auto use_exp_format = [=]() { + if (fspecs.format == float_format::exp) return true; + if (fspecs.format != float_format::general) return false; + // Use the fixed notation if the exponent is in [exp_lower, exp_upper), + // e.g. 0.0001 instead of 1e-04. Otherwise use the exponent notation. + const int exp_lower = -4, exp_upper = 16; + return output_exp < exp_lower || + output_exp >= (fspecs.precision > 0 ? fspecs.precision : exp_upper); + }; + if (use_exp_format()) { + int num_zeros = 0; + if (fspecs.showpoint) { + num_zeros = fspecs.precision - significand_size; + if (num_zeros < 0) num_zeros = 0; + size += to_unsigned(num_zeros); + } else if (significand_size == 1) { + decimal_point = Char(); + } + auto abs_output_exp = output_exp >= 0 ? output_exp : -output_exp; + int exp_digits = 2; + if (abs_output_exp >= 100) exp_digits = abs_output_exp >= 1000 ? 4 : 3; + + size += to_unsigned((decimal_point ? 1 : 0) + 2 + exp_digits); + char exp_char = fspecs.upper ? 'E' : 'e'; + auto write = [=](iterator it) { + if (sign) *it++ = detail::sign<Char>(sign); + // Insert a decimal point after the first digit and add an exponent. + it = write_significand(it, significand, significand_size, 1, + decimal_point); + if (num_zeros > 0) it = detail::fill_n(it, num_zeros, zero); + *it++ = static_cast<Char>(exp_char); + return write_exponent<Char>(output_exp, it); + }; + return specs.width > 0 ? write_padded<align::right>(out, specs, size, write) + : base_iterator(out, write(reserve(out, size))); + } + + int exp = fp.exponent + significand_size; + if (fp.exponent >= 0) { + // 1234e5 -> 123400000[.0+] + size += to_unsigned(fp.exponent); + int num_zeros = fspecs.precision - exp; +#ifdef FMT_FUZZ + if (num_zeros > 5000) + throw std::runtime_error("fuzz mode - avoiding excessive cpu use"); +#endif + if (fspecs.showpoint) { + if (num_zeros <= 0 && fspecs.format != float_format::fixed) num_zeros = 1; + if (num_zeros > 0) size += to_unsigned(num_zeros) + 1; + } + auto grouping = Grouping(loc, fspecs.locale); + size += to_unsigned(grouping.count_separators(significand_size)); + return write_padded<align::right>(out, specs, size, [&](iterator it) { + if (sign) *it++ = detail::sign<Char>(sign); + it = write_significand<Char>(it, significand, significand_size, + fp.exponent, grouping); + if (!fspecs.showpoint) return it; + *it++ = decimal_point; + return num_zeros > 0 ? detail::fill_n(it, num_zeros, zero) : it; + }); + } else if (exp > 0) { + // 1234e-2 -> 12.34[0+] + int num_zeros = fspecs.showpoint ? fspecs.precision - significand_size : 0; + size += 1 + to_unsigned(num_zeros > 0 ? num_zeros : 0); + auto grouping = Grouping(loc, fspecs.locale); + size += to_unsigned(grouping.count_separators(significand_size)); + return write_padded<align::right>(out, specs, size, [&](iterator it) { + if (sign) *it++ = detail::sign<Char>(sign); + it = write_significand(it, significand, significand_size, exp, + decimal_point, grouping); + return num_zeros > 0 ? detail::fill_n(it, num_zeros, zero) : it; + }); + } + // 1234e-6 -> 0.001234 + int num_zeros = -exp; + if (significand_size == 0 && fspecs.precision >= 0 && + fspecs.precision < num_zeros) { + num_zeros = fspecs.precision; + } + bool pointy = num_zeros != 0 || significand_size != 0 || fspecs.showpoint; + size += 1 + (pointy ? 1 : 0) + to_unsigned(num_zeros); + return write_padded<align::right>(out, specs, size, [&](iterator it) { + if (sign) *it++ = detail::sign<Char>(sign); + *it++ = zero; + if (!pointy) return it; + *it++ = decimal_point; + it = detail::fill_n(it, num_zeros, zero); + return write_significand<Char>(it, significand, significand_size); + }); +} + +template <typename Char> class fallback_digit_grouping { + public: + constexpr fallback_digit_grouping(locale_ref, bool) {} + + constexpr Char separator() const { return Char(); } + + constexpr int count_separators(int) const { return 0; } + + template <typename Out, typename C> + constexpr Out apply(Out out, basic_string_view<C>) const { + return out; + } +}; + +template <typename OutputIt, typename DecimalFP, typename Char> +FMT_CONSTEXPR20 auto write_float(OutputIt out, const DecimalFP& fp, + const basic_format_specs<Char>& specs, + float_specs fspecs, locale_ref loc) + -> OutputIt { + if (is_constant_evaluated()) { + return do_write_float<OutputIt, DecimalFP, Char, + fallback_digit_grouping<Char>>(out, fp, specs, fspecs, + loc); + } else { + return do_write_float(out, fp, specs, fspecs, loc); + } +} + +template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)> +FMT_CONSTEXPR20 bool isinf(T value) { + if (is_constant_evaluated()) { +#if defined(__cpp_if_constexpr) + if constexpr (std::numeric_limits<double>::is_iec559) { + auto bits = detail::bit_cast<uint64_t>(static_cast<double>(value)); + constexpr auto significand_bits = + dragonbox::float_info<double>::significand_bits; + return (bits & exponent_mask<double>()) && + !(bits & ((uint64_t(1) << significand_bits) - 1)); + } +#endif + } + return std::isinf(value); +} + +template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)> +FMT_CONSTEXPR20 bool isfinite(T value) { + if (is_constant_evaluated()) { +#if defined(__cpp_if_constexpr) + if constexpr (std::numeric_limits<double>::is_iec559) { + auto bits = detail::bit_cast<uint64_t>(static_cast<double>(value)); + return (bits & exponent_mask<double>()) != exponent_mask<double>(); + } +#endif + } + return std::isfinite(value); +} + +template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)> +FMT_INLINE FMT_CONSTEXPR bool signbit(T value) { + if (is_constant_evaluated()) { +#ifdef __cpp_if_constexpr + if constexpr (std::numeric_limits<double>::is_iec559) { + auto bits = detail::bit_cast<uint64_t>(static_cast<double>(value)); + return (bits & (uint64_t(1) << (num_bits<uint64_t>() - 1))) != 0; + } +#endif + } + return std::signbit(value); +} + +template <typename Char, typename OutputIt, typename T, + FMT_ENABLE_IF(std::is_floating_point<T>::value)> +FMT_CONSTEXPR20 auto write(OutputIt out, T value, + basic_format_specs<Char> specs, locale_ref loc = {}) + -> OutputIt { + if (const_check(!is_supported_floating_point(value))) return out; + float_specs fspecs = parse_float_type_spec(specs); + fspecs.sign = specs.sign; + if (detail::signbit(value)) { // value < 0 is false for NaN so use signbit. + fspecs.sign = sign::minus; + value = -value; + } else if (fspecs.sign == sign::minus) { + fspecs.sign = sign::none; + } + + if (!detail::isfinite(value)) + return write_nonfinite(out, detail::isinf(value), specs, fspecs); + + if (specs.align == align::numeric && fspecs.sign) { + auto it = reserve(out, 1); + *it++ = detail::sign<Char>(fspecs.sign); + out = base_iterator(out, it); + fspecs.sign = sign::none; + if (specs.width != 0) --specs.width; + } + + memory_buffer buffer; + if (fspecs.format == float_format::hex) { + if (fspecs.sign) buffer.push_back(detail::sign<char>(fspecs.sign)); + snprintf_float(promote_float(value), specs.precision, fspecs, buffer); + return write_bytes<align::right>(out, {buffer.data(), buffer.size()}, + specs); + } + int precision = specs.precision >= 0 || specs.type == presentation_type::none + ? specs.precision + : 6; + if (fspecs.format == float_format::exp) { + if (precision == max_value<int>()) + throw_format_error("number is too big"); + else + ++precision; + } + if (const_check(std::is_same<T, float>())) fspecs.binary32 = true; + if (!is_fast_float<T>()) fspecs.fallback = true; + int exp = format_float(promote_float(value), precision, fspecs, buffer); + fspecs.precision = precision; + auto fp = big_decimal_fp{buffer.data(), static_cast<int>(buffer.size()), exp}; + return write_float(out, fp, specs, fspecs, loc); +} + +template <typename Char, typename OutputIt, typename T, + FMT_ENABLE_IF(is_fast_float<T>::value)> +FMT_CONSTEXPR20 auto write(OutputIt out, T value) -> OutputIt { + if (is_constant_evaluated()) { + return write(out, value, basic_format_specs<Char>()); + } + + if (const_check(!is_supported_floating_point(value))) return out; + + using floaty = conditional_t<std::is_same<T, long double>::value, double, T>; + using uint = typename dragonbox::float_info<floaty>::carrier_uint; + auto bits = bit_cast<uint>(value); + + auto fspecs = float_specs(); + if (detail::signbit(value)) { + fspecs.sign = sign::minus; + value = -value; + } + + constexpr auto specs = basic_format_specs<Char>(); + uint mask = exponent_mask<floaty>(); + if ((bits & mask) == mask) + return write_nonfinite(out, std::isinf(value), specs, fspecs); + + auto dec = dragonbox::to_decimal(static_cast<floaty>(value)); + return write_float(out, dec, specs, fspecs, {}); +} + +template <typename Char, typename OutputIt, typename T, + FMT_ENABLE_IF(std::is_floating_point<T>::value && + !is_fast_float<T>::value)> +inline auto write(OutputIt out, T value) -> OutputIt { + return write(out, value, basic_format_specs<Char>()); +} + +template <typename Char, typename OutputIt> +auto write(OutputIt out, monostate, basic_format_specs<Char> = {}, + locale_ref = {}) -> OutputIt { + FMT_ASSERT(false, ""); + return out; +} + +template <typename Char, typename OutputIt> +FMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> value) + -> OutputIt { + auto it = reserve(out, value.size()); + it = copy_str_noinline<Char>(value.begin(), value.end(), it); + return base_iterator(out, it); +} + +template <typename Char, typename OutputIt, typename T, + FMT_ENABLE_IF(is_string<T>::value)> +constexpr auto write(OutputIt out, const T& value) -> OutputIt { + return write<Char>(out, to_string_view(value)); +} + +template <typename Char, typename OutputIt, typename T, + FMT_ENABLE_IF(is_integral<T>::value && + !std::is_same<T, bool>::value && + !std::is_same<T, Char>::value)> +FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt { + auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value); + bool negative = is_negative(value); + // Don't do -abs_value since it trips unsigned-integer-overflow sanitizer. + if (negative) abs_value = ~abs_value + 1; + int num_digits = count_digits(abs_value); + auto size = (negative ? 1 : 0) + static_cast<size_t>(num_digits); + auto it = reserve(out, size); + if (auto ptr = to_pointer<Char>(it, size)) { + if (negative) *ptr++ = static_cast<Char>('-'); + format_decimal<Char>(ptr, abs_value, num_digits); + return out; + } + if (negative) *it++ = static_cast<Char>('-'); + it = format_decimal<Char>(it, abs_value, num_digits).end; + return base_iterator(out, it); +} + +// FMT_ENABLE_IF() condition separated to workaround an MSVC bug. +template < + typename Char, typename OutputIt, typename T, + bool check = + std::is_enum<T>::value && !std::is_same<T, Char>::value && + mapped_type_constant<T, basic_format_context<OutputIt, Char>>::value != + type::custom_type, + FMT_ENABLE_IF(check)> +FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt { + return write<Char>( + out, static_cast<typename std::underlying_type<T>::type>(value)); +} + +template <typename Char, typename OutputIt, typename T, + FMT_ENABLE_IF(std::is_same<T, bool>::value)> +FMT_CONSTEXPR auto write(OutputIt out, T value, + const basic_format_specs<Char>& specs = {}, + locale_ref = {}) -> OutputIt { + return specs.type != presentation_type::none && + specs.type != presentation_type::string + ? write(out, value ? 1 : 0, specs, {}) + : write_bytes(out, value ? "true" : "false", specs); +} + +template <typename Char, typename OutputIt> +FMT_CONSTEXPR auto write(OutputIt out, Char value) -> OutputIt { + auto it = reserve(out, 1); + *it++ = value; + return base_iterator(out, it); +} + +template <typename Char, typename OutputIt> +FMT_CONSTEXPR_CHAR_TRAITS auto write(OutputIt out, const Char* value) + -> OutputIt { + if (!value) { + throw_format_error("string pointer is null"); + } else { + out = write(out, basic_string_view<Char>(value)); + } + return out; +} + +template <typename Char, typename OutputIt, typename T, + FMT_ENABLE_IF(std::is_same<T, void>::value)> +auto write(OutputIt out, const T* value, + const basic_format_specs<Char>& specs = {}, locale_ref = {}) + -> OutputIt { + check_pointer_type_spec(specs.type, error_handler()); + return write_ptr<Char>(out, to_uintptr(value), &specs); +} + +// A write overload that handles implicit conversions. +template <typename Char, typename OutputIt, typename T, + typename Context = basic_format_context<OutputIt, Char>> +FMT_CONSTEXPR auto write(OutputIt out, const T& value) -> enable_if_t< + std::is_class<T>::value && !is_string<T>::value && + !std::is_same<T, Char>::value && + !std::is_same<const T&, + decltype(arg_mapper<Context>().map(value))>::value, + OutputIt> { + return write<Char>(out, arg_mapper<Context>().map(value)); +} + +template <typename Char, typename OutputIt, typename T, + typename Context = basic_format_context<OutputIt, Char>> +FMT_CONSTEXPR auto write(OutputIt out, const T& value) + -> enable_if_t<mapped_type_constant<T, Context>::value == type::custom_type, + OutputIt> { + using formatter_type = + conditional_t<has_formatter<T, Context>::value, + typename Context::template formatter_type<T>, + fallback_formatter<T, Char>>; + auto ctx = Context(out, {}, {}); + return formatter_type().format(value, ctx); +} + +// An argument visitor that formats the argument and writes it via the output +// iterator. It's a class and not a generic lambda for compatibility with C++11. +template <typename Char> struct default_arg_formatter { + using iterator = buffer_appender<Char>; + using context = buffer_context<Char>; + + iterator out; + basic_format_args<context> args; + locale_ref loc; + + template <typename T> auto operator()(T value) -> iterator { + return write<Char>(out, value); + } + auto operator()(typename basic_format_arg<context>::handle h) -> iterator { + basic_format_parse_context<Char> parse_ctx({}); + context format_ctx(out, args, loc); + h.format(parse_ctx, format_ctx); + return format_ctx.out(); + } +}; + +template <typename Char> struct arg_formatter { + using iterator = buffer_appender<Char>; + using context = buffer_context<Char>; + + iterator out; + const basic_format_specs<Char>& specs; + locale_ref locale; + + template <typename T> + FMT_CONSTEXPR FMT_INLINE auto operator()(T value) -> iterator { + return detail::write(out, value, specs, locale); + } + auto operator()(typename basic_format_arg<context>::handle) -> iterator { + // User-defined types are handled separately because they require access + // to the parse context. + return out; + } +}; + +template <typename Char> struct custom_formatter { + basic_format_parse_context<Char>& parse_ctx; + buffer_context<Char>& ctx; + + void operator()( + typename basic_format_arg<buffer_context<Char>>::handle h) const { + h.format(parse_ctx, ctx); + } + template <typename T> void operator()(T) const {} +}; + +template <typename T> +using is_integer = + bool_constant<is_integral<T>::value && !std::is_same<T, bool>::value && + !std::is_same<T, char>::value && + !std::is_same<T, wchar_t>::value>; + +template <typename ErrorHandler> class width_checker { + public: + explicit FMT_CONSTEXPR width_checker(ErrorHandler& eh) : handler_(eh) {} + + template <typename T, FMT_ENABLE_IF(is_integer<T>::value)> + FMT_CONSTEXPR auto operator()(T value) -> unsigned long long { + if (is_negative(value)) handler_.on_error("negative width"); + return static_cast<unsigned long long>(value); + } + + template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)> + FMT_CONSTEXPR auto operator()(T) -> unsigned long long { + handler_.on_error("width is not integer"); + return 0; + } + + private: + ErrorHandler& handler_; +}; + +template <typename ErrorHandler> class precision_checker { + public: + explicit FMT_CONSTEXPR precision_checker(ErrorHandler& eh) : handler_(eh) {} + + template <typename T, FMT_ENABLE_IF(is_integer<T>::value)> + FMT_CONSTEXPR auto operator()(T value) -> unsigned long long { + if (is_negative(value)) handler_.on_error("negative precision"); + return static_cast<unsigned long long>(value); + } + + template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)> + FMT_CONSTEXPR auto operator()(T) -> unsigned long long { + handler_.on_error("precision is not integer"); + return 0; + } + + private: + ErrorHandler& handler_; +}; + +template <template <typename> class Handler, typename FormatArg, + typename ErrorHandler> +FMT_CONSTEXPR auto get_dynamic_spec(FormatArg arg, ErrorHandler eh) -> int { + unsigned long long value = visit_format_arg(Handler<ErrorHandler>(eh), arg); + if (value > to_unsigned(max_value<int>())) eh.on_error("number is too big"); + return static_cast<int>(value); +} + +template <typename Context, typename ID> +FMT_CONSTEXPR auto get_arg(Context& ctx, ID id) -> + typename Context::format_arg { + auto arg = ctx.arg(id); + if (!arg) ctx.on_error("argument not found"); + return arg; +} + +// The standard format specifier handler with checking. +template <typename Char> class specs_handler : public specs_setter<Char> { + private: + basic_format_parse_context<Char>& parse_context_; + buffer_context<Char>& context_; + + // This is only needed for compatibility with gcc 4.4. + using format_arg = basic_format_arg<buffer_context<Char>>; + + FMT_CONSTEXPR auto get_arg(auto_id) -> format_arg { + return detail::get_arg(context_, parse_context_.next_arg_id()); + } + + FMT_CONSTEXPR auto get_arg(int arg_id) -> format_arg { + parse_context_.check_arg_id(arg_id); + return detail::get_arg(context_, arg_id); + } + + FMT_CONSTEXPR auto get_arg(basic_string_view<Char> arg_id) -> format_arg { + parse_context_.check_arg_id(arg_id); + return detail::get_arg(context_, arg_id); + } + + public: + FMT_CONSTEXPR specs_handler(basic_format_specs<Char>& specs, + basic_format_parse_context<Char>& parse_ctx, + buffer_context<Char>& ctx) + : specs_setter<Char>(specs), parse_context_(parse_ctx), context_(ctx) {} + + template <typename Id> FMT_CONSTEXPR void on_dynamic_width(Id arg_id) { + this->specs_.width = get_dynamic_spec<width_checker>( + get_arg(arg_id), context_.error_handler()); + } + + template <typename Id> FMT_CONSTEXPR void on_dynamic_precision(Id arg_id) { + this->specs_.precision = get_dynamic_spec<precision_checker>( + get_arg(arg_id), context_.error_handler()); + } + + void on_error(const char* message) { context_.on_error(message); } +}; + +template <template <typename> class Handler, typename Context> +FMT_CONSTEXPR void handle_dynamic_spec(int& value, + arg_ref<typename Context::char_type> ref, + Context& ctx) { + switch (ref.kind) { + case arg_id_kind::none: + break; + case arg_id_kind::index: + value = detail::get_dynamic_spec<Handler>(ctx.arg(ref.val.index), + ctx.error_handler()); + break; + case arg_id_kind::name: + value = detail::get_dynamic_spec<Handler>(ctx.arg(ref.val.name), + ctx.error_handler()); + break; + } +} + +#define FMT_STRING_IMPL(s, base, explicit) \ + [] { \ + /* Use the hidden visibility as a workaround for a GCC bug (#1973). */ \ + /* Use a macro-like name to avoid shadowing warnings. */ \ + struct FMT_GCC_VISIBILITY_HIDDEN FMT_COMPILE_STRING : base { \ + using char_type = fmt::remove_cvref_t<decltype(s[0])>; \ + FMT_MAYBE_UNUSED FMT_CONSTEXPR explicit \ + operator fmt::basic_string_view<char_type>() const { \ + return fmt::detail_exported::compile_string_to_view<char_type>(s); \ + } \ + }; \ + return FMT_COMPILE_STRING(); \ + }() + +/** + \rst + Constructs a compile-time format string from a string literal *s*. + + **Example**:: + + // A compile-time error because 'd' is an invalid specifier for strings. + std::string s = fmt::format(FMT_STRING("{:d}"), "foo"); + \endrst + */ +#define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::compile_string, ) + +#if FMT_USE_USER_DEFINED_LITERALS +template <typename Char> struct udl_formatter { + basic_string_view<Char> str; + + template <typename... T> + auto operator()(T&&... args) const -> std::basic_string<Char> { + return vformat(str, fmt::make_args_checked<T...>(str, args...)); + } +}; + +# if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS +template <typename T, typename Char, size_t N, + fmt::detail_exported::fixed_string<Char, N> Str> +struct statically_named_arg : view { + static constexpr auto name = Str.data; + + const T& value; + statically_named_arg(const T& v) : value(v) {} +}; + +template <typename T, typename Char, size_t N, + fmt::detail_exported::fixed_string<Char, N> Str> +struct is_named_arg<statically_named_arg<T, Char, N, Str>> : std::true_type {}; + +template <typename T, typename Char, size_t N, + fmt::detail_exported::fixed_string<Char, N> Str> +struct is_statically_named_arg<statically_named_arg<T, Char, N, Str>> + : std::true_type {}; + +template <typename Char, size_t N, + fmt::detail_exported::fixed_string<Char, N> Str> +struct udl_arg { + template <typename T> auto operator=(T&& value) const { + return statically_named_arg<T, Char, N, Str>(std::forward<T>(value)); + } +}; +# else +template <typename Char> struct udl_arg { + const Char* str; + + template <typename T> auto operator=(T&& value) const -> named_arg<Char, T> { + return {str, std::forward<T>(value)}; + } +}; +# endif +#endif // FMT_USE_USER_DEFINED_LITERALS + +template <typename Locale, typename Char> +auto vformat(const Locale& loc, basic_string_view<Char> format_str, + basic_format_args<buffer_context<type_identity_t<Char>>> args) + -> std::basic_string<Char> { + basic_memory_buffer<Char> buffer; + detail::vformat_to(buffer, format_str, args, detail::locale_ref(loc)); + return {buffer.data(), buffer.size()}; +} + +using format_func = void (*)(detail::buffer<char>&, int, const char*); + +FMT_API void format_error_code(buffer<char>& out, int error_code, + string_view message) FMT_NOEXCEPT; + +FMT_API void report_error(format_func func, int error_code, + const char* message) FMT_NOEXCEPT; +FMT_END_DETAIL_NAMESPACE + +FMT_API auto vsystem_error(int error_code, string_view format_str, + format_args args) -> std::system_error; + +/** + \rst + Constructs :class:`std::system_error` with a message formatted with + ``fmt::format(fmt, args...)``. + *error_code* is a system error code as given by ``errno``. + + **Example**:: + + // This throws std::system_error with the description + // cannot open file 'madeup': No such file or directory + // or similar (system message may vary). + const char* filename = "madeup"; + std::FILE* file = std::fopen(filename, "r"); + if (!file) + throw fmt::system_error(errno, "cannot open file '{}'", filename); + \endrst +*/ +template <typename... T> +auto system_error(int error_code, format_string<T...> fmt, T&&... args) + -> std::system_error { + return vsystem_error(error_code, fmt, fmt::make_format_args(args...)); +} + +/** + \rst + Formats an error message for an error returned by an operating system or a + language runtime, for example a file opening error, and writes it to *out*. + The format is the same as the one used by ``std::system_error(ec, message)`` + where ``ec`` is ``std::error_code(error_code, std::generic_category()})``. + It is implementation-defined but normally looks like: + + .. parsed-literal:: + *<message>*: *<system-message>* + + where *<message>* is the passed message and *<system-message>* is the system + message corresponding to the error code. + *error_code* is a system error code as given by ``errno``. + \endrst + */ +FMT_API void format_system_error(detail::buffer<char>& out, int error_code, + const char* message) FMT_NOEXCEPT; + +// Reports a system error without throwing an exception. +// Can be used to report errors from destructors. +FMT_API void report_system_error(int error_code, + const char* message) FMT_NOEXCEPT; + +/** Fast integer formatter. */ +class format_int { + private: + // Buffer should be large enough to hold all digits (digits10 + 1), + // a sign and a null character. + enum { buffer_size = std::numeric_limits<unsigned long long>::digits10 + 3 }; + mutable char buffer_[buffer_size]; + char* str_; + + template <typename UInt> auto format_unsigned(UInt value) -> char* { + auto n = static_cast<detail::uint32_or_64_or_128_t<UInt>>(value); + return detail::format_decimal(buffer_, n, buffer_size - 1).begin; + } + + template <typename Int> auto format_signed(Int value) -> char* { + auto abs_value = static_cast<detail::uint32_or_64_or_128_t<Int>>(value); + bool negative = value < 0; + if (negative) abs_value = 0 - abs_value; + auto begin = format_unsigned(abs_value); + if (negative) *--begin = '-'; + return begin; + } + + public: + explicit format_int(int value) : str_(format_signed(value)) {} + explicit format_int(long value) : str_(format_signed(value)) {} + explicit format_int(long long value) : str_(format_signed(value)) {} + explicit format_int(unsigned value) : str_(format_unsigned(value)) {} + explicit format_int(unsigned long value) : str_(format_unsigned(value)) {} + explicit format_int(unsigned long long value) + : str_(format_unsigned(value)) {} + + /** Returns the number of characters written to the output buffer. */ + auto size() const -> size_t { + return detail::to_unsigned(buffer_ - str_ + buffer_size - 1); + } + + /** + Returns a pointer to the output buffer content. No terminating null + character is appended. + */ + auto data() const -> const char* { return str_; } + + /** + Returns a pointer to the output buffer content with terminating null + character appended. + */ + auto c_str() const -> const char* { + buffer_[buffer_size - 1] = '\0'; + return str_; + } + + /** + \rst + Returns the content of the output buffer as an ``std::string``. + \endrst + */ + auto str() const -> std::string { return std::string(str_, size()); } +}; + +template <typename T, typename Char> +template <typename FormatContext> +FMT_CONSTEXPR FMT_INLINE auto +formatter<T, Char, + enable_if_t<detail::type_constant<T, Char>::value != + detail::type::custom_type>>::format(const T& val, + FormatContext& ctx) + const -> decltype(ctx.out()) { + if (specs_.width_ref.kind != detail::arg_id_kind::none || + specs_.precision_ref.kind != detail::arg_id_kind::none) { + auto specs = specs_; + detail::handle_dynamic_spec<detail::width_checker>(specs.width, + specs.width_ref, ctx); + detail::handle_dynamic_spec<detail::precision_checker>( + specs.precision, specs.precision_ref, ctx); + return detail::write<Char>(ctx.out(), val, specs, ctx.locale()); + } + return detail::write<Char>(ctx.out(), val, specs_, ctx.locale()); +} + +#define FMT_FORMAT_AS(Type, Base) \ + template <typename Char> \ + struct formatter<Type, Char> : formatter<Base, Char> { \ + template <typename FormatContext> \ + auto format(Type const& val, FormatContext& ctx) const \ + -> decltype(ctx.out()) { \ + return formatter<Base, Char>::format(static_cast<Base>(val), ctx); \ + } \ + } + +FMT_FORMAT_AS(signed char, int); +FMT_FORMAT_AS(unsigned char, unsigned); +FMT_FORMAT_AS(short, int); +FMT_FORMAT_AS(unsigned short, unsigned); +FMT_FORMAT_AS(long, long long); +FMT_FORMAT_AS(unsigned long, unsigned long long); +FMT_FORMAT_AS(Char*, const Char*); +FMT_FORMAT_AS(std::basic_string<Char>, basic_string_view<Char>); +FMT_FORMAT_AS(std::nullptr_t, const void*); +FMT_FORMAT_AS(detail::byte, unsigned char); +FMT_FORMAT_AS(detail::std_string_view<Char>, basic_string_view<Char>); + +template <typename Char> +struct formatter<void*, Char> : formatter<const void*, Char> { + template <typename FormatContext> + auto format(void* val, FormatContext& ctx) const -> decltype(ctx.out()) { + return formatter<const void*, Char>::format(val, ctx); + } +}; + +template <typename Char, size_t N> +struct formatter<Char[N], Char> : formatter<basic_string_view<Char>, Char> { + template <typename FormatContext> + FMT_CONSTEXPR auto format(const Char* val, FormatContext& ctx) const + -> decltype(ctx.out()) { + return formatter<basic_string_view<Char>, Char>::format(val, ctx); + } +}; + +// A formatter for types known only at run time such as variant alternatives. +// +// Usage: +// using variant = std::variant<int, std::string>; +// template <> +// struct formatter<variant>: dynamic_formatter<> { +// auto format(const variant& v, format_context& ctx) { +// return visit([&](const auto& val) { +// return dynamic_formatter<>::format(val, ctx); +// }, v); +// } +// }; +template <typename Char = char> class dynamic_formatter { + private: + detail::dynamic_format_specs<Char> specs_; + const Char* format_str_; + + struct null_handler : detail::error_handler { + void on_align(align_t) {} + void on_sign(sign_t) {} + void on_hash() {} + }; + + template <typename Context> void handle_specs(Context& ctx) { + detail::handle_dynamic_spec<detail::width_checker>(specs_.width, + specs_.width_ref, ctx); + detail::handle_dynamic_spec<detail::precision_checker>( + specs_.precision, specs_.precision_ref, ctx); + } + + public: + template <typename ParseContext> + FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { + format_str_ = ctx.begin(); + // Checks are deferred to formatting time when the argument type is known. + detail::dynamic_specs_handler<ParseContext> handler(specs_, ctx); + return detail::parse_format_specs(ctx.begin(), ctx.end(), handler); + } + + template <typename T, typename FormatContext> + auto format(const T& val, FormatContext& ctx) -> decltype(ctx.out()) { + handle_specs(ctx); + detail::specs_checker<null_handler> checker( + null_handler(), detail::mapped_type_constant<T, FormatContext>::value); + checker.on_align(specs_.align); + if (specs_.sign != sign::none) checker.on_sign(specs_.sign); + if (specs_.alt) checker.on_hash(); + if (specs_.precision >= 0) checker.end_precision(); + return detail::write<Char>(ctx.out(), val, specs_, ctx.locale()); + } +}; + +/** + \rst + Converts ``p`` to ``const void*`` for pointer formatting. + + **Example**:: + + auto s = fmt::format("{}", fmt::ptr(p)); + \endrst + */ +template <typename T> auto ptr(T p) -> const void* { + static_assert(std::is_pointer<T>::value, ""); + return detail::bit_cast<const void*>(p); +} +template <typename T> auto ptr(const std::unique_ptr<T>& p) -> const void* { + return p.get(); +} +template <typename T> auto ptr(const std::shared_ptr<T>& p) -> const void* { + return p.get(); +} + +class bytes { + private: + string_view data_; + friend struct formatter<bytes>; + + public: + explicit bytes(string_view data) : data_(data) {} +}; + +template <> struct formatter<bytes> { + private: + detail::dynamic_format_specs<char> specs_; + + public: + template <typename ParseContext> + FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { + using handler_type = detail::dynamic_specs_handler<ParseContext>; + detail::specs_checker<handler_type> handler(handler_type(specs_, ctx), + detail::type::string_type); + auto it = parse_format_specs(ctx.begin(), ctx.end(), handler); + detail::check_string_type_spec(specs_.type, ctx.error_handler()); + return it; + } + + template <typename FormatContext> + auto format(bytes b, FormatContext& ctx) -> decltype(ctx.out()) { + detail::handle_dynamic_spec<detail::width_checker>(specs_.width, + specs_.width_ref, ctx); + detail::handle_dynamic_spec<detail::precision_checker>( + specs_.precision, specs_.precision_ref, ctx); + return detail::write_bytes(ctx.out(), b.data_, specs_); + } +}; + +// group_digits_view is not derived from view because it copies the argument. +template <typename T> struct group_digits_view { T value; }; + +/** + \rst + Returns a view that formats an integer value using ',' as a locale-independent + thousands separator. + + **Example**:: + + fmt::print("{}", fmt::group_digits(12345)); + // Output: "12,345" + \endrst + */ +template <typename T> auto group_digits(T value) -> group_digits_view<T> { + return {value}; +} + +template <typename T> struct formatter<group_digits_view<T>> : formatter<T> { + private: + detail::dynamic_format_specs<char> specs_; + + public: + template <typename ParseContext> + FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { + using handler_type = detail::dynamic_specs_handler<ParseContext>; + detail::specs_checker<handler_type> handler(handler_type(specs_, ctx), + detail::type::int_type); + auto it = parse_format_specs(ctx.begin(), ctx.end(), handler); + detail::check_string_type_spec(specs_.type, ctx.error_handler()); + return it; + } + + template <typename FormatContext> + auto format(group_digits_view<T> t, FormatContext& ctx) + -> decltype(ctx.out()) { + detail::handle_dynamic_spec<detail::width_checker>(specs_.width, + specs_.width_ref, ctx); + detail::handle_dynamic_spec<detail::precision_checker>( + specs_.precision, specs_.precision_ref, ctx); + return detail::write_int_localized( + ctx.out(), static_cast<detail::uint64_or_128_t<T>>(t.value), 0, specs_, + detail::digit_grouping<char>({"\3", ','})); + } +}; + +template <typename It, typename Sentinel, typename Char = char> +struct join_view : detail::view { + It begin; + Sentinel end; + basic_string_view<Char> sep; + + join_view(It b, Sentinel e, basic_string_view<Char> s) + : begin(b), end(e), sep(s) {} +}; + +template <typename It, typename Sentinel, typename Char> +using arg_join FMT_DEPRECATED_ALIAS = join_view<It, Sentinel, Char>; + +template <typename It, typename Sentinel, typename Char> +struct formatter<join_view<It, Sentinel, Char>, Char> { + private: + using value_type = +#ifdef __cpp_lib_ranges + std::iter_value_t<It>; +#else + typename std::iterator_traits<It>::value_type; +#endif + using context = buffer_context<Char>; + using mapper = detail::arg_mapper<context>; + + template <typename T, FMT_ENABLE_IF(has_formatter<T, context>::value)> + static auto map(const T& value) -> const T& { + return value; + } + template <typename T, FMT_ENABLE_IF(!has_formatter<T, context>::value)> + static auto map(const T& value) -> decltype(mapper().map(value)) { + return mapper().map(value); + } + + using formatter_type = + conditional_t<is_formattable<value_type, Char>::value, + formatter<remove_cvref_t<decltype(map( + std::declval<const value_type&>()))>, + Char>, + detail::fallback_formatter<value_type, Char>>; + + formatter_type value_formatter_; + + public: + template <typename ParseContext> + FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { + return value_formatter_.parse(ctx); + } + + template <typename FormatContext> + auto format(const join_view<It, Sentinel, Char>& value, FormatContext& ctx) + -> decltype(ctx.out()) { + auto it = value.begin; + auto out = ctx.out(); + if (it != value.end) { + out = value_formatter_.format(map(*it), ctx); + ++it; + while (it != value.end) { + out = detail::copy_str<Char>(value.sep.begin(), value.sep.end(), out); + ctx.advance_to(out); + out = value_formatter_.format(map(*it), ctx); + ++it; + } + } + return out; + } +}; + +/** + Returns a view that formats the iterator range `[begin, end)` with elements + separated by `sep`. + */ +template <typename It, typename Sentinel> +auto join(It begin, Sentinel end, string_view sep) -> join_view<It, Sentinel> { + return {begin, end, sep}; +} + +/** + \rst + Returns a view that formats `range` with elements separated by `sep`. + + **Example**:: + + std::vector<int> v = {1, 2, 3}; + fmt::print("{}", fmt::join(v, ", ")); + // Output: "1, 2, 3" + + ``fmt::join`` applies passed format specifiers to the range elements:: + + fmt::print("{:02}", fmt::join(v, ", ")); + // Output: "01, 02, 03" + \endrst + */ +template <typename Range> +auto join(Range&& range, string_view sep) + -> join_view<detail::iterator_t<Range>, detail::sentinel_t<Range>> { + return join(std::begin(range), std::end(range), sep); +} + +/** + \rst + Converts *value* to ``std::string`` using the default format for type *T*. + + **Example**:: + + #include <fmt/format.h> + + std::string answer = fmt::to_string(42); + \endrst + */ +template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)> +inline auto to_string(const T& value) -> std::string { + auto result = std::string(); + detail::write<char>(std::back_inserter(result), value); + return result; +} + +template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)> +FMT_NODISCARD inline auto to_string(T value) -> std::string { + // The buffer should be large enough to store the number including the sign + // or "false" for bool. + constexpr int max_size = detail::digits10<T>() + 2; + char buffer[max_size > 5 ? static_cast<unsigned>(max_size) : 5]; + char* begin = buffer; + return std::string(begin, detail::write<char>(begin, value)); +} + +template <typename Char, size_t SIZE> +FMT_NODISCARD auto to_string(const basic_memory_buffer<Char, SIZE>& buf) + -> std::basic_string<Char> { + auto size = buf.size(); + detail::assume(size < std::basic_string<Char>().max_size()); + return std::basic_string<Char>(buf.data(), size); +} + +FMT_BEGIN_DETAIL_NAMESPACE + +template <typename Char> +void vformat_to( + buffer<Char>& buf, basic_string_view<Char> fmt, + basic_format_args<FMT_BUFFER_CONTEXT(type_identity_t<Char>)> args, + locale_ref loc) { + // workaround for msvc bug regarding name-lookup in module + // link names into function scope + using detail::arg_formatter; + using detail::buffer_appender; + using detail::custom_formatter; + using detail::default_arg_formatter; + using detail::get_arg; + using detail::locale_ref; + using detail::parse_format_specs; + using detail::specs_checker; + using detail::specs_handler; + using detail::to_unsigned; + using detail::type; + using detail::write; + auto out = buffer_appender<Char>(buf); + if (fmt.size() == 2 && equal2(fmt.data(), "{}")) { + auto arg = args.get(0); + if (!arg) error_handler().on_error("argument not found"); + visit_format_arg(default_arg_formatter<Char>{out, args, loc}, arg); + return; + } + + struct format_handler : error_handler { + basic_format_parse_context<Char> parse_context; + buffer_context<Char> context; + + format_handler(buffer_appender<Char> out, basic_string_view<Char> str, + basic_format_args<buffer_context<Char>> args, locale_ref loc) + : parse_context(str), context(out, args, loc) {} + + void on_text(const Char* begin, const Char* end) { + auto text = basic_string_view<Char>(begin, to_unsigned(end - begin)); + context.advance_to(write<Char>(context.out(), text)); + } + + FMT_CONSTEXPR auto on_arg_id() -> int { + return parse_context.next_arg_id(); + } + FMT_CONSTEXPR auto on_arg_id(int id) -> int { + return parse_context.check_arg_id(id), id; + } + FMT_CONSTEXPR auto on_arg_id(basic_string_view<Char> id) -> int { + int arg_id = context.arg_id(id); + if (arg_id < 0) on_error("argument not found"); + return arg_id; + } + + FMT_INLINE void on_replacement_field(int id, const Char*) { + auto arg = get_arg(context, id); + context.advance_to(visit_format_arg( + default_arg_formatter<Char>{context.out(), context.args(), + context.locale()}, + arg)); + } + + auto on_format_specs(int id, const Char* begin, const Char* end) + -> const Char* { + auto arg = get_arg(context, id); + if (arg.type() == type::custom_type) { + parse_context.advance_to(parse_context.begin() + + (begin - &*parse_context.begin())); + visit_format_arg(custom_formatter<Char>{parse_context, context}, arg); + return parse_context.begin(); + } + auto specs = basic_format_specs<Char>(); + specs_checker<specs_handler<Char>> handler( + specs_handler<Char>(specs, parse_context, context), arg.type()); + begin = parse_format_specs(begin, end, handler); + if (begin == end || *begin != '}') + on_error("missing '}' in format string"); + auto f = arg_formatter<Char>{context.out(), specs, context.locale()}; + context.advance_to(visit_format_arg(f, arg)); + return begin; + } + }; + detail::parse_format_string<false>(fmt, format_handler(out, fmt, args, loc)); +} + +#ifndef FMT_HEADER_ONLY +extern template FMT_API auto thousands_sep_impl<char>(locale_ref) + -> thousands_sep_result<char>; +extern template FMT_API auto thousands_sep_impl<wchar_t>(locale_ref) + -> thousands_sep_result<wchar_t>; +extern template FMT_API auto decimal_point_impl(locale_ref) -> char; +extern template FMT_API auto decimal_point_impl(locale_ref) -> wchar_t; +extern template auto format_float<double>(double value, int precision, + float_specs specs, buffer<char>& buf) + -> int; +extern template auto format_float<long double>(long double value, int precision, + float_specs specs, + buffer<char>& buf) -> int; +void snprintf_float(float, int, float_specs, buffer<char>&) = delete; +extern template auto snprintf_float<double>(double value, int precision, + float_specs specs, + buffer<char>& buf) -> int; +extern template auto snprintf_float<long double>(long double value, + int precision, + float_specs specs, + buffer<char>& buf) -> int; +#endif // FMT_HEADER_ONLY + +FMT_END_DETAIL_NAMESPACE + +#if FMT_USE_USER_DEFINED_LITERALS +inline namespace literals { +/** + \rst + User-defined literal equivalent of :func:`fmt::arg`. + + **Example**:: + + using namespace fmt::literals; + fmt::print("Elapsed time: {s:.2f} seconds", "s"_a=1.23); + \endrst + */ +# if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS +template <detail_exported::fixed_string Str> +constexpr auto operator""_a() + -> detail::udl_arg<remove_cvref_t<decltype(Str.data[0])>, + sizeof(Str.data) / sizeof(decltype(Str.data[0])), Str> { + return {}; +} +# else +constexpr auto operator"" _a(const char* s, size_t) -> detail::udl_arg<char> { + return {s}; +} +# endif + +// DEPRECATED! +// User-defined literal equivalent of fmt::format. +FMT_DEPRECATED constexpr auto operator"" _format(const char* s, size_t n) + -> detail::udl_formatter<char> { + return {{s, n}}; +} +} // namespace literals +#endif // FMT_USE_USER_DEFINED_LITERALS + +template <typename Locale, FMT_ENABLE_IF(detail::is_locale<Locale>::value)> +inline auto vformat(const Locale& loc, string_view fmt, format_args args) + -> std::string { + return detail::vformat(loc, fmt, args); +} + +template <typename Locale, typename... T, + FMT_ENABLE_IF(detail::is_locale<Locale>::value)> +inline auto format(const Locale& loc, format_string<T...> fmt, T&&... args) + -> std::string { + return vformat(loc, string_view(fmt), fmt::make_format_args(args...)); +} + +template <typename... T, size_t SIZE, typename Allocator> +FMT_DEPRECATED auto format_to(basic_memory_buffer<char, SIZE, Allocator>& buf, + format_string<T...> fmt, T&&... args) + -> appender { + detail::vformat_to(buf, string_view(fmt), fmt::make_format_args(args...)); + return appender(buf); +} + +template <typename OutputIt, typename Locale, + FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value&& + detail::is_locale<Locale>::value)> +auto vformat_to(OutputIt out, const Locale& loc, string_view fmt, + format_args args) -> OutputIt { + using detail::get_buffer; + auto&& buf = get_buffer<char>(out); + detail::vformat_to(buf, fmt, args, detail::locale_ref(loc)); + return detail::get_iterator(buf); +} + +template <typename OutputIt, typename Locale, typename... T, + FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value&& + detail::is_locale<Locale>::value)> +FMT_INLINE auto format_to(OutputIt out, const Locale& loc, + format_string<T...> fmt, T&&... args) -> OutputIt { + return vformat_to(out, loc, fmt, fmt::make_format_args(args...)); +} + +FMT_MODULE_EXPORT_END +FMT_END_NAMESPACE + +#ifdef FMT_DEPRECATED_INCLUDE_XCHAR +# include "xchar.h" +#endif + +#ifdef FMT_HEADER_ONLY +# define FMT_FUNC inline +# include "format-inl.h" +#else +# define FMT_FUNC +#endif + +#endif // FMT_FORMAT_H_ diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 4f78fbfc9e7..24cc5735c96 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -1480,7 +1480,7 @@ class CyclesPreferences(bpy.types.AddonPreferences): col.label(text="and NVIDIA driver version 470 or newer", icon='BLANK1') elif device_type == 'HIP': import sys - col.label(text="Requires discrete AMD GPU with RDNA architecture", icon='BLANK1') + col.label(text="Requires discrete AMD GPU with Vega architecture", icon='BLANK1') if sys.platform[:3] == "win": col.label(text="and AMD Radeon Pro 21.Q4 driver or newer", icon='BLANK1') elif device_type == 'METAL': diff --git a/intern/cycles/cmake/macros.cmake b/intern/cycles/cmake/macros.cmake index 0f2e1b50434..e69e31f8e52 100644 --- a/intern/cycles/cmake/macros.cmake +++ b/intern/cycles/cmake/macros.cmake @@ -101,6 +101,7 @@ macro(cycles_target_link_libraries target) ${PNG_LIBRARIES} ${JPEG_LIBRARIES} ${TIFF_LIBRARY} + ${WEBP_LIBRARIES} ${OPENJPEG_LIBRARIES} ${OPENEXR_LIBRARIES} ${OPENEXR_LIBRARIES} # For circular dependencies between libs. diff --git a/intern/cycles/device/hip/util.h b/intern/cycles/device/hip/util.h index adb68a2d44c..4e4906171d1 100644 --- a/intern/cycles/device/hip/util.h +++ b/intern/cycles/device/hip/util.h @@ -51,7 +51,7 @@ static inline bool hipSupportsDevice(const int hipDevId) hipDeviceGetAttribute(&major, hipDeviceAttributeComputeCapabilityMajor, hipDevId); hipDeviceGetAttribute(&minor, hipDeviceAttributeComputeCapabilityMinor, hipDevId); - return (major > 10) || (major == 10 && minor >= 1); + return (major >= 9); } CCL_NAMESPACE_END diff --git a/intern/cycles/hydra/curves.h b/intern/cycles/hydra/curves.h index a1ac4a86715..1eb4a51c0db 100644 --- a/intern/cycles/hydra/curves.h +++ b/intern/cycles/hydra/curves.h @@ -13,10 +13,11 @@ HDCYCLES_NAMESPACE_OPEN_SCOPE class HdCyclesCurves final : public HdCyclesGeometry<PXR_NS::HdBasisCurves, CCL_NS::Hair> { public: - HdCyclesCurves(const PXR_NS::SdfPath &rprimId + HdCyclesCurves( + const PXR_NS::SdfPath &rprimId #if PXR_VERSION < 2102 - , - const PXR_NS::SdfPath &instancerId = {} + , + const PXR_NS::SdfPath &instancerId = {} #endif ); ~HdCyclesCurves() override; diff --git a/intern/cycles/hydra/mesh.h b/intern/cycles/hydra/mesh.h index e7aa2e4fa94..8ec108534a1 100644 --- a/intern/cycles/hydra/mesh.h +++ b/intern/cycles/hydra/mesh.h @@ -14,10 +14,11 @@ HDCYCLES_NAMESPACE_OPEN_SCOPE class HdCyclesMesh final : public HdCyclesGeometry<PXR_NS::HdMesh, CCL_NS::Mesh> { public: - HdCyclesMesh(const PXR_NS::SdfPath &rprimId + HdCyclesMesh( + const PXR_NS::SdfPath &rprimId #if PXR_VERSION < 2102 - , - const PXR_NS::SdfPath &instancerId = {} + , + const PXR_NS::SdfPath &instancerId = {} #endif ); ~HdCyclesMesh() override; diff --git a/intern/cycles/hydra/node_util.h b/intern/cycles/hydra/node_util.h index e91f554cc45..009a4a9eb38 100644 --- a/intern/cycles/hydra/node_util.h +++ b/intern/cycles/hydra/node_util.h @@ -4,8 +4,8 @@ #pragma once -#include "hydra/config.h" #include "graph/node.h" +#include "hydra/config.h" #include <pxr/base/vt/value.h> diff --git a/intern/cycles/hydra/pointcloud.h b/intern/cycles/hydra/pointcloud.h index aa1768e807f..a014a389dcc 100644 --- a/intern/cycles/hydra/pointcloud.h +++ b/intern/cycles/hydra/pointcloud.h @@ -13,10 +13,11 @@ HDCYCLES_NAMESPACE_OPEN_SCOPE class HdCyclesPoints final : public HdCyclesGeometry<PXR_NS::HdPoints, CCL_NS::PointCloud> { public: - HdCyclesPoints(const PXR_NS::SdfPath &rprimId + HdCyclesPoints( + const PXR_NS::SdfPath &rprimId #if PXR_VERSION < 2102 - , - const PXR_NS::SdfPath &instancerId = {} + , + const PXR_NS::SdfPath &instancerId = {} #endif ); ~HdCyclesPoints() override; diff --git a/intern/cycles/hydra/volume.h b/intern/cycles/hydra/volume.h index 775a7cf069e..7fb5fa779b5 100644 --- a/intern/cycles/hydra/volume.h +++ b/intern/cycles/hydra/volume.h @@ -13,10 +13,11 @@ HDCYCLES_NAMESPACE_OPEN_SCOPE class HdCyclesVolume final : public HdCyclesGeometry<PXR_NS::HdVolume, CCL_NS::Volume> { public: - HdCyclesVolume(const PXR_NS::SdfPath &rprimId + HdCyclesVolume( + const PXR_NS::SdfPath &rprimId #if PXR_VERSION < 2102 - , - const PXR_NS::SdfPath &instancerId = {} + , + const PXR_NS::SdfPath &instancerId = {} #endif ); ~HdCyclesVolume() override; diff --git a/intern/cycles/kernel/closure/bsdf_hair_principled.h b/intern/cycles/kernel/closure/bsdf_hair_principled.h index fb65d744a0c..33706213403 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_principled.h +++ b/intern/cycles/kernel/closure/bsdf_hair_principled.h @@ -220,7 +220,7 @@ ccl_device_inline void hair_attenuation(KernelGlobals kg, ccl_private float4 *Ap) { /* Primary specular (R). */ - Ap[0] = make_float4(f); + Ap[0] = make_float4(f, f, f, f); /* Transmission (TT). */ float3 col = sqr(1.0f - f) * T; diff --git a/intern/cycles/kernel/device/cpu/image.h b/intern/cycles/kernel/device/cpu/image.h index ebddc1989bd..3b714a3e580 100644 --- a/intern/cycles/kernel/device/cpu/image.h +++ b/intern/cycles/kernel/device/cpu/image.h @@ -31,20 +31,18 @@ ccl_device_inline float frac(float x, int *ix) return x - (float)i; } -template<typename ZeroT> ccl_always_inline ZeroT zero(); - -template<> ccl_always_inline float zero<float>() -{ - return 0.0f; -} - -template<> ccl_always_inline float4 zero<float4>() -{ - return zero_float4(); -} - template<typename TexT, typename OutT = float4> struct TextureInterpolator { + static ccl_always_inline OutT zero() + { + if constexpr (std::is_same<OutT, float4>::value) { + return zero_float4(); + } + else { + return 0.0f; + } + } + static ccl_always_inline float4 read(float4 r) { return r; @@ -99,7 +97,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator { static ccl_always_inline OutT read_clip(const TexT *data, int x, int y, int width, int height) { if (x < 0 || x >= width || y < 0 || y >= height) { - return zero<OutT>(); + return zero(); } return read(data[y * width + x]); } @@ -118,7 +116,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator { read_clip(const TexT *data, int x, int y, int z, int width, int height, int depth) { if (x < 0 || x >= width || y < 0 || y >= height || z < 0 || z >= depth) { - return zero<OutT>(); + return zero(); } return read(data[x + y * width + z * width * height]); } @@ -221,7 +219,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator { case EXTENSION_CLIP: /* No samples are inside the clip region. */ if (ix < 0 || ix >= width || iy < 0 || iy >= height) { - return zero<OutT>(); + return zero(); } break; case EXTENSION_EXTEND: @@ -230,7 +228,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator { break; default: kernel_assert(0); - return zero<OutT>(); + return zero(); } const TexT *data = (const TexT *)info.data; @@ -259,7 +257,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator { case EXTENSION_CLIP: /* No linear samples are inside the clip region. */ if (ix < -1 || ix >= width || iy < -1 || iy >= height) { - return zero<OutT>(); + return zero(); } nix = ix + 1; niy = iy + 1; @@ -272,7 +270,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator { break; default: kernel_assert(0); - return zero<OutT>(); + return zero(); } const TexT *data = (const TexT *)info.data; @@ -311,7 +309,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator { case EXTENSION_CLIP: /* No cubic samples are inside the clip region. */ if (ix < -2 || ix > width || iy < -2 || iy > height) { - return zero<OutT>(); + return zero(); } pix = ix - 1; @@ -335,7 +333,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator { break; default: kernel_assert(0); - return zero<OutT>(); + return zero(); } const TexT *data = (const TexT *)info.data; @@ -397,7 +395,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator { case EXTENSION_CLIP: /* No samples are inside the clip region. */ if (ix < 0 || ix >= width || iy < 0 || iy >= height || iz < 0 || iz >= depth) { - return zero<OutT>(); + return zero(); } break; case EXTENSION_EXTEND: @@ -407,7 +405,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator { break; default: kernel_assert(0); - return zero<OutT>(); + return zero(); } const TexT *data = (const TexT *)info.data; @@ -444,7 +442,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator { case EXTENSION_CLIP: /* No linear samples are inside the clip region. */ if (ix < -1 || ix >= width || iy < -1 || iy >= height || iz < -1 || iz >= depth) { - return zero<OutT>(); + return zero(); } nix = ix + 1; @@ -484,7 +482,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator { break; default: kernel_assert(0); - return zero<OutT>(); + return zero(); } return trilinear_lookup((const TexT *)info.data, @@ -553,7 +551,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator { case EXTENSION_CLIP: { /* No cubic samples are inside the clip region. */ if (ix < -2 || ix > width || iy < -2 || iy > height || iz < -2 || iz > depth) { - return zero<OutT>(); + return zero(); } pix = ix - 1; @@ -599,7 +597,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator { break; default: kernel_assert(0); - return zero<OutT>(); + return zero(); } const int xc[4] = {pix, ix, nix, nnix}; const int yc[4] = {piy, iy, niy, nniy}; diff --git a/intern/cycles/kernel/film/accumulate.h b/intern/cycles/kernel/film/accumulate.h index 6345430e4f4..d6a385a4bff 100644 --- a/intern/cycles/kernel/film/accumulate.h +++ b/intern/cycles/kernel/film/accumulate.h @@ -352,6 +352,12 @@ ccl_device_inline void kernel_accum_emission_or_background_pass(KernelGlobals kg pass_offset = pass; } else if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) { + /* Don't write any light passes for shadow catcher, for easier + * compositing back together of the combined pass. */ + if (path_flag & PATH_RAY_SHADOW_CATCHER_HIT) { + return; + } + if (path_flag & PATH_RAY_SURFACE_PASS) { /* Indirectly visible through reflection. */ const float3 diffuse_weight = INTEGRATOR_STATE(state, path, pass_diffuse_weight); @@ -437,6 +443,12 @@ ccl_device_inline void kernel_accum_light(KernelGlobals kg, if (kernel_data.film.light_pass_flag & PASS_ANY) { const uint32_t path_flag = INTEGRATOR_STATE(state, shadow_path, flag); + /* Don't write any light passes for shadow catcher, for easier + * compositing back together of the combined pass. */ + if (path_flag & PATH_RAY_SHADOW_CATCHER_HIT) { + return; + } + if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) { int pass_offset = PASS_UNUSED; diff --git a/intern/cycles/scene/integrator.cpp b/intern/cycles/scene/integrator.cpp index 755fbb9542b..fd559178073 100644 --- a/intern/cycles/scene/integrator.cpp +++ b/intern/cycles/scene/integrator.cpp @@ -109,8 +109,10 @@ NODE_DEFINE(Integrator) SOCKET_INT(denoise_start_sample, "Start Sample to Denoise", 0); SOCKET_BOOLEAN(use_denoise_pass_albedo, "Use Albedo Pass for Denoiser", true); SOCKET_BOOLEAN(use_denoise_pass_normal, "Use Normal Pass for Denoiser", true); - SOCKET_ENUM( - denoiser_prefilter, "Denoiser Prefilter", denoiser_prefilter_enum, DENOISER_PREFILTER_ACCURATE); + SOCKET_ENUM(denoiser_prefilter, + "Denoiser Prefilter", + denoiser_prefilter_enum, + DENOISER_PREFILTER_ACCURATE); return type; } diff --git a/intern/cycles/util/math_float4.h b/intern/cycles/util/math_float4.h index 5d4da7dd30f..ae9dfe75a9c 100644 --- a/intern/cycles/util/math_float4.h +++ b/intern/cycles/util/math_float4.h @@ -90,13 +90,13 @@ ccl_device_inline float4 zero_float4() #ifdef __KERNEL_SSE__ return float4(_mm_setzero_ps()); #else - return make_float4(0.0f); + return make_float4(0.0f, 0.0f, 0.0f, 0.0f); #endif } ccl_device_inline float4 one_float4() { - return make_float4(1.0f); + return make_float4(1.0f, 1.0f, 1.0f, 1.0f); } #if !defined(__KERNEL_METAL__) @@ -149,7 +149,7 @@ ccl_device_inline float4 operator/(const float4 &a, const float4 &b) ccl_device_inline float4 operator+(const float4 &a, const float f) { - return a + make_float4(f); + return a + make_float4(f, f, f, f); } ccl_device_inline float4 operator+(const float4 &a, const float4 &b) @@ -163,7 +163,7 @@ ccl_device_inline float4 operator+(const float4 &a, const float4 &b) ccl_device_inline float4 operator-(const float4 &a, const float f) { - return a - make_float4(f); + return a - make_float4(f, f, f, f); } ccl_device_inline float4 operator-(const float4 &a, const float4 &b) @@ -317,7 +317,7 @@ ccl_device_inline float4 reduce_add(const float4 &a) # endif # else float sum = (a.x + a.y) + (a.z + a.w); - return make_float4(sum); + return make_float4(sum, sum, sum, sum); # endif } diff --git a/intern/cycles/util/types_float4.h b/intern/cycles/util/types_float4.h index 0e84dfa3d64..68ba787dac0 100644 --- a/intern/cycles/util/types_float4.h +++ b/intern/cycles/util/types_float4.h @@ -45,7 +45,6 @@ ccl_device_inline float4 make_float4(const int4 &i); ccl_device_inline void print_float4(const char *label, const float4 &a); #endif /* __KERNEL_GPU__ */ -ccl_device_inline float4 make_float4(float f); CCL_NAMESPACE_END #endif /* __UTIL_TYPES_FLOAT4_H__ */ diff --git a/intern/cycles/util/types_float4_impl.h b/intern/cycles/util/types_float4_impl.h index aa923eb038d..de2e7cb7061 100644 --- a/intern/cycles/util/types_float4_impl.h +++ b/intern/cycles/util/types_float4_impl.h @@ -89,11 +89,6 @@ ccl_device_inline void print_float4(const char *label, const float4 &a) { printf("%s: %.8f %.8f %.8f %.8f\n", label, (double)a.x, (double)a.y, (double)a.z, (double)a.w); } -#else -ccl_device_inline float4 make_float4(float f) -{ - return make_float4(f, f, f, f); -} #endif /* __KERNEL_GPU__ */ CCL_NAMESPACE_END diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index 0f4b5147082..11a3c097958 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -151,6 +151,12 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system, ::SetWindowPos(m_hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); } + if (parentwindow) { + /* Release any parent capture to allow immediate interaction (T90110). */ + ::ReleaseCapture(); + parentwindow->lostMouseCapture(); + } + /* Show the window. */ int nCmdShow; switch (state) { diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h index 79b4e9d0cf6..d5f47871aff 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.h +++ b/intern/ghost/intern/GHOST_WindowWin32.h @@ -206,9 +206,7 @@ class GHOST_WindowWin32 : public GHOST_Window { GHOST_TSuccess endProgressBar(); /** - * Register a mouse capture state (should be called - * for any real button press, controls mouse - * capturing). + * Set or Release mouse capture (should be called for any real button press). * * \param event: Whether mouse was pressed and released, * or an operator grabbed or ungrabbed the mouse. @@ -216,8 +214,9 @@ class GHOST_WindowWin32 : public GHOST_Window { void updateMouseCapture(GHOST_MouseCaptureEventWin32 event); /** - * Inform the window that it has lost mouse capture, - * called in response to native window system messages. + * Inform the window that it has lost mouse capture, called in response to native window system + * messages (WA_INACTIVE, WM_CAPTURECHANGED) or if ReleaseCapture() is explicitly called (for new + * window creation). */ void lostMouseCapture(); diff --git a/intern/ghost/intern/GHOST_XrControllerModel.cpp b/intern/ghost/intern/GHOST_XrControllerModel.cpp index 78d81651e92..5be3a8e70ad 100644 --- a/intern/ghost/intern/GHOST_XrControllerModel.cpp +++ b/intern/ghost/intern/GHOST_XrControllerModel.cpp @@ -234,7 +234,7 @@ static void calc_node_transforms(const tinygltf::Node &gltf_node, {(float)dm[4], (float)dm[5], (float)dm[6], (float)dm[7]}, {(float)dm[8], (float)dm[9], (float)dm[10], (float)dm[11]}, {(float)dm[12], (float)dm[13], (float)dm[14], (float)dm[15]}}; - memcpy(r_local_transform, m, sizeof(float) * 16); + memcpy(r_local_transform, m, sizeof(float[4][4])); } else { /* No matrix is present, so construct a matrix from the TRS values (each one is optional). */ diff --git a/intern/itasc/WSDLSSolver.cpp b/intern/itasc/WSDLSSolver.cpp index 28d0e4de7ff..bd1f1407185 100644 --- a/intern/itasc/WSDLSSolver.cpp +++ b/intern/itasc/WSDLSSolver.cpp @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later * Copyright 2009 Ruben Smits. */ -/** \file itasc/WSDLSSolver.cpp +/** \file * \ingroup intern_itasc */ diff --git a/intern/opencolorio/ocio_impl_glsl.cc b/intern/opencolorio/ocio_impl_glsl.cc index 4de4d2caf15..fcaab5dd752 100644 --- a/intern/opencolorio/ocio_impl_glsl.cc +++ b/intern/opencolorio/ocio_impl_glsl.cc @@ -177,6 +177,7 @@ static bool createGPUShader(OCIO_GPUShader &shader, ShaderCreateInfo info("OCIO_Display"); /* Work around OpenColorIO not supporting latest GLSL yet. */ + info.define("texture1D", "texture"); info.define("texture2D", "texture"); info.define("texture3D", "texture"); info.typedef_source("ocio_shader_shared.hh"); @@ -206,8 +207,11 @@ static bool createGPUShader(OCIO_GPUShader &shader, /* Set LUT textures. */ int slot = TEXTURE_SLOT_LUTS_OFFSET; for (OCIO_GPULutTexture &texture : textures.luts) { - ImageType type = GPU_texture_dimensions(texture.texture) == 2 ? ImageType::FLOAT_2D : - ImageType::FLOAT_3D; + const int dimensions = GPU_texture_dimensions(texture.texture); + ImageType type = (dimensions == 1) ? ImageType::FLOAT_1D : + (dimensions == 2) ? ImageType::FLOAT_2D : + ImageType::FLOAT_3D; + info.sampler(slot++, type, texture.sampler_name.c_str()); } @@ -305,9 +309,9 @@ static bool addGPUUniform(OCIO_GPUTextures &textures, return true; } -static bool addGPULut2D(OCIO_GPUTextures &textures, - const GpuShaderDescRcPtr &shader_desc, - int index) +static bool addGPULut1D2D(OCIO_GPUTextures &textures, + const GpuShaderDescRcPtr &shader_desc, + int index) { const char *texture_name = nullptr; const char *sampler_name = nullptr; @@ -329,7 +333,15 @@ static bool addGPULut2D(OCIO_GPUTextures &textures, GPU_R16F; OCIO_GPULutTexture lut; - lut.texture = GPU_texture_create_2d(texture_name, width, height, 1, format, values); + /* There does not appear to be an explicit way to check if a texture is 1D or 2D. + * It depends on more than height. So check instead by looking at the source. */ + std::string sampler1D_name = std::string("sampler1D ") + sampler_name; + if (strstr(shader_desc->getShaderText(), sampler1D_name.c_str()) != nullptr) { + lut.texture = GPU_texture_create_1d(texture_name, width, 1, format, values); + } + else { + lut.texture = GPU_texture_create_2d(texture_name, width, height, 1, format, values); + } if (lut.texture == nullptr) { return false; } @@ -390,7 +402,7 @@ static bool createGPUTextures(OCIO_GPUTextures &textures, } } for (int index = 0; index < shaderdesc_to_scene_linear->getNumTextures(); index++) { - if (!addGPULut2D(textures, shaderdesc_to_scene_linear, index)) { + if (!addGPULut1D2D(textures, shaderdesc_to_scene_linear, index)) { return false; } } @@ -405,7 +417,7 @@ static bool createGPUTextures(OCIO_GPUTextures &textures, } } for (int index = 0; index < shaderdesc_to_display->getNumTextures(); index++) { - if (!addGPULut2D(textures, shaderdesc_to_display, index)) { + if (!addGPULut1D2D(textures, shaderdesc_to_display, index)) { return false; } } diff --git a/release/license/THIRD-PARTY-LICENSES.txt b/release/license/THIRD-PARTY-LICENSES.txt index 933f03b5564..59f53832c9b 100644 --- a/release/license/THIRD-PARTY-LICENSES.txt +++ b/release/license/THIRD-PARTY-LICENSES.txt @@ -2961,6 +2961,8 @@ Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors. ** Expat; version 2.2.10 -- https://github.com/libexpat/libexpat/ Copyright (c) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper Copyright (c) 2001-2019 Expat maintainers +** {fmt}; version 8.1.1 -- https://github.com/fmtlib/fmt +Copyright (c) 2012 - present, Victor Zverovich ** JSON for Modern C++; version 3.10.2 -- https://github.com/nlohmann/json/ Copyright (c) 2013-2021 Niels Lohmann ** Libxml2; version 2.9.10 -- http://xmlsoft.org/ diff --git a/release/scripts/modules/bl_i18n_utils/settings.py b/release/scripts/modules/bl_i18n_utils/settings.py index f8975d91f86..ef481a3eb19 100644 --- a/release/scripts/modules/bl_i18n_utils/settings.py +++ b/release/scripts/modules/bl_i18n_utils/settings.py @@ -340,7 +340,10 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = { "y", "y = (Ax + B)", # Sub-strings. + "all", + "all and invert unselected", "and AMD Radeon Pro 21.Q4 driver or newer", + "and NVIDIA driver version 470 or newer", "available with", "brown fox", "can't save image while rendering", @@ -358,6 +361,7 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = { "face data", "gimbal", "global", + "glTF Settings", "image file not found", "image format is read-only", "image path can't be written to", @@ -370,8 +374,12 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = { "multi-res modifier", "non-triangle face", "normal", + "or AMD with macOS 12.3 or newer", "performance impact!", "right", + "selected", + "selected and lock unselected", + "selected and unlock unselected", "the lazy dog", "to the top level of the tree", "unable to load movie clip", @@ -380,6 +388,7 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = { "unknown error reading file", "unknown error stating file", "unknown error writing file", + "unselected", "unsupported font format", "unsupported format", "unsupported image format", diff --git a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py index 144b7d09422..c0e065bf050 100644 --- a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py +++ b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py @@ -104,6 +104,7 @@ class SpellChecker: "builtin", "builtins", "bytecode", "chunksize", + "codebase", "customdata", "dataset", "datasets", "de", @@ -123,6 +124,7 @@ class SpellChecker: "filepath", "filepaths", "forcefield", "forcefields", "framerange", + "frontmost", "fulldome", "fulldomes", "fullscreen", "gamepad", diff --git a/release/scripts/modules/rna_manual_reference.py b/release/scripts/modules/rna_manual_reference.py index 4b10c29346e..1cd9cf9c649 100644 --- a/release/scripts/modules/rna_manual_reference.py +++ b/release/scripts/modules/rna_manual_reference.py @@ -344,7 +344,6 @@ url_manual_mapping = ( ("bpy.types.sequencerpreviewoverlay.show_metadata*", "editors/video_sequencer/preview/display/overlays.html#bpy-types-sequencerpreviewoverlay-show-metadata"), ("bpy.types.sequencertimelineoverlay.show_fcurves*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay-show-fcurves"), ("bpy.types.spaceclipeditor.use_grayscale_preview*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-use-grayscale-preview"), - ("bpy.types.spaceoutliner.use_filter_lib_override*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-lib-override"), ("bpy.types.spaceoutliner.use_filter_object_empty*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-empty"), ("bpy.types.spaceoutliner.use_filter_object_light*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-light"), ("bpy.types.spacesequenceeditor.proxy_render_size*", "video_editing/preview/sidebar.html#bpy-types-spacesequenceeditor-proxy-render-size"), diff --git a/release/scripts/presets/keyconfig/Blender.py b/release/scripts/presets/keyconfig/Blender.py index 8f9bea82358..7ce9a5650bd 100644 --- a/release/scripts/presets/keyconfig/Blender.py +++ b/release/scripts/presets/keyconfig/Blender.py @@ -87,6 +87,16 @@ class Prefs(bpy.types.KeyConfigPreferences): ) # Experimental: only show with developer extras, see: T96544. + use_tweak_select_passthrough: BoolProperty( + name="Tweak Select: Mouse Select & Move", + description=( + "The tweak tool is activated immediately instead of placing the cursor. " + "This is an experimental preference and may be removed" + ), + default=False, + update=update_fn, + ) + # Experimental: only show with developer extras, see: T96544. use_tweak_tool_lmb_interaction: BoolProperty( name="Tweak Tool: Left Mouse Select & Move", description=( @@ -283,6 +293,9 @@ class Prefs(bpy.types.KeyConfigPreferences): row = sub.row() row.prop(self, "use_select_all_toggle") + if show_developer_ui: + row = sub.row() + row.prop(self, "use_tweak_select_passthrough") if show_developer_ui and (not is_select_left): row = sub.row() row.prop(self, "use_tweak_tool_lmb_interaction") @@ -340,6 +353,7 @@ def load(): use_gizmo_drag=(is_select_left and kc_prefs.gizmo_action == 'DRAG'), use_fallback_tool=True, use_fallback_tool_rmb=(False if is_select_left else kc_prefs.rmb_action == 'FALLBACK_TOOL'), + use_tweak_select_passthrough=(show_developer_ui and kc_prefs.use_tweak_select_passthrough), use_tweak_tool_lmb_interaction=( False if is_select_left else (show_developer_ui and kc_prefs.use_tweak_tool_lmb_interaction) diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index ae112ee8054..78039abcc54 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -31,6 +31,7 @@ class Params: "context_menu_event", "cursor_set_event", "cursor_tweak_event", + "use_tweak_select_passthrough", "use_tweak_tool_lmb_interaction", "use_mouse_emulate_3_button", @@ -103,6 +104,7 @@ class Params: use_gizmo_drag=True, use_fallback_tool=False, use_fallback_tool_rmb=False, + use_tweak_select_passthrough=False, use_tweak_tool_lmb_interaction=False, use_v3d_tab_menu=False, use_v3d_shade_ex_pie=False, @@ -189,6 +191,8 @@ class Params: self.use_file_single_click = use_file_single_click + self.use_tweak_select_passthrough = use_tweak_select_passthrough + self.use_fallback_tool = use_fallback_tool self.use_fallback_tool_rmb = use_fallback_tool_rmb @@ -446,7 +450,7 @@ def _template_items_change_frame(params): # Tool System Templates -def _template_items_tool_select(params, operator, cursor_operator, fallback, *, extend): +def _template_items_tool_select(params, operator, cursor_operator, fallback): if params.select_mouse == 'LEFTMOUSE': # By default use 'PRESS' for immediate select without quick delay. # Fallback key-maps 'CLICK' since 'PRESS' events passes through (allowing either click or drag). @@ -458,7 +462,7 @@ def _template_items_tool_select(params, operator, cursor_operator, fallback, *, (operator, {"type": 'LEFTMOUSE', "value": 'CLICK' if fallback else 'PRESS'}, {"properties": [("deselect_all", True)]}), (operator, {"type": 'LEFTMOUSE', "value": 'CLICK' if fallback else 'PRESS', "shift": True}, - {"properties": [(extend, True)]}), + {"properties": [("toggle", True)]}), ] else: # Experimental support for LMB interaction for the tweak tool. @@ -1185,7 +1189,12 @@ def km_uv_editor(params): items.extend([ # Selection modes. *_template_items_uv_select_mode(params), - *_template_uv_select(type=params.select_mouse, value=params.select_mouse_value_fallback, legacy=params.legacy), + *_template_uv_select( + type=params.select_mouse, + value=params.select_mouse_value_fallback, + select_passthrough=params.use_tweak_select_passthrough, + legacy=params.legacy, + ), ("uv.mark_seam", {"type": 'E', "value": 'PRESS', "ctrl": True}, None), ("uv.select_loop", {"type": params.select_mouse, "value": params.select_mouse_value, "alt": True}, None), @@ -1513,6 +1522,7 @@ def km_view3d(params): type=params.select_mouse, value=params.select_mouse_value_fallback, legacy=params.legacy, + select_passthrough=params.use_tweak_select_passthrough, ), op_tool_optional( ("view3d.select_box", {"type": 'B', "value": 'PRESS'}, None), @@ -4677,7 +4687,7 @@ def _template_paint_radial_control(paint, rotation=False, secondary_rotation=Fal return items -def _template_view3d_select(*, type, value, legacy, exclude_mod=None): +def _template_view3d_select(*, type, value, legacy, select_passthrough, exclude_mod=None): # NOTE: `exclude_mod` is needed since we don't want this tool to exclude Control-RMB actions when this is used # as a tool key-map with RMB-select and `use_fallback_tool_rmb` is enabled. See T92467. return [( @@ -4685,7 +4695,8 @@ def _template_view3d_select(*, type, value, legacy, exclude_mod=None): {"type": type, "value": value, **{m: True for m in mods}}, {"properties": [(c, True) for c in props]}, ) for props, mods in ( - (("deselect_all",) if not legacy else (), ()), + ((("deselect_all", "select_passthrough") if select_passthrough else + ("deselect_all",)) if not legacy else (), ()), (("toggle",), ("shift",)), (("center", "object"), ("ctrl",)), (("enumerate",), ("alt",)), @@ -4711,10 +4722,13 @@ def _template_view3d_gpencil_select(*, type, value, legacy, use_select_mouse=Tru ] -def _template_uv_select(*, type, value, legacy): +def _template_uv_select(*, type, value, select_passthrough, legacy): return [ ("uv.select", {"type": type, "value": value}, - {"properties": [("deselect_all", not legacy)]}), + {"properties": [ + *((("deselect_all", True),) if not legacy else ()), + *((("select_passthrough", True),) if select_passthrough else ()), + ]}), ("uv.select", {"type": type, "value": value, "shift": True}, {"properties": [("toggle", True)]}), ] @@ -6306,9 +6320,13 @@ def km_image_editor_tool_uv_select(params, *, fallback): {"space_type": 'IMAGE_EDITOR', "region_type": 'WINDOW'}, {"items": [ *([] if (fallback and (params.select_mouse == 'RIGHTMOUSE')) else _template_items_tool_select( - params, "uv.select", "uv.cursor_set", fallback, extend="toggle")), + params, "uv.select", "uv.cursor_set", fallback)), *([] if (not params.use_fallback_tool_rmb) else _template_uv_select( - type=params.select_mouse, value=params.select_mouse_value, legacy=params.legacy)), + type=params.select_mouse, + value=params.select_mouse_value, + select_passthrough=params.use_tweak_select_passthrough, + legacy=params.legacy, + )), ]}, ) @@ -6513,9 +6531,14 @@ def km_3d_view_tool_select(params, *, fallback): {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, {"items": [ *([] if (fallback and (params.select_mouse == 'RIGHTMOUSE')) else _template_items_tool_select( - params, "view3d.select", "view3d.cursor3d", fallback, extend="toggle")), + params, "view3d.select", "view3d.cursor3d", fallback)), *([] if (not params.use_fallback_tool_rmb) else _template_view3d_select( - type=params.select_mouse, value=params.select_mouse_value, legacy=params.legacy, exclude_mod="ctrl")), + type=params.select_mouse, + value=params.select_mouse_value, + legacy=params.legacy, + select_passthrough=params.use_tweak_select_passthrough, + exclude_mod="ctrl", + )), ]}, ) @@ -7424,7 +7447,7 @@ def km_3d_view_tool_edit_gpencil_select(params, *, fallback): {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, {"items": [ *([] if (fallback and (params.select_mouse == 'RIGHTMOUSE')) else _template_items_tool_select( - params, "gpencil.select", "view3d.cursor3d", fallback, extend="toggle")), + params, "gpencil.select", "view3d.cursor3d", fallback)), *([] if (not params.use_fallback_tool_rmb) else _template_view3d_gpencil_select( type=params.select_mouse, value=params.select_mouse_value, legacy=params.legacy)), ]}, @@ -7562,7 +7585,7 @@ def km_3d_view_tool_sculpt_gpencil_select(params): return ( "3D View Tool: Sculpt Gpencil, Tweak", {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, - {"items": _template_items_tool_select(params, "gpencil.select", "view3d.cursor3d", False, extend="toggle")}, + {"items": _template_items_tool_select(params, "gpencil.select", "view3d.cursor3d", False)}, ) @@ -7602,7 +7625,7 @@ def km_sequencer_editor_tool_generic_select(params, *, fallback): {"space_type": 'SEQUENCE_EDITOR', "region_type": 'WINDOW'}, {"items": [ *([] if (fallback and (params.select_mouse == 'RIGHTMOUSE')) else _template_items_tool_select( - params, "sequencer.select", "sequencer.cursor_set", fallback, extend="toggle")), + params, "sequencer.select", "sequencer.cursor_set", fallback)), *([] if (not params.use_fallback_tool_rmb) else _template_sequencer_preview_select( type=params.select_mouse, value=params.select_mouse_value, legacy=params.legacy)), 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 947a7e5c7a7..d5a9887f551 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -361,6 +361,10 @@ class GPENCIL_UL_annotation_layer(UIList): split.prop(gpl, "info", text="", emboss=False) row = layout.row(align=True) + + icon_xray = "XRAY" if gpl.show_in_front else "FACESEL" + row.prop(gpl, "show_in_front", text="", icon=icon_xray, emboss=False) + row.prop(gpl, "annotation_hide", text="", emboss=False) elif self.layout_type == 'GRID': layout.alignment = 'CENTER' diff --git a/release/scripts/startup/bl_ui/space_outliner.py b/release/scripts/startup/bl_ui/space_outliner.py index 9d3f20ce4a4..bbe165b9286 100644 --- a/release/scripts/startup/bl_ui/space_outliner.py +++ b/release/scripts/startup/bl_ui/space_outliner.py @@ -442,15 +442,6 @@ class OUTLINER_PT_filter(Panel): row.label(icon='BLANK1') row.prop(space, "use_filter_object_others", text="Others") - if bpy.data.libraries: - col.separator() - row = col.row() - row.label(icon='LIBRARY_DATA_OVERRIDE') - row.prop(space, "use_filter_lib_override", text="Library Overrides") - row = col.row() - row.label(icon='LIBRARY_DATA_OVERRIDE') - row.prop(space, "use_filter_lib_override_system", text="System Overrides") - classes = ( OUTLINER_HT_header, diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 2533c993b9a..2eff8ca8cf6 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -386,8 +386,8 @@ class USERPREF_PT_edit_objects_duplicate_data(EditingPanel, CenterAlignMixIn, Pa col.prop(edit, "use_duplicate_curve", text="Curve") # col.prop(edit, "use_duplicate_fcurve", text="F-Curve") # Not implemented. col.prop(edit, "use_duplicate_grease_pencil", text="Grease Pencil") - if hasattr(edit, "use_duplicate_hair"): - col.prop(edit, "use_duplicate_hair", text="Hair") + if hasattr(edit, "use_duplicate_curves"): + col.prop(edit, "use_duplicate_curves", text="Curves") col = flow.column() col.prop(edit, "use_duplicate_lattice", text="Lattice") @@ -2260,6 +2260,7 @@ class USERPREF_PT_experimental_new_features(ExperimentalPanel, Panel): self._draw_items( context, ( ({"property": "use_sculpt_tools_tilt"}, "T82877"), + ({"property": "use_select_nearest_on_first_click"}, "T96752"), ({"property": "use_extended_asset_browser"}, ("project/view/130/", "Project Page")), ({"property": "use_override_templates"}, ("T73318", "Milestone 4")), ({"property": "use_named_attribute_nodes"}, ("T91742")), diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 57e8e6d54b3..e535dc18a1f 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -5301,6 +5301,8 @@ class VIEW3D_MT_pivot_pie(Menu): pie.prop_enum(context.scene.tool_settings, "transform_pivot_point", value='ACTIVE_ELEMENT') if (obj is None) or (mode in {'OBJECT', 'POSE', 'WEIGHT_PAINT'}): pie.prop(context.scene.tool_settings, "use_transform_pivot_point_align") + if mode in {'EDIT_GPENCIL'}: + pie.prop(context.scene.tool_settings.gpencil_sculpt, "use_scale_thickness") class VIEW3D_MT_orientations_pie(Menu): diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt index dee163a9797..deff45d0350 100644 --- a/source/blender/CMakeLists.txt +++ b/source/blender/CMakeLists.txt @@ -19,6 +19,7 @@ set(SRC_DNA_INC ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_constraint_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_curve_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_curveprofile_types.h + ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_curves_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_customdata_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_defs.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_documentation.h @@ -31,7 +32,6 @@ set(SRC_DNA_INC ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpencil_modifier_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpencil_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpu_types.h - ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_curves_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_image_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_ipo_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_key_types.h diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h index 3817fe59f95..058b0f120f7 100644 --- a/source/blender/blenfont/BLF_api.h +++ b/source/blender/blenfont/BLF_api.h @@ -44,7 +44,7 @@ int BLF_load_mem_unique(const char *name, const unsigned char *mem, int mem_size void BLF_unload(const char *name) ATTR_NONNULL(); void BLF_unload_id(int fontid); -char *BLF_display_name_from_file(const char *filename); +char *BLF_display_name_from_file(const char *filepath); /** * Check if font supports a particular glyph. @@ -279,7 +279,7 @@ void BLF_dir_free(char **dirs, int count) ATTR_NONNULL(); * * \note called from a thread, so it bypasses the normal BLF_* api (which isn't thread-safe). */ -void BLF_thumb_preview(const char *filename, +void BLF_thumb_preview(const char *filepath, const char **draw_str, const char **i18n_draw_str, unsigned char draw_str_lines, diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c index 043d6da7d73..2b5a2cdf606 100644 --- a/source/blender/blenfont/intern/blf.c +++ b/source/blender/blenfont/intern/blf.c @@ -129,7 +129,7 @@ bool BLF_has_glyph(int fontid, unsigned int unicode) { FontBLF *font = blf_get(fontid); if (font) { - return FT_Get_Char_Index(font->face, unicode) != 0; + return FT_Get_Char_Index(font->face, unicode) != FT_Err_Ok; } return false; } @@ -158,14 +158,14 @@ int BLF_load_unique(const char *name) return -1; } - char *filename = blf_dir_search(name); - if (!filename) { + char *filepath = blf_dir_search(name); + if (!filepath) { printf("Can't find font: %s\n", name); return -1; } - FontBLF *font = blf_font_new(name, filename); - MEM_freeN(filename); + FontBLF *font = blf_font_new(name, filepath); + MEM_freeN(filepath); if (!font) { printf("Can't load font: %s\n", name); @@ -869,9 +869,9 @@ void BLF_draw_buffer(int fontid, const char *str, const size_t str_len) BLF_draw_buffer_ex(fontid, str, str_len, NULL); } -char *BLF_display_name_from_file(const char *filename) +char *BLF_display_name_from_file(const char *filepath) { - FontBLF *font = blf_font_new("font_name", filename); + FontBLF *font = blf_font_new("font_name", filepath); if (!font) { return NULL; } diff --git a/source/blender/blenfont/intern/blf_dir.c b/source/blender/blenfont/intern/blf_dir.c index 69b44ed9b01..8534a8c583f 100644 --- a/source/blender/blenfont/intern/blf_dir.c +++ b/source/blender/blenfont/intern/blf_dir.c @@ -132,12 +132,12 @@ char *blf_dir_search(const char *file) return s; } -char *blf_dir_metrics_search(const char *filename) +char *blf_dir_metrics_search(const char *filepath) { char *mfile; char *s; - mfile = BLI_strdup(filename); + mfile = BLI_strdup(filepath); s = strrchr(mfile, '.'); if (s) { if (BLI_strnlen(s, 4) < 4) { diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index c4bd22d1310..60ff5f6470f 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -1213,14 +1213,14 @@ static void blf_font_fill(FontBLF *font) font->glyph_cache_mutex = &blf_glyph_cache_mutex; } -FontBLF *blf_font_new(const char *name, const char *filename) +FontBLF *blf_font_new(const char *name, const char *filepath) { FontBLF *font; FT_Error err; char *mfile; font = (FontBLF *)MEM_callocN(sizeof(FontBLF), "blf_font_new"); - err = FT_New_Face(ft_lib, filename, 0, &font->face); + err = FT_New_Face(ft_lib, filepath, 0, &font->face); if (err) { if (ELEM(err, FT_Err_Unknown_File_Format, FT_Err_Unimplemented_Feature)) { printf("Format of this font file is not supported\n"); @@ -1246,17 +1246,17 @@ FontBLF *blf_font_new(const char *name, const char *filename) return NULL; } - mfile = blf_dir_metrics_search(filename); + mfile = blf_dir_metrics_search(filepath); if (mfile) { err = FT_Attach_File(font->face, mfile); if (err) { - fprintf(stderr, "FT_Attach_File failed to load '%s' with error %d\n", filename, (int)err); + fprintf(stderr, "FT_Attach_File failed to load '%s' with error %d\n", filepath, (int)err); } MEM_freeN(mfile); } font->name = BLI_strdup(name); - font->filename = BLI_strdup(filename); + font->filepath = BLI_strdup(filepath); blf_font_fill(font); if (FT_HAS_KERNING(font->face)) { @@ -1303,7 +1303,7 @@ FontBLF *blf_font_new_from_mem(const char *name, const unsigned char *mem, int m } font->name = BLI_strdup(name); - font->filename = NULL; + font->filepath = NULL; blf_font_fill(font); return font; } @@ -1317,8 +1317,8 @@ void blf_font_free(FontBLF *font) } FT_Done_Face(font->face); - if (font->filename) { - MEM_freeN(font->filename); + if (font->filepath) { + MEM_freeN(font->filepath); } if (font->name) { MEM_freeN(font->name); @@ -1340,7 +1340,7 @@ bool blf_font_size(FontBLF *font, float size, unsigned int dpi) size = (float)ft_size / 64.0f; if (font->size != size || font->dpi != dpi) { - if (FT_Set_Char_Size(font->face, 0, ft_size, dpi, dpi) == 0) { + if (FT_Set_Char_Size(font->face, 0, ft_size, dpi, dpi) == FT_Err_Ok) { font->size = size; font->dpi = dpi; } diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c index 4810e46b1d2..28531c5afc1 100644 --- a/source/blender/blenfont/intern/blf_glyph.c +++ b/source/blender/blenfont/intern/blf_glyph.c @@ -258,7 +258,7 @@ static FT_GlyphSlot blf_glyph_load(FontBLF *font, FT_UInt glyph_index) } } - if (FT_Load_Glyph(font->face, glyph_index, load_flags) == 0) { + if (FT_Load_Glyph(font->face, glyph_index, load_flags) == FT_Err_Ok) { return font->face->glyph; } return NULL; @@ -280,7 +280,7 @@ static bool blf_glyph_render_bitmap(FontBLF *font, FT_GlyphSlot glyph) /* Render the glyph curves to a bitmap. */ FT_Error err = FT_Render_Glyph(glyph, render_mode); - if (err != 0) { + if (err != FT_Err_Ok) { return false; } diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h index 14e1a8f72d1..81a1460df4d 100644 --- a/source/blender/blenfont/intern/blf_internal.h +++ b/source/blender/blenfont/intern/blf_internal.h @@ -25,7 +25,7 @@ char *blf_dir_search(const char *file); * Some font have additional file with metrics information, * in general, the extension of the file is: `.afm` or `.pfm` */ -char *blf_dir_metrics_search(const char *filename); +char *blf_dir_metrics_search(const char *filepath); /* int blf_dir_split(const char *str, char *file, int *size); */ /* UNUSED */ int blf_font_init(void); @@ -36,7 +36,7 @@ bool blf_font_id_is_valid(int fontid); void blf_draw_buffer__start(struct FontBLF *font); void blf_draw_buffer__end(void); -struct FontBLF *blf_font_new(const char *name, const char *filename); +struct FontBLF *blf_font_new(const char *name, const char *filepath); struct FontBLF *blf_font_new_from_mem(const char *name, const unsigned char *mem, int mem_size); void blf_font_attach_from_mem(struct FontBLF *font, const unsigned char *mem, int mem_size); diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h index 61b6edc4974..23dc2fda38c 100644 --- a/source/blender/blenfont/intern/blf_internal_types.h +++ b/source/blender/blenfont/intern/blf_internal_types.h @@ -147,8 +147,8 @@ typedef struct FontBLF { /* # of times this font was loaded */ unsigned int reference_count; - /* filename or NULL. */ - char *filename; + /** File-path or NULL. */ + char *filepath; /* aspect ratio or scale. */ float aspect[3]; diff --git a/source/blender/blenfont/intern/blf_thumbs.c b/source/blender/blenfont/intern/blf_thumbs.c index 9d9a8a51d0f..0e265fb7553 100644 --- a/source/blender/blenfont/intern/blf_thumbs.c +++ b/source/blender/blenfont/intern/blf_thumbs.c @@ -29,7 +29,7 @@ #include "BLI_strict_flags.h" -void BLF_thumb_preview(const char *filename, +void BLF_thumb_preview(const char *filepath, const char **draw_str, const char **i18n_draw_str, const unsigned char draw_str_lines, @@ -49,9 +49,9 @@ void BLF_thumb_preview(const char *filename, FontBLF *font; /* Create a new blender font obj and fill it with default values */ - font = blf_font_new("thumb_font", filename); + font = blf_font_new("thumb_font", filepath); if (!font) { - printf("Info: Can't load font '%s', no preview possible\n", filename); + printf("Info: Can't load font '%s', no preview possible\n", filepath); return; } @@ -73,7 +73,7 @@ void BLF_thumb_preview(const char *filename, for (int i = 0; i < draw_str_lines; i++) { const char *draw_str_i18n = i18n_draw_str[i] != NULL ? i18n_draw_str[i] : draw_str[i]; const size_t draw_str_i18n_len = strlen(draw_str_i18n); - int draw_str_i18n_nbr = 0; + int draw_str_i18_count = 0; CLAMP_MIN(font_size_curr, font_size_min); if (!blf_font_size(font, (float)font_size_curr, dpi)) { @@ -91,8 +91,8 @@ void BLF_thumb_preview(const char *filename, * since many fonts will then show nothing but ugly 'missing char' in their preview). * Does not handle all cases, but much better than nothing. */ - if (blf_font_count_missing_chars(font, draw_str_i18n, draw_str_i18n_len, &draw_str_i18n_nbr) > - (draw_str_i18n_nbr / 2)) { + if (blf_font_count_missing_chars(font, draw_str_i18n, draw_str_i18n_len, &draw_str_i18_count) > + (draw_str_i18_count / 2)) { blf_font_draw_buffer(font, draw_str[i], strlen(draw_str[i]), NULL); } else { diff --git a/source/blender/blenkernel/BKE_attribute_math.hh b/source/blender/blenkernel/BKE_attribute_math.hh index 3075c0689e9..9efa64d1474 100644 --- a/source/blender/blenkernel/BKE_attribute_math.hh +++ b/source/blender/blenkernel/BKE_attribute_math.hh @@ -22,7 +22,7 @@ inline void convert_to_static_type(const CPPType &cpp_type, const Func &func) [&](auto type_tag) { using T = typename decltype(type_tag)::type; if constexpr (std::is_same_v<T, void>) { - /* It's expected that the given cpp type is one of the supported once. */ + /* It's expected that the given cpp type is one of the supported ones. */ BLI_assert_unreachable(); } else { diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh index eb4f8f5d5c8..82f77d83bec 100644 --- a/source/blender/blenkernel/BKE_curves.hh +++ b/source/blender/blenkernel/BKE_curves.hh @@ -122,14 +122,14 @@ class CurvesGeometry : public ::CurvesGeometry { * Accessors. */ - int points_size() const; - int curves_size() const; + int points_num() const; + int curves_num() const; IndexRange points_range() const; IndexRange curves_range() const; /** * The index of the first point in every curve. The size of this span is one larger than the - * number of curves. Consider using #range_for_curve rather than using the offsets directly. + * number of curves. Consider using #points_for_curve rather than using the offsets directly. */ Span<int> offsets() const; MutableSpan<int> offsets(); @@ -137,8 +137,8 @@ class CurvesGeometry : public ::CurvesGeometry { /** * Access a range of indices of point data for a specific curve. */ - IndexRange range_for_curve(int index) const; - IndexRange range_for_curves(IndexRange curves) const; + IndexRange points_for_curve(int index) const; + IndexRange points_for_curves(IndexRange curves) const; /** The type (#CurveType) of each curve, or potentially a single if all are the same type. */ VArray<int8_t> curve_types() const; @@ -146,6 +146,8 @@ class CurvesGeometry : public ::CurvesGeometry { MutableSpan<int8_t> curve_types(); bool has_curve_with_type(const CurveType type) const; + /** Return the number of curves with each type. */ + std::array<int, CURVE_TYPES_NUM> count_curve_types() const; MutableSpan<float3> positions(); Span<float3> positions() const; @@ -243,23 +245,36 @@ class CurvesGeometry : public ::CurvesGeometry { * The total number of points in the evaluated poly curve. * This can depend on the resolution attribute if it exists. */ - int evaluated_points_size() const; + int evaluated_points_num() const; /** * Access a range of indices of point data for a specific curve. * Call #evaluated_offsets() first to ensure that the evaluated offsets cache is current. */ - IndexRange evaluated_range_for_curve(int index) const; + IndexRange evaluated_points_for_curve(int index) const; + IndexRange evaluated_points_for_curves(IndexRange curves) const; /** * The index of the first evaluated point for every curve. The size of this span is one larger - * than the number of curves. Consider using #evaluated_range_for_curve rather than using the + * than the number of curves. Consider using #evaluated_points_for_curve rather than using the * offsets directly. */ Span<int> evaluated_offsets() const; + /** Makes sure the data described by #evaluated_offsets if necessary. */ + void ensure_evaluated_offsets() const; + Span<float3> evaluated_positions() const; + /** + * Evaluate a generic data to the standard evaluated points of a specific curve, + * defined by the resolution attribute or other factors, depending on the curve type. + * + * \warning This function expects offsets to the evaluated points for each curve to be + * calculated. That can be ensured with #ensure_evaluated_offsets. + */ + void interpolate_to_evaluated(int curve_index, GSpan src, GMutableSpan dst) const; + private: /** * Make sure the basis weights for NURBS curve's evaluated points are calculated. @@ -275,7 +290,7 @@ class CurvesGeometry : public ::CurvesGeometry { * Change the number of elements. New values for existing attributes should be properly * initialized afterwards. */ - void resize(int point_size, int curve_size); + void resize(int points_num, int curves_num); /** Call after deforming the position attribute. */ void tag_positions_changed(); @@ -314,9 +329,9 @@ namespace curves { * and the fact that curves with two points cannot be cyclic. The logic is simple, but this * function should be used to make intentions clearer. */ -inline int curve_segment_size(const int size, const bool cyclic) +inline int curve_segment_size(const int points_num, const bool cyclic) { - return (cyclic && size > 2) ? size : size - 1; + return (cyclic && points_num > 2) ? points_num : points_num - 1; } namespace bezier { @@ -375,16 +390,23 @@ void calculate_evaluated_positions(Span<float3> positions, Span<int> evaluated_offsets, MutableSpan<float3> evaluated_positions); +/** + * Evaluate generic data to the evaluated points, with counts for each segment described by + * #evaluated_offsets. Unlike other curve types, for Bezier curves generic data and positions + * are treated separately, since attribute values aren't stored for the handle control points. + */ +void interpolate_to_evaluated(GSpan src, Span<int> evaluated_offsets, GMutableSpan dst); + } // namespace bezier namespace catmull_rom { /** * Calculate the number of evaluated points that #interpolate_to_evaluated is expected to produce. - * \param size: The number of points in the curve. + * \param points_num: The number of points in the curve. * \param resolution: The resolution for each segment. */ -int calculate_evaluated_size(int size, bool cyclic, int resolution); +int calculate_evaluated_size(int points_num, bool cyclic, int resolution); /** * Evaluate the Catmull Rom curve. The length of the #dst span should be calculated with @@ -399,7 +421,7 @@ namespace nurbs { /** * Checks the conditions that a NURBS curve needs to evaluate. */ -bool check_valid_size_and_order(int size, int8_t order, bool cyclic, KnotsMode knots_mode); +bool check_valid_size_and_order(int points_num, int8_t order, bool cyclic, KnotsMode knots_mode); /** * Calculate the standard evaluated size for a NURBS curve, using the standard that @@ -410,14 +432,14 @@ bool check_valid_size_and_order(int size, int8_t order, bool cyclic, KnotsMode k * shared. */ int calculate_evaluated_size( - int size, int8_t order, bool cyclic, int resolution, KnotsMode knots_mode); + int points_num, int8_t order, bool cyclic, int resolution, KnotsMode knots_mode); /** * Calculate the length of the knot vector for a NURBS curve with the given properties. * The knots must be longer for a cyclic curve, for example, in order to provide weights for the * last evaluated points that are also influenced by the first control points. */ -int knots_size(int size, int8_t order, bool cyclic); +int knots_size(int points_num, int8_t order, bool cyclic); /** * Calculate the knots for a spline given its properties, based on built-in standards defined by @@ -428,7 +450,7 @@ int knots_size(int size, int8_t order, bool cyclic); * changes, and is generally more intuitive than defining the knot vector manually. */ void calculate_knots( - int size, KnotsMode mode, int8_t order, bool cyclic, MutableSpan<float> knots); + int points_num, KnotsMode mode, int8_t order, bool cyclic, MutableSpan<float> knots); /** * Based on the knots, the order, and other properties of a NURBS curve, calculate a cache that can @@ -436,7 +458,7 @@ void calculate_knots( * two pieces of information for every evaluated point: the first control point that influences it, * and a weight for each control point. */ -void calculate_basis_cache(int size, +void calculate_basis_cache(int points_num, int evaluated_size, int8_t order, bool cyclic, @@ -461,11 +483,11 @@ void interpolate_to_evaluated(const BasisCache &basis_cache, } // namespace curves -Curves *curves_new_nomain(int point_size, int curves_size); +Curves *curves_new_nomain(int points_num, int curves_num); /** * Create a new curves data-block containing a single curve with the given length and type. */ -Curves *curves_new_nomain_single(int point_size, CurveType type); +Curves *curves_new_nomain_single(int points_num, CurveType type); } // namespace blender::bke diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 911f4aab394..6b805a4c29d 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -589,7 +589,7 @@ void CustomData_layers__print(struct CustomData *data); /* External file storage */ void CustomData_external_add( - struct CustomData *data, struct ID *id, int type, int totelem, const char *filename); + struct CustomData *data, struct ID *id, int type, int totelem, const char *filepath); void CustomData_external_remove(struct CustomData *data, struct ID *id, int type, int totelem); bool CustomData_external_test(struct CustomData *data, int type); diff --git a/source/blender/blenkernel/BKE_dynamicpaint.h b/source/blender/blenkernel/BKE_dynamicpaint.h index 5a1c99774fd..109d3e6d977 100644 --- a/source/blender/blenkernel/BKE_dynamicpaint.h +++ b/source/blender/blenkernel/BKE_dynamicpaint.h @@ -129,7 +129,7 @@ int dynamicPaint_calculateFrame(struct DynamicPaintSurface *surface, struct Object *cObject, int frame); void dynamicPaint_outputSurfaceImage(struct DynamicPaintSurface *surface, - char *filename, + const char *filepath, short output_layer); /* PaintPoint state */ diff --git a/source/blender/blenkernel/BKE_gpencil_geom.h b/source/blender/blenkernel/BKE_gpencil_geom.h index 4127030e96f..ad3b1971ca9 100644 --- a/source/blender/blenkernel/BKE_gpencil_geom.h +++ b/source/blender/blenkernel/BKE_gpencil_geom.h @@ -220,30 +220,78 @@ bool BKE_gpencil_stroke_sample(struct bGPdata *gpd, * \param gps: Stroke to smooth * \param i: Point index * \param inf: Amount of smoothing to apply + * \param iterations: Radius of points to consider, equivalent to iterations * \param smooth_caps: Apply smooth to stroke extremes + * \param keep_shape: Smooth out fine details first + * \param r_gps: Stroke to put the result into */ -bool BKE_gpencil_stroke_smooth_point(struct bGPDstroke *gps, int i, float inf, bool smooth_caps); +bool BKE_gpencil_stroke_smooth_point(struct bGPDstroke *gps, + int point_index, + float influence, + int iterations, + bool smooth_caps, + bool keep_shape, + struct bGPDstroke *r_gps); /** * Apply smooth strength to stroke point. * \param gps: Stroke to smooth * \param point_index: Point index * \param influence: Amount of smoothing to apply + * \param iterations: Radius of points to consider, equivalent to iterations + * \param r_gps: Stroke to put the result into */ -bool BKE_gpencil_stroke_smooth_strength(struct bGPDstroke *gps, int point_index, float influence); +bool BKE_gpencil_stroke_smooth_strength(struct bGPDstroke *gps, + int point_index, + float influence, + int iterations, + struct bGPDstroke *r_gps); /** * Apply smooth for thickness to stroke point (use pressure). * \param gps: Stroke to smooth * \param point_index: Point index * \param influence: Amount of smoothing to apply + * \param iterations: Radius of points to consider, equivalent to iterations + * \param r_gps: Stroke to put the result into */ -bool BKE_gpencil_stroke_smooth_thickness(struct bGPDstroke *gps, int point_index, float influence); +bool BKE_gpencil_stroke_smooth_thickness(struct bGPDstroke *gps, + int point_index, + float influence, + int iterations, + struct bGPDstroke *r_gps); /** - * Apply smooth for UV rotation to stroke point (use pressure). + * Apply smooth for UV rotation/factor to stroke point. * \param gps: Stroke to smooth * \param point_index: Point index * \param influence: Amount of smoothing to apply + * \param iterations: Radius of points to consider, equivalent to iterations + * \param r_gps: Stroke to put the result into */ -bool BKE_gpencil_stroke_smooth_uv(struct bGPDstroke *gps, int point_index, float influence); +bool BKE_gpencil_stroke_smooth_uv(struct bGPDstroke *gps, + int point_index, + float influence, + int iterations, + struct bGPDstroke *r_gps); +/** + * Apply smooth operation to the stroke. + * \param gps: Stroke to smooth + * \param influence: The interpolation factor for the smooth and the original stroke + * \param iterations: Radius of points to consider, equivalent to iterations + * \param smooth_position: Smooth point locations + * \param smooth_strength: Smooth point strength + * \param smooth_thickness: Smooth point thickness + * \param smooth_uv: Smooth uv rotation/factor + * \param keep_shape: Use different distribution for smooth locations to keep the shape + * \param weights: per point weights to multiply influence with (optional, can be null) + */ +void BKE_gpencil_stroke_smooth(struct bGPDstroke *gps, + const float influence, + const int iterations, + const bool smooth_position, + const bool smooth_strength, + const bool smooth_thickness, + const bool smooth_uv, + const bool keep_shape, + const float *weights); /** * Close grease pencil stroke. * \param gps: Stroke to close diff --git a/source/blender/blenkernel/BKE_image_partial_update.hh b/source/blender/blenkernel/BKE_image_partial_update.hh index 8cbb8819551..393bf003caa 100644 --- a/source/blender/blenkernel/BKE_image_partial_update.hh +++ b/source/blender/blenkernel/BKE_image_partial_update.hh @@ -165,6 +165,7 @@ class ImageTileData : AbstractTileData { * Can be nullptr when the file doesn't exist or when the tile hasn't been initialized. */ ImBuf *tile_buffer = nullptr; + void *tile_buffer_lock = nullptr; ImageTileData(Image *image, ImageUser *image_user) : image(image) { @@ -177,14 +178,15 @@ class ImageTileData : AbstractTileData { { image_user.tile = new_tile_number; tile = BKE_image_get_tile(image, new_tile_number); - tile_buffer = BKE_image_acquire_ibuf(image, &image_user, NULL); + tile_buffer = BKE_image_acquire_ibuf(image, &image_user, &tile_buffer_lock); } void free_data() override { - BKE_image_release_ibuf(image, tile_buffer, nullptr); + BKE_image_release_ibuf(image, tile_buffer, tile_buffer_lock); tile = nullptr; tile_buffer = nullptr; + tile_buffer_lock = nullptr; } }; diff --git a/source/blender/blenkernel/BKE_image_save.h b/source/blender/blenkernel/BKE_image_save.h index b022e677845..052fc937af9 100644 --- a/source/blender/blenkernel/BKE_image_save.h +++ b/source/blender/blenkernel/BKE_image_save.h @@ -49,21 +49,26 @@ bool BKE_image_save(struct ReportList *reports, /* Render saving. */ -/* Save single or multilayer OpenEXR files from the render result. - * Optionally saves only a specific view or layer. */ +/** + * Save single or multi-layer OpenEXR files from the render result. + * Optionally saves only a specific view or layer. + */ bool BKE_image_render_write_exr(struct ReportList *reports, const struct RenderResult *rr, - const char *filename, + const char *filepath, const struct ImageFormatData *imf, const bool save_as_render, const char *view, int layer); +/** + * \param filepath_basis: May be used as-is, or used as a basis for multi-view images. + */ bool BKE_image_render_write(struct ReportList *reports, struct RenderResult *rr, const struct Scene *scene, const bool stamp, - const char *name); + const char *filepath_basis); #ifdef __cplusplus } diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h index 7f099125706..77a3223c064 100644 --- a/source/blender/blenkernel/BKE_layer.h +++ b/source/blender/blenkernel/BKE_layer.h @@ -301,10 +301,9 @@ void BKE_view_layer_visible_bases_iterator_end(BLI_Iterator *iter); #define FOREACH_SELECTED_OBJECT_BEGIN(_view_layer, _v3d, _instance) \ { \ - struct ObjectsVisibleIteratorData data_ = { \ - .view_layer = _view_layer, \ - .v3d = _v3d, \ - }; \ + struct ObjectsVisibleIteratorData data_ = {NULL}; \ + data_.view_layer = _view_layer; \ + data_.v3d = _v3d; \ ITER_BEGIN (BKE_view_layer_selected_objects_iterator_begin, \ BKE_view_layer_selected_objects_iterator_next, \ BKE_view_layer_selected_objects_iterator_end, \ @@ -319,7 +318,9 @@ void BKE_view_layer_visible_bases_iterator_end(BLI_Iterator *iter); #define FOREACH_SELECTED_EDITABLE_OBJECT_BEGIN(_view_layer, _v3d, _instance) \ { \ - struct ObjectsVisibleIteratorData data_ = {_view_layer, _v3d}; \ + struct ObjectsVisibleIteratorData data_ = {NULL}; \ + data_.view_layer = _view_layer; \ + data_.v3d = _v3d; \ ITER_BEGIN (BKE_view_layer_selected_editable_objects_iterator_begin, \ BKE_view_layer_selected_editable_objects_iterator_next, \ BKE_view_layer_selected_editable_objects_iterator_end, \ @@ -334,10 +335,9 @@ void BKE_view_layer_visible_bases_iterator_end(BLI_Iterator *iter); #define FOREACH_VISIBLE_OBJECT_BEGIN(_view_layer, _v3d, _instance) \ { \ - struct ObjectsVisibleIteratorData data_ = { \ - .view_layer = _view_layer, \ - .v3d = _v3d, \ - }; \ + struct ObjectsVisibleIteratorData data_ = {NULL}; \ + data_.view_layer = _view_layer; \ + data_.v3d = _v3d; \ ITER_BEGIN (BKE_view_layer_visible_objects_iterator_begin, \ BKE_view_layer_visible_objects_iterator_next, \ BKE_view_layer_visible_objects_iterator_end, \ @@ -404,10 +404,9 @@ void BKE_view_layer_visible_bases_iterator_end(BLI_Iterator *iter); #define FOREACH_VISIBLE_BASE_BEGIN(_view_layer, _v3d, _instance) \ { \ - struct ObjectsVisibleIteratorData data_ = { \ - .view_layer = _view_layer, \ - .v3d = _v3d, \ - }; \ + struct ObjectsVisibleIteratorData data_ = {NULL}; \ + data_.view_layer = _view_layer; \ + data_.v3d = _v3d; \ ITER_BEGIN (BKE_view_layer_visible_bases_iterator_begin, \ BKE_view_layer_visible_bases_iterator_next, \ BKE_view_layer_visible_bases_iterator_end, \ @@ -437,10 +436,9 @@ void BKE_view_layer_visible_bases_iterator_end(BLI_Iterator *iter); IteratorBeginCb func_begin; \ IteratorCb func_next, func_end; \ void *data_in; \ - struct ObjectsVisibleIteratorData data_ = { \ - .view_layer = _view_layer, \ - .v3d = _v3d, \ - }; \ + struct ObjectsVisibleIteratorData data_ = {NULL}; \ + data_.view_layer = _view_layer; \ + data_.v3d = _v3d; \ \ if (flag == SELECT) { \ func_begin = &BKE_view_layer_selected_objects_iterator_begin; \ diff --git a/source/blender/blenkernel/BKE_lib_id.h b/source/blender/blenkernel/BKE_lib_id.h index 040be8d1280..c3122758a72 100644 --- a/source/blender/blenkernel/BKE_lib_id.h +++ b/source/blender/blenkernel/BKE_lib_id.h @@ -515,7 +515,7 @@ void BKE_main_id_flag_listbase(struct ListBase *lb, int flag, bool value); void BKE_main_id_flag_all(struct Main *bmain, int flag, bool value); /** - * Next to indirect usage in `readfile.c/writefile.c` also in `editobject.c`, `scene.c`. + * Next to indirect usage in `readfile.c/writefile.c` also in `editobject.c`, `scene.cc`. */ void BKE_main_id_newptr_and_tag_clear(struct Main *bmain); diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 0ba9713b96d..1ad20c52a4b 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -571,7 +571,7 @@ typedef struct MLoopNorSpaceArray { struct LinkNode *loops_pool; /* Allocated once, avoids to call BLI_linklist_prepend_arena() for each loop! */ char data_type; /* Whether we store loop indices, or pointers to BMLoop. */ - int num_spaces; /* Number of clnors spaces defined in this array. */ + int spaces_num; /* Number of clnors spaces defined in this array. */ struct MemArena *mem; } MLoopNorSpaceArray; /** diff --git a/source/blender/blenkernel/BKE_packedFile.h b/source/blender/blenkernel/BKE_packedFile.h index 8433894b8c5..893aa2a5b1c 100644 --- a/source/blender/blenkernel/BKE_packedFile.h +++ b/source/blender/blenkernel/BKE_packedFile.h @@ -45,7 +45,7 @@ enum ePF_FileStatus { struct PackedFile *BKE_packedfile_duplicate(const struct PackedFile *pf_src); struct PackedFile *BKE_packedfile_new(struct ReportList *reports, - const char *filename, + const char *filepath, const char *basepath); struct PackedFile *BKE_packedfile_new_from_memory(void *mem, int memlen); @@ -102,7 +102,7 @@ int BKE_packedfile_unpack_all_libraries(struct Main *bmain, struct ReportList *r int BKE_packedfile_write_to_file(struct ReportList *reports, const char *ref_file_name, - const char *filename, + const char *filepath, struct PackedFile *pf, bool guimode); @@ -122,7 +122,7 @@ int BKE_packedfile_count_all(struct Main *bmain); * - #PF_NOFILE: the original file doesn't exist. */ enum ePF_FileCompare BKE_packedfile_compare_to_file(const char *ref_file_name, - const char *filename, + const char *filepath_rel, struct PackedFile *pf); /* Read. */ diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 8c50a89ec90..a6402a1e8a1 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -225,7 +225,7 @@ bool BKE_scene_remove_render_view(struct Scene *scene, struct SceneRenderView *s /* Render profile. */ int get_render_subsurf_level(const struct RenderData *r, int lvl, bool for_render); -int get_render_child_particle_number(const struct RenderData *r, int num, bool for_render); +int get_render_child_particle_number(const struct RenderData *r, int child_num, bool for_render); bool BKE_scene_use_shading_nodes_custom(struct Scene *scene); bool BKE_scene_use_spherical_stereo(struct Scene *scene); diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index e4edd01481b..a39d981d74f 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -104,8 +104,6 @@ set(SRC intern/crazyspace.c intern/cryptomatte.cc intern/curve.cc - intern/curves.cc - intern/curves_geometry.cc intern/curve_bevel.c intern/curve_bezier.cc intern/curve_catmull_rom.cc @@ -116,6 +114,8 @@ set(SRC intern/curve_nurbs.cc intern/curve_to_mesh_convert.cc intern/curveprofile.cc + intern/curves.cc + intern/curves_geometry.cc intern/customdata.cc intern/customdata_file.c intern/data_transfer.c @@ -157,9 +157,9 @@ set(SRC intern/idtype.c intern/image.cc intern/image_format.cc - intern/image_partial_update.cc intern/image_gen.c intern/image_gpu.cc + intern/image_partial_update.cc intern/image_save.cc intern/ipo.c intern/kelvinlet.c @@ -248,7 +248,7 @@ set(SRC intern/preferences.c intern/report.c intern/rigidbody.c - intern/scene.c + intern/scene.cc intern/screen.c intern/shader_fx.c intern/shrinkwrap.c @@ -349,10 +349,10 @@ set(SRC BKE_cryptomatte.h BKE_cryptomatte.hh BKE_curve.h - BKE_curves.h - BKE_curves.hh BKE_curve_to_mesh.hh BKE_curveprofile.h + BKE_curves.h + BKE_curves.hh BKE_customdata.h BKE_customdata_file.h BKE_data_transfer.h @@ -600,14 +600,14 @@ if(WITH_IMAGE_CINEON) add_definitions(-DWITH_CINEON) endif() -if(WITH_IMAGE_FRAMESERVER) - add_definitions(-DWITH_FRAMESERVER) -endif() - if(WITH_IMAGE_HDR) add_definitions(-DWITH_HDR) endif() +if(WITH_IMAGE_WEBP) + add_definitions(-DWITH_WEBP) +endif() + if(WITH_CODEC_AVI) list(APPEND INC ../io/avi @@ -821,6 +821,7 @@ if(WITH_GTESTS) intern/fcurve_test.cc intern/idprop_serialize_test.cc intern/image_partial_update_test.cc + intern/image_test.cc intern/lattice_deform_test.cc intern/layer_test.cc intern/lib_id_remapper_test.cc diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c index b0393ed723d..8d3649fef08 100644 --- a/source/blender/blenkernel/intern/appdir.c +++ b/source/blender/blenkernel/intern/appdir.c @@ -1022,16 +1022,16 @@ void BKE_appdir_app_templates(ListBase *templates) continue; } - struct direntry *dir; - uint totfile = BLI_filelist_dir_contents(subdir, &dir); - for (int f = 0; f < totfile; f++) { - if (!FILENAME_IS_CURRPAR(dir[f].relname) && S_ISDIR(dir[f].type)) { - char *template = BLI_strdup(dir[f].relname); + struct direntry *dirs; + const uint dir_num = BLI_filelist_dir_contents(subdir, &dirs); + for (int f = 0; f < dir_num; f++) { + if (!FILENAME_IS_CURRPAR(dirs[f].relname) && S_ISDIR(dirs[f].type)) { + char *template = BLI_strdup(dirs[f].relname); BLI_addtail(templates, BLI_genericNodeN(template)); } } - BLI_filelist_free(dir, totfile); + BLI_filelist_free(dirs, dir_num); } } diff --git a/source/blender/blenkernel/intern/blendfile_link_append.c b/source/blender/blenkernel/intern/blendfile_link_append.c index 294fe57c923..be2abdbfb69 100644 --- a/source/blender/blenkernel/intern/blendfile_link_append.c +++ b/source/blender/blenkernel/intern/blendfile_link_append.c @@ -999,7 +999,7 @@ static void blendfile_link_append_proxies_convert(Main *bmain, ReportList *repor RPT_WARNING, "Proxies have been removed from Blender (%d proxies were automatically converted " "to library overrides, %d proxies could not be converted and were cleared). " - "Please consider re-saving any library .blend file with the newest Blender version.", + "Please consider re-saving any library .blend file with the newest Blender version", bf_reports.count.proxies_to_lib_overrides_success, bf_reports.count.proxies_to_lib_overrides_failures); } diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index 891145b47c9..bdaea487cfb 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -432,7 +432,8 @@ void BKE_collection_add_from_object(Main *bmain, bool is_instantiated = false; FOREACH_SCENE_COLLECTION_BEGIN (scene, collection) { - if (!ID_IS_LINKED(collection) && BKE_collection_has_object(collection, ob_src)) { + if (!ID_IS_LINKED(collection) && !ID_IS_OVERRIDABLE_LIBRARY(collection) && + BKE_collection_has_object(collection, ob_src)) { collection_child_add(collection, collection_dst, 0, true); is_instantiated = true; } @@ -454,7 +455,8 @@ void BKE_collection_add_from_collection(Main *bmain, bool is_instantiated = false; FOREACH_SCENE_COLLECTION_BEGIN (scene, collection) { - if (!ID_IS_LINKED(collection) && collection_find_child(collection, collection_src)) { + if (!ID_IS_LINKED(collection) && !ID_IS_OVERRIDABLE_LIBRARY(collection) && + collection_find_child(collection, collection_src)) { collection_child_add(collection, collection_dst, 0, true); is_instantiated = true; } diff --git a/source/blender/blenkernel/intern/crazyspace.c b/source/blender/blenkernel/intern/crazyspace.c index 9d13bf3ac11..96389c44839 100644 --- a/source/blender/blenkernel/intern/crazyspace.c +++ b/source/blender/blenkernel/intern/crazyspace.c @@ -236,7 +236,7 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct Depsgraph *depsgra ModifierData *md; Mesh *me_input = ob->data; Mesh *me = NULL; - int i, a, numleft = 0, numVerts = 0; + int i, a, modifiers_left_num = 0, verts_num = 0; int cageIndex = BKE_modifiers_get_cage_index(scene, ob, NULL, 1); float(*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL; VirtualModifierData virtualModifierData; @@ -266,14 +266,14 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct Depsgraph *depsgra BLI_linklist_free((LinkNode *)datamasks, NULL); me = BKE_mesh_wrapper_from_editmesh_with_coords(em, &cd_mask_extra, NULL, me_input); - deformedVerts = editbmesh_vert_coords_alloc(em, &numVerts); - defmats = MEM_mallocN(sizeof(*defmats) * numVerts, "defmats"); + deformedVerts = editbmesh_vert_coords_alloc(em, &verts_num); + defmats = MEM_mallocN(sizeof(*defmats) * verts_num, "defmats"); - for (a = 0; a < numVerts; a++) { + for (a = 0; a < verts_num; a++) { unit_m3(defmats[a]); } } - mti->deformMatricesEM(md, &mectx, em, me, deformedVerts, defmats, numVerts); + mti->deformMatricesEM(md, &mectx, em, me, deformedVerts, defmats, verts_num); } else { break; @@ -283,7 +283,7 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct Depsgraph *depsgra for (; md && i <= cageIndex; md = md->next, i++) { if (editbmesh_modifier_is_enabled(scene, ob, md, me != NULL) && BKE_modifier_is_correctable_deformed(md)) { - numleft++; + modifiers_left_num++; } } @@ -294,7 +294,7 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct Depsgraph *depsgra *deformmats = defmats; *deformcos = deformedVerts; - return numleft; + return modifiers_left_num; } /** @@ -319,13 +319,13 @@ static void crazyspace_init_verts_and_matrices(const Mesh *mesh, float (**deformmats)[3][3], float (**deformcos)[3]) { - int num_verts; - *deformcos = BKE_mesh_vert_coords_alloc(mesh, &num_verts); - *deformmats = MEM_callocN(sizeof(**deformmats) * num_verts, "defmats"); - for (int a = 0; a < num_verts; a++) { + int verts_num; + *deformcos = BKE_mesh_vert_coords_alloc(mesh, &verts_num); + *deformmats = MEM_callocN(sizeof(**deformmats) * verts_num, "defmats"); + for (int a = 0; a < verts_num; a++) { unit_m3((*deformmats)[a]); } - BLI_assert(num_verts == mesh->totvert); + BLI_assert(verts_num == mesh->totvert); } static bool crazyspace_modifier_supports_deform_matrices(ModifierData *md) @@ -352,7 +352,7 @@ int BKE_sculpt_get_first_deform_matrices(struct Depsgraph *depsgraph, ModifierData *md; Mesh *me_eval = NULL; float(*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL; - int numleft = 0; + int modifiers_left_num = 0; VirtualModifierData virtualModifierData; Object object_eval; crazyspace_init_object_for_eval(depsgraph, object, &object_eval); @@ -364,7 +364,7 @@ int BKE_sculpt_get_first_deform_matrices(struct Depsgraph *depsgraph, if (is_sculpt_mode && has_multires) { *deformmats = NULL; *deformcos = NULL; - return numleft; + return modifiers_left_num; } md = BKE_modifiers_get_virtual_modifierlist(&object_eval, &virtualModifierData); @@ -401,7 +401,7 @@ int BKE_sculpt_get_first_deform_matrices(struct Depsgraph *depsgraph, } if (crazyspace_modifier_supports_deform(md)) { - numleft++; + modifiers_left_num++; } } @@ -412,7 +412,7 @@ int BKE_sculpt_get_first_deform_matrices(struct Depsgraph *depsgraph, *deformmats = defmats; *deformcos = deformedVerts; - return numleft; + return modifiers_left_num; } void BKE_crazyspace_build_sculpt(struct Depsgraph *depsgraph, @@ -489,13 +489,13 @@ void BKE_crazyspace_build_sculpt(struct Depsgraph *depsgraph, } if (*deformmats == NULL) { - int a, numVerts; + int a, verts_num; Mesh *mesh = (Mesh *)object->data; - *deformcos = BKE_mesh_vert_coords_alloc(mesh, &numVerts); - *deformmats = MEM_callocN(sizeof(*(*deformmats)) * numVerts, "defmats"); + *deformcos = BKE_mesh_vert_coords_alloc(mesh, &verts_num); + *deformmats = MEM_callocN(sizeof(*(*deformmats)) * verts_num, "defmats"); - for (a = 0; a < numVerts; a++) { + for (a = 0; a < verts_num; a++) { unit_m3((*deformmats)[a]); } } @@ -523,7 +523,7 @@ void BKE_crazyspace_api_eval(Depsgraph *depsgraph, } const Mesh *mesh = (const Mesh *)object->data; - object->runtime.crazyspace_num_verts = mesh->totvert; + object->runtime.crazyspace_verts_num = mesh->totvert; BKE_crazyspace_build_sculpt(depsgraph, scene, object, @@ -537,12 +537,12 @@ void BKE_crazyspace_api_displacement_to_deformed(struct Object *object, float displacement[3], float r_displacement_deformed[3]) { - if (vertex_index < 0 || vertex_index >= object->runtime.crazyspace_num_verts) { + if (vertex_index < 0 || vertex_index >= object->runtime.crazyspace_verts_num) { BKE_reportf(reports, RPT_ERROR, "Invalid vertex index %d (expected to be within 0 to %d range)", vertex_index, - object->runtime.crazyspace_num_verts); + object->runtime.crazyspace_verts_num); return; } @@ -557,12 +557,12 @@ void BKE_crazyspace_api_displacement_to_original(struct Object *object, float displacement_deformed[3], float r_displacement[3]) { - if (vertex_index < 0 || vertex_index >= object->runtime.crazyspace_num_verts) { + if (vertex_index < 0 || vertex_index >= object->runtime.crazyspace_verts_num) { BKE_reportf(reports, RPT_ERROR, "Invalid vertex index %d (expected to be within 0 to %d range))", vertex_index, - object->runtime.crazyspace_num_verts); + object->runtime.crazyspace_verts_num); return; } diff --git a/source/blender/blenkernel/intern/curve.cc b/source/blender/blenkernel/intern/curve.cc index 354ddd7d167..8b58ad848f2 100644 --- a/source/blender/blenkernel/intern/curve.cc +++ b/source/blender/blenkernel/intern/curve.cc @@ -4718,11 +4718,11 @@ static NURBSValidationStatus nurb_check_valid(const int pnts, if (pnts <= 1) { return NURBSValidationStatus::AtLeastTwoPointsRequired; } - else if (type == CU_NURBS) { + if (type == CU_NURBS) { if (pnts < order) { return NURBSValidationStatus::MorePointsThanOrderRequired; } - else if (flag & CU_NURB_BEZIER) { + if (flag & CU_NURB_BEZIER) { int points_needed = 0; if (flag & CU_NURB_CYCLIC) { const int remainder = pnts % (order - 1); @@ -4765,7 +4765,7 @@ bool BKE_nurb_valid_message(const int pnts, message_dst[0] = 0; return false; } - msg_template = TIP_("At least two points required."); + msg_template = TIP_("At least two points required"); break; case NURBSValidationStatus::MorePointsThanOrderRequired: msg_template = TIP_("Must have more control points than Order"); diff --git a/source/blender/blenkernel/intern/curve_bezier.cc b/source/blender/blenkernel/intern/curve_bezier.cc index 52a2674ab3d..b11216983b2 100644 --- a/source/blender/blenkernel/intern/curve_bezier.cc +++ b/source/blender/blenkernel/intern/curve_bezier.cc @@ -121,8 +121,8 @@ void calculate_evaluated_positions(const Span<float3> positions, }); /* Evaluate the final cyclic segment if necessary. */ - const IndexRange evaluated_range = offsets_to_range(evaluated_offsets, positions.size() - 2); - if (evaluated_range.size() == 1) { + const IndexRange last_segment_points = offsets_to_range(evaluated_offsets, positions.size() - 2); + if (last_segment_points.size() == 1) { evaluated_positions.last() = positions.last(); } else { @@ -130,10 +130,54 @@ void calculate_evaluated_positions(const Span<float3> positions, handles_right.last(), handles_left.first(), positions.first(), - evaluated_positions.slice(evaluated_range)); + evaluated_positions.slice(last_segment_points)); } } +template<typename T> +static inline void linear_interpolation(const T &a, const T &b, MutableSpan<T> dst) +{ + dst.first() = a; + const float step = 1.0f / dst.size(); + for (const int i : dst.index_range().drop_front(1)) { + dst[i] = attribute_math::mix2(i * step, a, b); + } +} + +template<typename T> +static void interpolate_to_evaluated(const Span<T> src, + const Span<int> evaluated_offsets, + MutableSpan<T> dst) +{ + BLI_assert(!src.is_empty()); + BLI_assert(dst.size() == src.size()); + BLI_assert(evaluated_offsets.last() == dst.size()); + + linear_interpolation(src.first(), src[1], dst.take_front(evaluated_offsets.first())); + + threading::parallel_for( + src.index_range().drop_back(1).drop_front(1), 512, [&](IndexRange range) { + for (const int i : range) { + const IndexRange segment_points = offsets_to_range(evaluated_offsets, i - 1); + linear_interpolation(src[i], src[i + 1], dst.slice(segment_points)); + } + }); + + const IndexRange last_segment_points(evaluated_offsets.last(1), + evaluated_offsets.last() - evaluated_offsets.last(1)); + linear_interpolation(src.last(), src.first(), dst.slice(last_segment_points)); +} + +void interpolate_to_evaluated(const GSpan src, const Span<int> evaluated_offsets, GMutableSpan dst) +{ + attribute_math::convert_to_static_type(src.type(), [&](auto dummy) { + using T = decltype(dummy); + if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) { + interpolate_to_evaluated(src.typed<T>(), evaluated_offsets, dst.typed<T>()); + } + }); +} + /** \} */ } // namespace blender::bke::curves::bezier diff --git a/source/blender/blenkernel/intern/curve_catmull_rom.cc b/source/blender/blenkernel/intern/curve_catmull_rom.cc index 27687eb736f..ea3672dd56b 100644 --- a/source/blender/blenkernel/intern/curve_catmull_rom.cc +++ b/source/blender/blenkernel/intern/curve_catmull_rom.cc @@ -9,11 +9,11 @@ namespace blender::bke::curves::catmull_rom { -int calculate_evaluated_size(const int size, const bool cyclic, const int resolution) +int calculate_evaluated_size(const int points_num, const bool cyclic, const int resolution) { - const int eval_size = resolution * curve_segment_size(size, cyclic); + const int eval_size = resolution * curve_segment_size(points_num, cyclic); /* If the curve isn't cyclic, one last point is added to the final point. */ - return (cyclic && size > 2) ? eval_size : eval_size + 1; + return (cyclic && points_num > 2) ? eval_size : eval_size + 1; } /* Adapted from Cycles #catmull_rom_basis_eval function. */ diff --git a/source/blender/blenkernel/intern/curve_eval.cc b/source/blender/blenkernel/intern/curve_eval.cc index b2399f25638..2cf83b57881 100644 --- a/source/blender/blenkernel/intern/curve_eval.cc +++ b/source/blender/blenkernel/intern/curve_eval.cc @@ -398,7 +398,7 @@ std::unique_ptr<CurveEval> curves_to_curve_eval(const Curves &curves) VArray<int8_t> curve_types = geometry.curve_types(); std::unique_ptr<CurveEval> curve_eval = std::make_unique<CurveEval>(); for (const int curve_index : curve_types.index_range()) { - const IndexRange point_range = geometry.range_for_curve(curve_index); + const IndexRange point_range = geometry.points_for_curve(curve_index); std::unique_ptr<Spline> spline; switch (curve_types[curve_index]) { @@ -489,7 +489,7 @@ Curves *curve_eval_to_curves(const CurveEval &curve_eval) const Spline &spline = *curve_eval.splines()[curve_index]; curve_types[curve_index] = curve_eval.splines()[curve_index]->type(); - const IndexRange point_range = geometry.range_for_curve(curve_index); + const IndexRange point_range = geometry.points_for_curve(curve_index); switch (spline.type()) { case CURVE_TYPE_POLY: diff --git a/source/blender/blenkernel/intern/curve_nurbs.cc b/source/blender/blenkernel/intern/curve_nurbs.cc index a4cdbbca654..0114c0b45f4 100644 --- a/source/blender/blenkernel/intern/curve_nurbs.cc +++ b/source/blender/blenkernel/intern/curve_nurbs.cc @@ -10,53 +10,53 @@ namespace blender::bke::curves::nurbs { -bool check_valid_size_and_order(const int size, +bool check_valid_size_and_order(const int points_num, const int8_t order, const bool cyclic, const KnotsMode knots_mode) { - if (size < order) { + if (points_num < order) { return false; } if (ELEM(knots_mode, NURBS_KNOT_MODE_BEZIER, NURBS_KNOT_MODE_ENDPOINT_BEZIER)) { - if (knots_mode == NURBS_KNOT_MODE_BEZIER && size <= order) { + if (knots_mode == NURBS_KNOT_MODE_BEZIER && points_num <= order) { return false; } - return (!cyclic || size % (order - 1) == 0); + return (!cyclic || points_num % (order - 1) == 0); } return true; } -int calculate_evaluated_size(const int size, +int calculate_evaluated_size(const int points_num, const int8_t order, const bool cyclic, const int resolution, const KnotsMode knots_mode) { - if (!check_valid_size_and_order(size, order, cyclic, knots_mode)) { + if (!check_valid_size_and_order(points_num, order, cyclic, knots_mode)) { return 0; } - return resolution * curve_segment_size(size, cyclic); + return resolution * curve_segment_size(points_num, cyclic); } -int knots_size(const int size, const int8_t order, const bool cyclic) +int knots_size(const int points_num, const int8_t order, const bool cyclic) { if (cyclic) { - return size + order * 2 - 1; + return points_num + order * 2 - 1; } - return size + order; + return points_num + order; } -void calculate_knots(const int size, +void calculate_knots(const int points_num, const KnotsMode mode, const int8_t order, const bool cyclic, MutableSpan<float> knots) { - BLI_assert(knots.size() == knots_size(size, order, cyclic)); - UNUSED_VARS_NDEBUG(size); + BLI_assert(knots.size() == knots_size(points_num, order, cyclic)); + UNUSED_VARS_NDEBUG(points_num); const bool is_bezier = ELEM(mode, NURBS_KNOT_MODE_BEZIER, NURBS_KNOT_MODE_ENDPOINT_BEZIER); const bool is_end_point = ELEM(mode, NURBS_KNOT_MODE_ENDPOINT, NURBS_KNOT_MODE_ENDPOINT_BEZIER); @@ -94,7 +94,7 @@ void calculate_knots(const int size, } static void calculate_basis_for_point(const float parameter, - const int size, + const int points_num, const int degree, const Span<float> knots, MutableSpan<float> r_weights, @@ -104,7 +104,7 @@ static void calculate_basis_for_point(const float parameter, int start = 0; int end = 0; - for (const int i : IndexRange(size + degree)) { + for (const int i : IndexRange(points_num + degree)) { const bool knots_equal = knots[i] == knots[i + 1]; if (knots_equal || parameter < knots[i] || parameter > knots[i + 1]) { continue; @@ -121,7 +121,7 @@ static void calculate_basis_for_point(const float parameter, for (const int i_order : IndexRange(2, degree)) { if (end + i_order >= knots.size()) { - end = size + degree - i_order; + end = points_num + degree - i_order; } for (const int i : IndexRange(end - start + 1)) { const int knot_index = start + i; @@ -146,15 +146,14 @@ static void calculate_basis_for_point(const float parameter, r_start_index = start; } -void calculate_basis_cache(const int size, +void calculate_basis_cache(const int points_num, const int evaluated_size, const int8_t order, const bool cyclic, const Span<float> knots, BasisCache &basis_cache) { - BLI_assert(size > 0); - BLI_assert(evaluated_size > 0); + BLI_assert(points_num > 0); const int8_t degree = order - 1; @@ -168,7 +167,7 @@ void calculate_basis_cache(const int size, MutableSpan<float> basis_weights(basis_cache.weights); MutableSpan<int> basis_start_indices(basis_cache.start_indices); - const int last_control_point_index = cyclic ? size + degree : size; + const int last_control_point_index = cyclic ? points_num + degree : points_num; const int evaluated_segment_size = curve_segment_size(evaluated_size, cyclic); const float start = knots[degree]; @@ -176,7 +175,7 @@ void calculate_basis_cache(const int size, const float step = (end - start) / evaluated_segment_size; for (const int i : IndexRange(evaluated_size)) { /* Clamp parameter due to floating point inaccuracy. */ - const float parameter = std::clamp(start + step * i, knots[0], knots[size + degree]); + const float parameter = std::clamp(start + step * i, knots[0], knots[points_num + degree]); MutableSpan<float> point_weights = basis_weights.slice(i * order, order); diff --git a/source/blender/blenkernel/intern/curves.cc b/source/blender/blenkernel/intern/curves.cc index 838f7f28e93..82db1176759 100644 --- a/source/blender/blenkernel/intern/curves.cc +++ b/source/blender/blenkernel/intern/curves.cc @@ -366,19 +366,19 @@ void BKE_curves_batch_cache_free(Curves *curves) namespace blender::bke { -Curves *curves_new_nomain(const int point_size, const int curves_size) +Curves *curves_new_nomain(const int points_num, const int curves_num) { Curves *curves = static_cast<Curves *>(BKE_id_new_nomain(ID_CV, nullptr)); CurvesGeometry &geometry = CurvesGeometry::wrap(curves->geometry); - geometry.resize(point_size, curves_size); + geometry.resize(points_num, curves_num); return curves; } -Curves *curves_new_nomain_single(const int point_size, const CurveType type) +Curves *curves_new_nomain_single(const int points_num, const CurveType type) { - Curves *curves = curves_new_nomain(point_size, 1); + Curves *curves = curves_new_nomain(points_num, 1); CurvesGeometry &geometry = CurvesGeometry::wrap(curves->geometry); - geometry.offsets().last() = point_size; + geometry.offsets().last() = points_num; geometry.curve_types().first() = type; return curves; } diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index db69fbc4063..7ceaa8f0f37 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -149,24 +149,24 @@ CurvesGeometry::~CurvesGeometry() /** \name Accessors * \{ */ -int CurvesGeometry::points_size() const +int CurvesGeometry::points_num() const { return this->point_size; } -int CurvesGeometry::curves_size() const +int CurvesGeometry::curves_num() const { return this->curve_size; } IndexRange CurvesGeometry::points_range() const { - return IndexRange(this->points_size()); + return IndexRange(this->points_num()); } IndexRange CurvesGeometry::curves_range() const { - return IndexRange(this->curves_size()); + return IndexRange(this->curves_num()); } -IndexRange CurvesGeometry::range_for_curve(const int index) const +IndexRange CurvesGeometry::points_for_curve(const int index) const { BLI_assert(this->curve_size > 0); BLI_assert(this->curve_offsets != nullptr); @@ -175,7 +175,7 @@ IndexRange CurvesGeometry::range_for_curve(const int index) const return {offset, offset_next - offset}; } -IndexRange CurvesGeometry::range_for_curves(const IndexRange curves) const +IndexRange CurvesGeometry::points_for_curves(const IndexRange curves) const { BLI_assert(this->curve_size > 0); BLI_assert(this->curve_offsets != nullptr); @@ -186,7 +186,7 @@ IndexRange CurvesGeometry::range_for_curves(const IndexRange curves) const static int domain_size(const CurvesGeometry &curves, const AttributeDomain domain) { - return domain == ATTR_DOMAIN_POINT ? curves.points_size() : curves.curves_size(); + return domain == ATTR_DOMAIN_POINT ? curves.points_num() : curves.curves_num(); } static CustomData &domain_custom_data(CurvesGeometry &curves, const AttributeDomain domain) @@ -277,6 +277,40 @@ bool CurvesGeometry::has_curve_with_type(const CurveType type) const return false; } +std::array<int, CURVE_TYPES_NUM> CurvesGeometry::count_curve_types() const +{ + using CountsType = std::array<int, CURVE_TYPES_NUM>; + + CountsType identity; + identity.fill(0); + + const VArray<int8_t> types = this->curve_types(); + if (types.is_single()) { + identity[types.get_internal_single()] = this->curves_num(); + return identity; + } + + Span<int8_t> types_span = types.get_internal_span(); + return threading::parallel_reduce( + this->curves_range(), + 2048, + identity, + [&](const IndexRange curves_range, const CountsType &init) { + CountsType result = init; + for (const int curve_index : curves_range) { + result[types_span[curve_index]]++; + } + return result; + }, + [](const CountsType &a, const CountsType &b) { + CountsType result = a; + for (const int i : IndexRange(CURVE_TYPES_NUM)) { + result[i] += b[i]; + } + return result; + }); +} + MutableSpan<float3> CurvesGeometry::positions() { this->position = (float(*)[3])CustomData_duplicate_referenced_layer_named( @@ -431,7 +465,7 @@ static void calculate_evaluated_offsets(const CurvesGeometry &curves, VArray<int8_t> nurbs_knots_modes = curves.nurbs_knots_modes(); build_offsets(offsets, [&](const int curve_index) -> int { - const IndexRange points = curves.range_for_curve(curve_index); + const IndexRange points = curves.points_for_curve(curve_index); switch (types[curve_index]) { case CURVE_TYPE_CATMULL_ROM: return curves::catmull_rom::calculate_evaluated_size( @@ -457,35 +491,44 @@ static void calculate_evaluated_offsets(const CurvesGeometry &curves, }); } -int CurvesGeometry::evaluated_points_size() const +int CurvesGeometry::evaluated_points_num() const { /* This could avoid calculating offsets in the future in simple circumstances. */ return this->evaluated_offsets().last(); } -IndexRange CurvesGeometry::evaluated_range_for_curve(int index) const +IndexRange CurvesGeometry::evaluated_points_for_curve(int index) const { BLI_assert(!this->runtime->offsets_cache_dirty); return offsets_to_range(this->runtime->evaluated_offsets_cache.as_span(), index); } -Span<int> CurvesGeometry::evaluated_offsets() const +IndexRange CurvesGeometry::evaluated_points_for_curves(const IndexRange curves) const +{ + BLI_assert(!this->runtime->offsets_cache_dirty); + BLI_assert(this->curve_size > 0); + const int offset = this->runtime->evaluated_offsets_cache[curves.start()]; + const int offset_next = this->runtime->evaluated_offsets_cache[curves.one_after_last()]; + return {offset, offset_next - offset}; +} + +void CurvesGeometry::ensure_evaluated_offsets() const { if (!this->runtime->offsets_cache_dirty) { - return this->runtime->evaluated_offsets_cache; + return; } /* A double checked lock. */ std::scoped_lock lock{this->runtime->offsets_cache_mutex}; if (!this->runtime->offsets_cache_dirty) { - return this->runtime->evaluated_offsets_cache; + return; } threading::isolate_task([&]() { - this->runtime->evaluated_offsets_cache.resize(this->curves_size() + 1); + this->runtime->evaluated_offsets_cache.resize(this->curves_num() + 1); if (this->has_curve_with_type(CURVE_TYPE_BEZIER)) { - this->runtime->bezier_evaluated_offsets.resize(this->points_size()); + this->runtime->bezier_evaluated_offsets.resize(this->points_num()); } else { this->runtime->bezier_evaluated_offsets.clear_and_make_inline(); @@ -496,6 +539,11 @@ Span<int> CurvesGeometry::evaluated_offsets() const }); this->runtime->offsets_cache_dirty = false; +} + +Span<int> CurvesGeometry::evaluated_offsets() const +{ + this->ensure_evaluated_offsets(); return this->runtime->evaluated_offsets_cache; } @@ -536,7 +584,7 @@ void CurvesGeometry::ensure_nurbs_basis_cache() const return; } - this->runtime->nurbs_basis_cache.resize(this->curves_size()); + this->runtime->nurbs_basis_cache.resize(this->curves_num()); MutableSpan<curves::nurbs::BasisCache> basis_caches(this->runtime->nurbs_basis_cache); VArray<bool> cyclic = this->cyclic(); @@ -545,8 +593,8 @@ void CurvesGeometry::ensure_nurbs_basis_cache() const threading::parallel_for(nurbs_mask.index_range(), 64, [&](const IndexRange range) { for (const int curve_index : nurbs_mask.slice(range)) { - const IndexRange points = this->range_for_curve(curve_index); - const IndexRange evaluated_points = this->evaluated_range_for_curve(curve_index); + const IndexRange points = this->points_for_curve(curve_index); + const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index); const int8_t order = orders[curve_index]; const bool is_cyclic = cyclic[curve_index]; @@ -564,6 +612,8 @@ void CurvesGeometry::ensure_nurbs_basis_cache() const } }); }); + + this->runtime->nurbs_basis_cache_dirty = false; } Span<float3> CurvesGeometry::evaluated_positions() const @@ -579,7 +629,7 @@ Span<float3> CurvesGeometry::evaluated_positions() const } threading::isolate_task([&]() { - this->runtime->evaluated_position_cache.resize(this->evaluated_points_size()); + this->runtime->evaluated_position_cache.resize(this->evaluated_points_num()); MutableSpan<float3> evaluated_positions = this->runtime->evaluated_position_cache; VArray<int8_t> types = this->curve_types(); @@ -598,8 +648,8 @@ Span<float3> CurvesGeometry::evaluated_positions() const threading::parallel_for(this->curves_range(), 128, [&](IndexRange curves_range) { for (const int curve_index : curves_range) { - const IndexRange points = this->range_for_curve(curve_index); - const IndexRange evaluated_points = this->evaluated_range_for_curve(curve_index); + const IndexRange points = this->points_for_curve(curve_index); + const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index); switch (types[curve_index]) { case CURVE_TYPE_CATMULL_ROM: @@ -639,22 +689,54 @@ Span<float3> CurvesGeometry::evaluated_positions() const return this->runtime->evaluated_position_cache; } +void CurvesGeometry::interpolate_to_evaluated(const int curve_index, + const GSpan src, + GMutableSpan dst) const +{ + BLI_assert(!this->runtime->offsets_cache_dirty); + BLI_assert(!this->runtime->nurbs_basis_cache_dirty); + const IndexRange points = this->points_for_curve(curve_index); + BLI_assert(src.size() == points.size()); + BLI_assert(dst.size() == this->evaluated_points_for_curve(curve_index).size()); + switch (this->curve_types()[curve_index]) { + case CURVE_TYPE_CATMULL_ROM: + curves::catmull_rom::interpolate_to_evaluated( + src, this->cyclic()[curve_index], this->resolution()[curve_index], dst); + return; + case CURVE_TYPE_POLY: + dst.type().copy_assign_n(src.data(), dst.data(), src.size()); + return; + case CURVE_TYPE_BEZIER: + curves::bezier::interpolate_to_evaluated( + src, this->runtime->bezier_evaluated_offsets.as_span().slice(points), dst); + return; + case CURVE_TYPE_NURBS: + curves::nurbs::interpolate_to_evaluated(this->runtime->nurbs_basis_cache[curve_index], + this->nurbs_orders()[curve_index], + this->nurbs_weights().slice(points), + src, + dst); + return; + } + BLI_assert_unreachable(); +} + /** \} */ /* -------------------------------------------------------------------- */ /** \name Operations * \{ */ -void CurvesGeometry::resize(const int point_size, const int curve_size) +void CurvesGeometry::resize(const int points_num, const int curves_num) { - if (point_size != this->point_size) { - CustomData_realloc(&this->point_data, point_size); - this->point_size = point_size; + if (points_num != this->point_size) { + CustomData_realloc(&this->point_data, points_num); + this->point_size = points_num; } - if (curve_size != this->curve_size) { - CustomData_realloc(&this->curve_data, curve_size); - this->curve_size = curve_size; - this->curve_offsets = (int *)MEM_reallocN(this->curve_offsets, sizeof(int) * (curve_size + 1)); + if (curves_num != this->curve_size) { + CustomData_realloc(&this->curve_data, curves_num); + this->curve_size = curves_num; + this->curve_offsets = (int *)MEM_reallocN(this->curve_offsets, sizeof(int) * (curves_num + 1)); } this->tag_topology_changed(); this->update_customdata_pointers(); @@ -727,7 +809,7 @@ static std::optional<bounds::MinMaxResult<float3>> curves_bounds(const CurvesGeo { Span<float3> positions = curves.positions(); if (curves.radius) { - Span<float> radii{curves.radius, curves.points_size()}; + Span<float> radii{curves.radius, curves.points_num()}; return bounds::min_max_with_radii(positions, radii); } return bounds::min_max(positions); @@ -784,7 +866,7 @@ static CurvesGeometry copy_with_removed_curves(const CurvesGeometry &curves, new_curve_ranges.append(IndexRange(new_tot_curves, curve_range.size())); new_tot_curves += curve_range.size(); - const IndexRange old_point_range = curves.range_for_curves(curve_range); + const IndexRange old_point_range = curves.points_for_curves(curve_range); old_point_ranges.append(old_point_range); new_point_ranges.append(IndexRange(new_tot_points, old_point_range.size())); new_tot_points += old_point_range.size(); @@ -889,7 +971,7 @@ static void reverse_curve_point_data(const CurvesGeometry &curves, { threading::parallel_for(curve_selection.index_range(), 256, [&](IndexRange range) { for (const int curve_i : curve_selection.slice(range)) { - data.slice(curves.range_for_curve(curve_i)).reverse(); + data.slice(curves.points_for_curve(curve_i)).reverse(); } }); } @@ -902,7 +984,7 @@ static void reverse_swap_curve_point_data(const CurvesGeometry &curves, { threading::parallel_for(curve_selection.index_range(), 256, [&](IndexRange range) { for (const int curve_i : curve_selection.slice(range)) { - const IndexRange points = curves.range_for_curve(curve_i); + const IndexRange points = curves.points_for_curve(curve_i); MutableSpan<T> a = data_a.slice(points); MutableSpan<T> b = data_b.slice(points); for (const int i : IndexRange(points.size() / 2)) { @@ -926,7 +1008,7 @@ static bool layer_matches_name_and_type(const CustomDataLayer &layer, void CurvesGeometry::reverse_curves(const IndexMask curves_to_reverse) { - CustomData_duplicate_referenced_layers(&this->point_data, this->points_size()); + CustomData_duplicate_referenced_layers(&this->point_data, this->points_num()); /* Collect the Bezier handle attributes while iterating through the point custom data layers; * they need special treatment later. */ @@ -940,22 +1022,22 @@ void CurvesGeometry::reverse_curves(const IndexMask curves_to_reverse) if (positions_left.is_empty() && layer_matches_name_and_type(layer, ATTR_HANDLE_POSITION_LEFT, CD_PROP_FLOAT3)) { - positions_left = {static_cast<float3 *>(layer.data), this->points_size()}; + positions_left = {static_cast<float3 *>(layer.data), this->points_num()}; continue; } if (positions_right.is_empty() && layer_matches_name_and_type(layer, ATTR_HANDLE_POSITION_RIGHT, CD_PROP_FLOAT3)) { - positions_right = {static_cast<float3 *>(layer.data), this->points_size()}; + positions_right = {static_cast<float3 *>(layer.data), this->points_num()}; continue; } if (types_left.is_empty() && layer_matches_name_and_type(layer, ATTR_HANDLE_TYPE_LEFT, CD_PROP_INT8)) { - types_left = {static_cast<int8_t *>(layer.data), this->points_size()}; + types_left = {static_cast<int8_t *>(layer.data), this->points_num()}; continue; } if (types_right.is_empty() && layer_matches_name_and_type(layer, ATTR_HANDLE_TYPE_RIGHT, CD_PROP_INT8)) { - types_right = {static_cast<int8_t *>(layer.data), this->points_size()}; + types_right = {static_cast<int8_t *>(layer.data), this->points_num()}; continue; } @@ -963,7 +1045,7 @@ void CurvesGeometry::reverse_curves(const IndexMask curves_to_reverse) attribute_math::convert_to_static_type(data_type, [&](auto dummy) { using T = decltype(dummy); reverse_curve_point_data<T>( - *this, curves_to_reverse, {static_cast<T *>(layer.data), this->points_size()}); + *this, curves_to_reverse, {static_cast<T *>(layer.data), this->points_num()}); }); } @@ -1001,8 +1083,8 @@ static void adapt_curve_domain_point_to_curve_impl(const CurvesGeometry &curves, MutableSpan<T> r_values) { attribute_math::DefaultMixer<T> mixer(r_values); - for (const int i_curve : IndexRange(curves.curves_size())) { - for (const int i_point : curves.range_for_curve(i_curve)) { + for (const int i_curve : IndexRange(curves.curves_num())) { + for (const int i_point : curves.points_for_curve(i_curve)) { mixer.mix_in(i_curve, old_values[i_point]); } } @@ -1022,8 +1104,8 @@ void adapt_curve_domain_point_to_curve_impl(const CurvesGeometry &curves, MutableSpan<bool> r_values) { r_values.fill(true); - for (const int i_curve : IndexRange(curves.curves_size())) { - for (const int i_point : curves.range_for_curve(i_curve)) { + for (const int i_curve : IndexRange(curves.curves_num())) { + for (const int i_point : curves.points_for_curve(i_curve)) { if (!old_values[i_point]) { r_values[i_curve] = false; break; @@ -1039,7 +1121,7 @@ static GVArray adapt_curve_domain_point_to_curve(const CurvesGeometry &curves, attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) { using T = decltype(dummy); if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) { - Array<T> values(curves.curves_size()); + Array<T> values(curves.curves_num()); adapt_curve_domain_point_to_curve_impl<T>(curves, varray.typed<T>(), values); new_varray = VArray<T>::ForContainer(std::move(values)); } @@ -1059,8 +1141,8 @@ static void adapt_curve_domain_curve_to_point_impl(const CurvesGeometry &curves, const VArray<T> &old_values, MutableSpan<T> r_values) { - for (const int i_curve : IndexRange(curves.curves_size())) { - r_values.slice(curves.range_for_curve(i_curve)).fill(old_values[i_curve]); + for (const int i_curve : IndexRange(curves.curves_num())) { + r_values.slice(curves.points_for_curve(i_curve)).fill(old_values[i_curve]); } } @@ -1070,7 +1152,7 @@ static GVArray adapt_curve_domain_curve_to_point(const CurvesGeometry &curves, GVArray new_varray; attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) { using T = decltype(dummy); - Array<T> values(curves.points_size()); + Array<T> values(curves.points_num()); adapt_curve_domain_curve_to_point_impl<T>(curves, varray.typed<T>(), values); new_varray = VArray<T>::ForContainer(std::move(values)); }); diff --git a/source/blender/blenkernel/intern/curves_geometry_test.cc b/source/blender/blenkernel/intern/curves_geometry_test.cc index 1b3b3f54451..e4dc9eead60 100644 --- a/source/blender/blenkernel/intern/curves_geometry_test.cc +++ b/source/blender/blenkernel/intern/curves_geometry_test.cc @@ -46,7 +46,7 @@ TEST(curves_geometry, Move) CurvesGeometry other = std::move(curves); /* The old curves should be empty, and the offsets are expected to be null. */ - EXPECT_EQ(curves.points_size(), 0); /* NOLINT: bugprone-use-after-move */ + EXPECT_EQ(curves.points_num(), 0); /* NOLINT: bugprone-use-after-move */ EXPECT_EQ(curves.curve_offsets, nullptr); /* NOLINT: bugprone-use-after-move */ /* Just a basic check that the new curves work okay. */ @@ -63,6 +63,28 @@ TEST(curves_geometry, Move) EXPECT_EQ(second_other.offsets().data(), offsets_data); } +TEST(curves_geometry, TypeCount) +{ + CurvesGeometry curves = create_basic_curves(100, 10); + curves.curve_types().copy_from({ + CURVE_TYPE_BEZIER, + CURVE_TYPE_NURBS, + CURVE_TYPE_NURBS, + CURVE_TYPE_NURBS, + CURVE_TYPE_CATMULL_ROM, + CURVE_TYPE_CATMULL_ROM, + CURVE_TYPE_CATMULL_ROM, + CURVE_TYPE_POLY, + CURVE_TYPE_POLY, + CURVE_TYPE_POLY, + }); + std::array<int, CURVE_TYPES_NUM> counts = curves.count_curve_types(); + EXPECT_EQ(counts[CURVE_TYPE_CATMULL_ROM], 3); + EXPECT_EQ(counts[CURVE_TYPE_POLY], 3); + EXPECT_EQ(counts[CURVE_TYPE_BEZIER], 1); + EXPECT_EQ(counts[CURVE_TYPE_NURBS], 3); +} + TEST(curves_geometry, CatmullRomEvaluation) { CurvesGeometry curves(4, 1); @@ -206,7 +228,7 @@ TEST(curves_geometry, CatmullRomTwoPointCyclic) /* The cyclic value should be ignored when there are only two control points. There should * be 12 evaluated points for the single segment and an extra for the last point. */ - EXPECT_EQ(curves.evaluated_points_size(), 13); + EXPECT_EQ(curves.evaluated_points_num(), 13); } TEST(curves_geometry, BezierPositionEvaluation) @@ -383,4 +405,77 @@ TEST(curves_geometry, NURBSEvaluation) } } +TEST(curves_geometry, BezierGenericEvaluation) +{ + CurvesGeometry curves(3, 1); + curves.curve_types().fill(CURVE_TYPE_BEZIER); + curves.resolution().fill(8); + curves.offsets().last() = 3; + + MutableSpan<float3> handles_left = curves.handle_positions_left(); + MutableSpan<float3> handles_right = curves.handle_positions_right(); + MutableSpan<float3> positions = curves.positions(); + positions.first() = {-1, 0, 0}; + handles_right.first() = {-1, 1, 0}; + handles_left[1] = {0, 0, 0}; + positions[1] = {1, 0, 0}; + handles_right[1] = {2, 0, 0}; + handles_left.last() = {1, 1, 0}; + positions.last() = {2, 1, 0}; + + /* Dangling handles shouldn't be used in a non-cyclic curve. */ + handles_left.first() = {100, 100, 100}; + handles_right.last() = {100, 100, 100}; + + Span<float3> evaluated_positions = curves.evaluated_positions(); + static const Array<float3> result_1{{ + {-1.0f, 0.0f, 0.0f}, + {-0.955078f, 0.287109f, 0.0f}, + {-0.828125f, 0.421875f, 0.0f}, + {-0.630859f, 0.439453f, 0.0f}, + {-0.375f, 0.375f, 0.0f}, + {-0.0722656f, 0.263672f, 0.0f}, + {0.265625f, 0.140625f, 0.0f}, + {0.626953f, 0.0410156f, 0.0f}, + {1.0f, 0.0f, 0.0f}, + {1.28906f, 0.0429688f, 0.0f}, + {1.4375f, 0.15625f, 0.0f}, + {1.49219f, 0.316406f, 0.0f}, + {1.5f, 0.5f, 0.0f}, + {1.50781f, 0.683594f, 0.0f}, + {1.5625f, 0.84375f, 0.0f}, + {1.71094f, 0.957031f, 0.0f}, + {2.0f, 1.0f, 0.0f}, + }}; + for (const int i : evaluated_positions.index_range()) { + EXPECT_V3_NEAR(evaluated_positions[i], result_1[i], 1e-5f); + } + + Array<float> radii{{0.0f, 1.0f, 2.0f}}; + Array<float> evaluated_radii(17); + curves.interpolate_to_evaluated(0, radii.as_span(), evaluated_radii.as_mutable_span()); + static const Array<float> result_2{{ + 0.0f, + 0.125f, + 0.25f, + 0.375f, + 0.5f, + 0.625f, + 0.75f, + 0.875f, + 1.0f, + 1.125f, + 1.25f, + 1.375f, + 1.5f, + 1.625f, + 1.75f, + 1.875f, + 2.0f, + }}; + for (const int i : evaluated_radii.index_range()) { + EXPECT_NEAR(evaluated_radii[i], result_2[i], 1e-6f); + } +} + } // namespace blender::bke::tests diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index e5424b39091..702488fb93b 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -62,6 +62,10 @@ BLI_STATIC_ASSERT(ARRAY_SIZE(((CustomData *)nullptr)->typemap) == CD_NUMTYPES, " static CLG_LogRef LOG = {"bke.customdata"}; +/* -------------------------------------------------------------------- */ +/** \name Mesh Mask Utilities + * \{ */ + void CustomData_MeshMasks_update(CustomData_MeshMasks *mask_dst, const CustomData_MeshMasks *mask_src) { @@ -82,7 +86,12 @@ bool CustomData_MeshMasks_are_matching(const CustomData_MeshMasks *mask_ref, ((mask_required->lmask & mask_ref->lmask) == mask_required->lmask)); } -/********************* Layer type information **********************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Layer Type Information + * \{ */ + struct LayerTypeInfo { int size; /* the memory size of one element of this layer's data */ @@ -164,6 +173,12 @@ struct LayerTypeInfo { int (*layers_max)(); }; +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Callbacks for (#MDeformVert, #CD_MDEFORMVERT) + * \{ */ + static void layerCopy_mdeformvert(const void *source, void *dest, int count) { int i, size = sizeof(MDeformVert); @@ -315,6 +330,12 @@ static void layerInterp_mdeformvert(const void **sources, } } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Callbacks for (#vec3f, #CD_NORMAL) + * \{ */ + static void layerInterp_normal(const void **sources, const float *weights, const float *UNUSED(sub_weights), @@ -371,6 +392,12 @@ static void layerCopyValue_normal(const void *source, } } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Callbacks for (#MTFace, #CD_MTFACE) + * \{ */ + static void layerCopy_tface(const void *source, void *dest, int count) { const MTFace *source_tf = (const MTFace *)source; @@ -436,6 +463,12 @@ static int layerMaxNum_tface() return MAX_MTFACE; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Callbacks for (#MFloatProperty, #CD_PROP_FLOAT) + * \{ */ + static void layerCopy_propFloat(const void *source, void *dest, int count) { memcpy(dest, source, sizeof(MFloatProperty) * count); @@ -473,16 +506,34 @@ static bool layerValidate_propFloat(void *data, const uint totitems, const bool return has_errors; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Callbacks for (#MIntProperty, #CD_PROP_INT32) + * \{ */ + static void layerCopy_propInt(const void *source, void *dest, int count) { memcpy(dest, source, sizeof(MIntProperty) * count); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Callbacks for (#MStringProperty, #CD_PROP_STRING) + * \{ */ + static void layerCopy_propString(const void *source, void *dest, int count) { memcpy(dest, source, sizeof(MStringProperty) * count); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Callbacks for (#OrigSpaceFace, #CD_ORIGSPACE) + * \{ */ + static void layerCopy_origspace_face(const void *source, void *dest, int count) { const OrigSpaceFace *source_tf = (const OrigSpaceFace *)source; @@ -541,6 +592,12 @@ static void layerDefault_origspace_face(void *data, int count) } } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Callbacks for (#MDisps, #CD_MDISPS) + * \{ */ + static void layerSwap_mdisps(void *data, const int *ci) { MDisps *s = static_cast<MDisps *>(data); @@ -653,6 +710,13 @@ static size_t layerFilesize_mdisps(CDataFile *UNUSED(cdf), const void *data, int return size; } + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Callbacks for (`float`, #CD_PAINT_MASK) + * \{ */ + static void layerInterp_paint_mask(const void **sources, const float *weights, const float *UNUSED(sub_weights), @@ -668,6 +732,12 @@ static void layerInterp_paint_mask(const void **sources, *(float *)dest = mask; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Callbacks for (#GridPaintMask, #CD_GRID_PAINT_MASK) + * \{ */ + static void layerCopy_grid_paint_mask(const void *source, void *dest, int count) { const GridPaintMask *s = static_cast<const GridPaintMask *>(source); @@ -1179,6 +1249,12 @@ static void layerInterp_shapekey(const void **sources, copy_v3_v3((float *)dest, co); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Callbacks for (#MVertSkin, #CD_MVERT_SKIN) + * \{ */ + static void layerDefault_mvert_skin(void *data, int count) { MVertSkin *vs = static_cast<MVertSkin *>(data); @@ -1216,6 +1292,12 @@ static void layerInterp_mvert_skin(const void **sources, vs_dst->flag &= ~MVERT_SKIN_ROOT; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Callbacks for (`short[4][3]`, #CD_TESSLOOPNORMAL) + * \{ */ + static void layerSwap_flnor(void *data, const int *corner_indices) { short(*flnors)[4][3] = static_cast<short(*)[4][3]>(data); @@ -1229,6 +1311,12 @@ static void layerSwap_flnor(void *data, const int *corner_indices) memcpy(flnors, nors, sizeof(nors)); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Callbacks for (`int`, #CD_FACEMAP) + * \{ */ + static void layerDefault_fmap(void *data, int count) { int *fmap_num = (int *)data; @@ -1237,6 +1325,12 @@ static void layerDefault_fmap(void *data, int count) } } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Callbacks for (#MPropCol, #CD_PROP_COLOR) + * \{ */ + static void layerCopyValue_propcol(const void *source, void *dest, const int mixmode, @@ -1360,6 +1454,12 @@ static int layerMaxNum_propcol() return MAX_MCOL; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Callbacks for (#vec3f, #CD_PROP_FLOAT3) + * \{ */ + static void layerInterp_propfloat3(const void **sources, const float *weights, const float *UNUSED(sub_weights), @@ -1407,6 +1507,12 @@ static bool layerValidate_propfloat3(void *data, const uint totitems, const bool return has_errors; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Callbacks for (#vec2f, #CD_PROP_FLOAT2) + * \{ */ + static void layerInterp_propfloat2(const void **sources, const float *weights, const float *UNUSED(sub_weights), @@ -1452,6 +1558,12 @@ static bool layerValidate_propfloat2(void *data, const uint totitems, const bool return has_errors; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Callbacks for (`bool`, #CD_PROP_BOOL) + * \{ */ + static void layerInterp_propbool(const void **sources, const float *weights, const float *UNUSED(sub_weights), @@ -2053,7 +2165,12 @@ void customData_mask_layers__print(const CustomData_MeshMasks *mask) } } -/********************* CustomData functions *********************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name CustomData Functions + * \{ */ + static void customData_update_offsets(CustomData *data); static CustomDataLayer *customData_add_layer__internal(CustomData *data, @@ -4471,14 +4588,18 @@ void CustomData_layers__print(CustomData *data) printf("}\n"); } -/****************************** External Files *******************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name External Files + * \{ */ -static void customdata_external_filename(char filename[FILE_MAX], +static void customdata_external_filename(char filepath[FILE_MAX], ID *id, CustomDataExternal *external) { - BLI_strncpy(filename, external->filename, FILE_MAX); - BLI_path_abs(filename, ID_BLEND_PATH_FROM_GLOBAL(id)); + BLI_strncpy(filepath, external->filepath, FILE_MAX); + BLI_path_abs(filepath, ID_BLEND_PATH_FROM_GLOBAL(id)); } void CustomData_external_reload(CustomData *data, ID *UNUSED(id), CustomDataMask mask, int totelem) @@ -4503,7 +4624,7 @@ void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int { CustomDataExternal *external = data->external; CustomDataLayer *layer; - char filename[FILE_MAX]; + char filepath[FILE_MAX]; int update = 0; if (!external) { @@ -4529,12 +4650,12 @@ void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int return; } - customdata_external_filename(filename, id, external); + customdata_external_filename(filepath, id, external); CDataFile *cdf = cdf_create(CDF_TYPE_MESH); - if (!cdf_read_open(cdf, filename)) { + if (!cdf_read_open(cdf, filepath)) { cdf_free(cdf); - CLOG_ERROR(&LOG, "Failed to read %s layer from %s.", layerType_getName(layer->type), filename); + CLOG_ERROR(&LOG, "Failed to read %s layer from %s.", layerType_getName(layer->type), filepath); return; } @@ -4577,7 +4698,7 @@ void CustomData_external_write( { CustomDataExternal *external = data->external; int update = 0; - char filename[FILE_MAX]; + char filepath[FILE_MAX]; if (!external) { return; @@ -4602,7 +4723,7 @@ void CustomData_external_write( /* make sure data is read before we try to write */ CustomData_external_read(data, id, mask, totelem); - customdata_external_filename(filename, id, external); + customdata_external_filename(filepath, id, external); CDataFile *cdf = cdf_create(CDF_TYPE_MESH); @@ -4622,8 +4743,8 @@ void CustomData_external_write( } } - if (!cdf_write_open(cdf, filename)) { - CLOG_ERROR(&LOG, "Failed to open %s for writing.", filename); + if (!cdf_write_open(cdf, filepath)) { + CLOG_ERROR(&LOG, "Failed to open %s for writing.", filepath); cdf_free(cdf); return; } @@ -4651,7 +4772,7 @@ void CustomData_external_write( } if (i != data->totlayer) { - CLOG_ERROR(&LOG, "Failed to write data to %s.", filename); + CLOG_ERROR(&LOG, "Failed to write data to %s.", filepath); cdf_write_close(cdf); cdf_free(cdf); return; @@ -4676,7 +4797,7 @@ void CustomData_external_write( } void CustomData_external_add( - CustomData *data, ID *UNUSED(id), int type, int UNUSED(totelem), const char *filename) + CustomData *data, ID *UNUSED(id), int type, int UNUSED(totelem), const char *filepath) { CustomDataExternal *external = data->external; @@ -4695,7 +4816,7 @@ void CustomData_external_add( external = MEM_cnew<CustomDataExternal>(__func__); data->external = external; } - BLI_strncpy(external->filename, filename, sizeof(external->filename)); + BLI_strncpy(external->filepath, filepath, sizeof(external->filepath)); layer->flag |= CD_FLAG_EXTERNAL | CD_FLAG_IN_MEMORY; } @@ -4735,7 +4856,12 @@ bool CustomData_external_test(CustomData *data, int type) return (layer->flag & CD_FLAG_EXTERNAL) != 0; } -/* ********** Mesh-to-mesh data transfer ********** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Mesh-to-Mesh Data Transfer + * \{ */ + static void copy_bit_flag(void *dst, const void *src, const size_t data_size, const uint64_t flag) { #define COPY_BIT_FLAG(_type, _dst, _src, _f) \ @@ -5014,6 +5140,12 @@ void CustomData_data_transfer(const MeshPairRemap *me_remap, MEM_SAFE_FREE(tmp_data_src); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Custom Data IO + * \{ */ + static void write_mdisps(BlendWriter *writer, int count, MDisps *mdlist, int external) { if (mdlist) { @@ -5208,6 +5340,12 @@ void CustomData_blend_read(BlendDataReader *reader, CustomData *data, int count) CustomData_update_typemap(data); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Custom Data Debugging + * \{ */ + #ifndef NDEBUG void CustomData_debug_info_from_layers(const CustomData *data, const char *indent, DynStr *dynstr) @@ -5238,8 +5376,16 @@ void CustomData_debug_info_from_layers(const CustomData *data, const char *inden #endif /* NDEBUG */ +/** \} */ + namespace blender::bke { +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Custom Data C++ API + * \{ */ + const blender::CPPType *custom_data_type_to_cpp_type(const CustomDataType type) { switch (type) { @@ -5289,4 +5435,6 @@ CustomDataType cpp_type_to_custom_data_type(const blender::CPPType &type) return static_cast<CustomDataType>(-1); } +/** \} */ + } // namespace blender::bke diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 8ec7bbea0e5..0f5814c0a23 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -3266,7 +3266,7 @@ static void dynamic_paint_output_surface_image_wetmap_cb( } void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface, - char *filename, + const char *filepath, short output_layer) { ImBuf *ibuf = NULL; @@ -3286,7 +3286,7 @@ void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface, format = R_IMF_IMTYPE_PNG; } #endif - BLI_strncpy(output_file, filename, sizeof(output_file)); + BLI_strncpy(output_file, filepath, sizeof(output_file)); BKE_image_path_ensure_ext_from_imtype(output_file, format); /* Validate output file path */ diff --git a/source/blender/blenkernel/intern/geometry_component_curves.cc b/source/blender/blenkernel/intern/geometry_component_curves.cc index 7cf6fc5a03e..27689d70c77 100644 --- a/source/blender/blenkernel/intern/geometry_component_curves.cc +++ b/source/blender/blenkernel/intern/geometry_component_curves.cc @@ -236,10 +236,10 @@ int CurveComponent::attribute_domain_size(const AttributeDomain domain) const const blender::bke::CurvesGeometry &geometry = blender::bke::CurvesGeometry::wrap( curves_->geometry); if (domain == ATTR_DOMAIN_POINT) { - return geometry.points_size(); + return geometry.points_num(); } if (domain == ATTR_DOMAIN_CURVE) { - return geometry.curves_size(); + return geometry.curves_num(); } return 0; } diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index 76c8a0054b3..2bfe984462c 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -944,20 +944,71 @@ class VArrayImpl_For_VertexWeights final : public VMutableArrayImpl<float> { if (dverts_ == nullptr) { return 0.0f; } - const MDeformVert &dvert = dverts_[index]; - for (const MDeformWeight &weight : Span(dvert.dw, dvert.totweight)) { - if (weight.def_nr == dvert_index_) { - return weight.weight; - } + if (const MDeformWeight *weight = this->find_weight_at_index(index)) { + return weight->weight; } return 0.0f; - ; } void set(const int64_t index, const float value) override { - MDeformWeight *weight = BKE_defvert_ensure_index(&dverts_[index], dvert_index_); - weight->weight = value; + MDeformVert &dvert = dverts_[index]; + if (value == 0.0f) { + if (MDeformWeight *weight = this->find_weight_at_index(index)) { + weight->weight = 0.0f; + } + } + else { + MDeformWeight *weight = BKE_defvert_ensure_index(&dvert, dvert_index_); + weight->weight = value; + } + } + + void set_all(Span<float> src) override + { + for (const int64_t index : src.index_range()) { + this->set(index, src[index]); + } + } + + void materialize(IndexMask mask, MutableSpan<float> r_span) const override + { + if (dverts_ == nullptr) { + return r_span.fill_indices(mask, 0.0f); + } + for (const int64_t index : mask) { + if (const MDeformWeight *weight = this->find_weight_at_index(index)) { + r_span[index] = weight->weight; + } + else { + r_span[index] = 0.0f; + } + } + } + + void materialize_to_uninitialized(IndexMask mask, MutableSpan<float> r_span) const override + { + this->materialize(mask, r_span); + } + + private: + MDeformWeight *find_weight_at_index(const int64_t index) + { + for (MDeformWeight &weight : MutableSpan(dverts_[index].dw, dverts_[index].totweight)) { + if (weight.def_nr == dvert_index_) { + return &weight; + } + } + return nullptr; + } + const MDeformWeight *find_weight_at_index(const int64_t index) const + { + for (const MDeformWeight &weight : Span(dverts_[index].dw, dverts_[index].totweight)) { + if (weight.def_nr == dvert_index_) { + return &weight; + } + } + return nullptr; } }; diff --git a/source/blender/blenkernel/intern/gpencil_geom.cc b/source/blender/blenkernel/intern/gpencil_geom.cc index a5eff1f9d5a..a0b6ab2d654 100644 --- a/source/blender/blenkernel/intern/gpencil_geom.cc +++ b/source/blender/blenkernel/intern/gpencil_geom.cc @@ -980,74 +980,116 @@ bool BKE_gpencil_stroke_shrink(bGPDstroke *gps, const float dist, const short mo /** \name Stroke Smooth Positions * \{ */ -bool BKE_gpencil_stroke_smooth_point(bGPDstroke *gps, int i, float inf, const bool smooth_caps) +bool BKE_gpencil_stroke_smooth_point(bGPDstroke *gps, + int i, + float influence, + int iterations, + const bool smooth_caps, + const bool keep_shape, + bGPDstroke *r_gps) { - bGPDspoint *pt = &gps->points[i]; - float sco[3] = {0.0f}; - const bool is_cyclic = (gps->flag & GP_STROKE_CYCLIC) != 0; - - /* Do nothing if not enough points to smooth out */ - if (gps->totpoints <= 2) { + /* If nothing to do, return early */ + if (gps->totpoints <= 2 || iterations <= 0) { return false; } - /* Only affect endpoints by a fraction of the normal strength, - * to prevent the stroke from shrinking too much + /* Overview of the algorithm here and in the following smooth functions: + * The smooth functions return the new attribute in question for a single point. + * The result is stored in r_gps->points[i], while the data is read from gps. + * To get a correct result, duplicate the stroke point data and read from the copy, + * while writing to the real stroke. Not doing that will result in acceptable, but + * asymmetric results. + * This algorithm works as long as all points are being smoothed. If there is + * points that should not get smoothed, use the old repeat smooth pattern with + * the parameter "iterations" set to 1 or 2. (2 matches the old algorithm). */ - if ((!smooth_caps) && (!is_cyclic && ELEM(i, 0, gps->totpoints - 1))) { - inf *= 0.1f; - } - - /* Compute smoothed coordinate by taking the ones nearby */ - /* XXX: This is potentially slow, - * and suffers from accumulation error as earlier points are handled before later ones. */ - { - /* XXX: this is hardcoded to look at 2 points on either side of the current one - * (i.e. 5 items total). */ - const int steps = 2; - const float average_fac = 1.0f / (float)(steps * 2 + 1); - int step; - - /* add the point itself */ - madd_v3_v3fl(sco, &pt->x, average_fac); - - /* n-steps before/after current point */ - /* XXX: review how the endpoints are treated by this algorithm. */ - /* XXX: falloff measures should also introduce some weighting variations, - * so that further-out points get less weight. */ - for (step = 1; step <= steps; step++) { - bGPDspoint *pt1, *pt2; - int before = i - step; - int after = i + step; - - if (is_cyclic) { - if (before < 0) { - /* Sub to end point (before is already negative). */ - before = gps->totpoints + before; - CLAMP(before, 0, gps->totpoints - 1); - } - if (after > gps->totpoints - 1) { - /* Add to start point. */ - after = after - gps->totpoints; - CLAMP(after, 0, gps->totpoints - 1); + + const bGPDspoint *pt = &gps->points[i]; + const bool is_cyclic = (gps->flag & GP_STROKE_CYCLIC) != 0; + /* If smooth_caps is false, the caps will not be translated by smoothing. */ + if (!smooth_caps && !is_cyclic && ELEM(i, 0, gps->totpoints - 1)) { + copy_v3_v3(&r_gps->points[i].x, &pt->x); + return true; + } + + /* This function uses a binomial kernel, which is the discrete version of gaussian blur. + * The weight for a vertex at the relative index i is + * w = nCr(n, j + n/2) / 2^n = (n/1 * (n-1)/2 * ... * (n-j-n/2)/(j+n/2)) / 2^n + * All weights together sum up to 1 + * This is equivalent to doing multiple iterations of averaging neighbors, + * where n = iterations * 2 and -n/2 <= j <= n/2 + * + * Now the problem is that nCr(n, j + n/2) is very hard to compute for n > 500, since even + * double precision isn't sufficient. A very good robust approximation for n > 20 is + * nCr(n, j + n/2) / 2^n = sqrt(2/(pi*n)) * exp(-2*j*j/n) + * + * There is one more problem left: The old smooth algorithm was doing a more aggressive + * smooth. To solve that problem, choose a different n/2, which does not match the range and + * normalize the weights on finish. This may cause some artifacts at low values. + * + * keep_shape is a new option to stop the stroke from severly deforming. + * It uses different partially negative weights. + * w = 2 * (nCr(n, j + n/2) / 2^n) - (nCr(3*n, j + n) / 2^(3*n)) + * ~ 2 * sqrt(2/(pi*n)) * exp(-2*j*j/n) - sqrt(2/(pi*3*n)) * exp(-2*j*j/(3*n)) + * All weigths still sum up to 1. + * Note these weights only work because the averaging is done in relative coordinates. + */ + float sco[3] = {0.0f, 0.0f, 0.0f}; + float tmp[3]; + const int n_half = keep_shape ? (iterations * iterations) / 8 + iterations : + (iterations * iterations) / 4 + 2 * iterations + 12; + double w = keep_shape ? 2.0 : 1.0; + double w2 = keep_shape ? + (1.0 / M_SQRT3) * exp((2 * iterations * iterations) / (double)(n_half * 3)) : + 0.0; + double total_w = 0.0; + for (int step = iterations; step > 0; step--) { + int before = i - step; + int after = i + step; + float w_before = (float)(w - w2); + float w_after = (float)(w - w2); + + if (is_cyclic) { + before = (before % gps->totpoints + gps->totpoints) % gps->totpoints; + after = after % gps->totpoints; + } + else { + if (before < 0) { + if (!smooth_caps) { + w_before *= -before / (float)i; } + before = 0; } - else { - CLAMP_MIN(before, 0); - CLAMP_MAX(after, gps->totpoints - 1); + if (after > gps->totpoints - 1) { + if (!smooth_caps) { + w_after *= (after - (gps->totpoints - 1)) / (float)(gps->totpoints - 1 - i); + } + after = gps->totpoints - 1; } + } - pt1 = &gps->points[before]; - pt2 = &gps->points[after]; + /* Add both these points in relative coordinates to the weighted average sum. */ + sub_v3_v3v3(tmp, &gps->points[before].x, &pt->x); + madd_v3_v3fl(sco, tmp, w_before); + sub_v3_v3v3(tmp, &gps->points[after].x, &pt->x); + madd_v3_v3fl(sco, tmp, w_after); - /* add both these points to the average-sum (s += p[i]/n) */ - madd_v3_v3fl(sco, &pt1->x, average_fac); - madd_v3_v3fl(sco, &pt2->x, average_fac); - } + total_w += w_before; + total_w += w_after; + + w *= (n_half + step) / (double)(n_half + 1 - step); + w2 *= (n_half * 3 + step) / (double)(n_half * 3 + 1 - step); } + total_w += w - w2; + /* The accumulated weight total_w should be + * ~sqrt(M_PI * n_half) * exp((iterations * iterations) / n_half) < 100 + * here, but sometimes not quite. */ + mul_v3_fl(sco, (float)(1.0 / total_w)); + /* Shift back to global coordinates. */ + add_v3_v3(sco, &pt->x); - /* Based on influence factor, blend between original and optimal smoothed coordinate */ - interp_v3_v3v3(&pt->x, &pt->x, sco, inf); + /* Based on influence factor, blend between original and optimal smoothed coordinate. */ + interp_v3_v3v3(&r_gps->points[i].x, &pt->x, sco, influence); return true; } @@ -1058,74 +1100,54 @@ bool BKE_gpencil_stroke_smooth_point(bGPDstroke *gps, int i, float inf, const bo /** \name Stroke Smooth Strength * \{ */ -bool BKE_gpencil_stroke_smooth_strength(bGPDstroke *gps, int point_index, float influence) +bool BKE_gpencil_stroke_smooth_strength( + bGPDstroke *gps, int i, float influence, int iterations, bGPDstroke *r_gps) { - bGPDspoint *ptb = &gps->points[point_index]; - const bool is_cyclic = (gps->flag & GP_STROKE_CYCLIC) != 0; - - /* Do nothing if not enough points */ - if ((gps->totpoints <= 2) || (point_index < 1)) { + /* If nothing to do, return early */ + if (gps->totpoints <= 2 || iterations <= 0) { return false; } - /* Only affect endpoints by a fraction of the normal influence */ - float inf = influence; - if (!is_cyclic && ELEM(point_index, 0, gps->totpoints - 1)) { - inf *= 0.01f; - } - /* Limit max influence to reduce pop effect. */ - CLAMP_MAX(inf, 0.98f); - - float total = 0.0f; - float max_strength = 0.0f; - const int steps = 4; - const float average_fac = 1.0f / (float)(steps * 2 + 1); - int step; - /* add the point itself */ - total += ptb->strength * average_fac; - max_strength = ptb->strength; + /* See BKE_gpencil_stroke_smooth_point for details on the algorithm. */ - /* n-steps before/after current point */ - for (step = 1; step <= steps; step++) { - bGPDspoint *pt1, *pt2; - int before = point_index - step; - int after = point_index + step; + const bGPDspoint *pt = &gps->points[i]; + const bool is_cyclic = (gps->flag & GP_STROKE_CYCLIC) != 0; + float strength = 0.0f; + const int n_half = (iterations * iterations) / 4 + iterations; + double w = 1.0; + double total_w = 0.0; + for (int step = iterations; step > 0; step--) { + int before = i - step; + int after = i + step; + float w_before = (float)w; + float w_after = (float)w; if (is_cyclic) { - if (before < 0) { - /* Sub to end point (before is already negative). */ - before = gps->totpoints + before; - CLAMP(before, 0, gps->totpoints - 1); - } - if (after > gps->totpoints - 1) { - /* Add to start point. */ - after = after - gps->totpoints; - CLAMP(after, 0, gps->totpoints - 1); - } + before = (before % gps->totpoints + gps->totpoints) % gps->totpoints; + after = after % gps->totpoints; } else { CLAMP_MIN(before, 0); CLAMP_MAX(after, gps->totpoints - 1); } - pt1 = &gps->points[before]; - pt2 = &gps->points[after]; - /* add both these points to the average-sum (s += p[i]/n) */ - total += pt1->strength * average_fac; - total += pt2->strength * average_fac; - /* Save max value. */ - if (max_strength < pt1->strength) { - max_strength = pt1->strength; - } - if (max_strength < pt2->strength) { - max_strength = pt2->strength; - } + /* Add both these points in relative coordinates to the weighted average sum. */ + strength += w_before * (gps->points[before].strength - pt->strength); + strength += w_after * (gps->points[after].strength - pt->strength); + + total_w += w_before; + total_w += w_after; + + w *= (n_half + step) / (double)(n_half + 1 - step); } + total_w += w; + /* The accumulated weight total_w should be + * ~sqrt(M_PI * n_half) * exp((iterations * iterations) / n_half) < 100 + * here, but sometimes not quite. */ + strength /= total_w; /* Based on influence factor, blend between original and optimal smoothed value. */ - ptb->strength = interpf(ptb->strength, total, inf); - /* Clamp to maximum stroke strength to avoid weird results. */ - CLAMP_MAX(ptb->strength, max_strength); + r_gps->points[i].strength = pt->strength + strength * influence; return true; } @@ -1136,74 +1158,55 @@ bool BKE_gpencil_stroke_smooth_strength(bGPDstroke *gps, int point_index, float /** \name Stroke Smooth Thickness * \{ */ -bool BKE_gpencil_stroke_smooth_thickness(bGPDstroke *gps, int point_index, float influence) +bool BKE_gpencil_stroke_smooth_thickness( + bGPDstroke *gps, int i, float influence, int iterations, bGPDstroke *r_gps) { - bGPDspoint *ptb = &gps->points[point_index]; - const bool is_cyclic = (gps->flag & GP_STROKE_CYCLIC) != 0; - - /* Do nothing if not enough points */ - if ((gps->totpoints <= 2) || (point_index < 1)) { + /* If nothing to do, return early */ + if (gps->totpoints <= 2 || iterations <= 0) { return false; } - /* Only affect endpoints by a fraction of the normal influence */ - float inf = influence; - if (!is_cyclic && ELEM(point_index, 0, gps->totpoints - 1)) { - inf *= 0.01f; - } - /* Limit max influence to reduce pop effect. */ - CLAMP_MAX(inf, 0.98f); - - float total = 0.0f; - float max_pressure = 0.0f; - const int steps = 4; - const float average_fac = 1.0f / (float)(steps * 2 + 1); - int step; - /* add the point itself */ - total += ptb->pressure * average_fac; - max_pressure = ptb->pressure; + /* See BKE_gpencil_stroke_smooth_point for details on the algorithm. */ - /* n-steps before/after current point */ - for (step = 1; step <= steps; step++) { - bGPDspoint *pt1, *pt2; - int before = point_index - step; - int after = point_index + step; + const bGPDspoint *pt = &gps->points[i]; + const bool is_cyclic = (gps->flag & GP_STROKE_CYCLIC) != 0; + float pressure = 0.0f; + const int n_half = (iterations * iterations) / 4 + iterations; + double w = 1.0; + double total_w = 0.0; + for (int step = iterations; step > 0; step--) { + int before = i - step; + int after = i + step; + float w_before = (float)w; + float w_after = (float)w; if (is_cyclic) { - if (before < 0) { - /* Sub to end point (before is already negative). */ - before = gps->totpoints + before; - CLAMP(before, 0, gps->totpoints - 1); - } - if (after > gps->totpoints - 1) { - /* Add to start point. */ - after = after - gps->totpoints; - CLAMP(after, 0, gps->totpoints - 1); - } + before = (before % gps->totpoints + gps->totpoints) % gps->totpoints; + after = after % gps->totpoints; } else { CLAMP_MIN(before, 0); CLAMP_MAX(after, gps->totpoints - 1); } - pt1 = &gps->points[before]; - pt2 = &gps->points[after]; - /* add both these points to the average-sum (s += p[i]/n) */ - total += pt1->pressure * average_fac; - total += pt2->pressure * average_fac; - /* Save max value. */ - if (max_pressure < pt1->pressure) { - max_pressure = pt1->pressure; - } - if (max_pressure < pt2->pressure) { - max_pressure = pt2->pressure; - } + /* Add both these points in relative coordinates to the weighted average sum. */ + pressure += w_before * (gps->points[before].pressure - pt->pressure); + pressure += w_after * (gps->points[after].pressure - pt->pressure); + + total_w += w_before; + total_w += w_after; + + w *= (n_half + step) / (double)(n_half + 1 - step); } + total_w += w; + /* The accumulated weight total_w should be + * ~sqrt(M_PI * n_half) * exp((iterations * iterations) / n_half) < 100 + * here, but sometimes not quite. */ + pressure /= total_w; /* Based on influence factor, blend between original and optimal smoothed value. */ - ptb->pressure = interpf(ptb->pressure, total, inf); - /* Clamp to maximum stroke thickness to avoid weird results. */ - CLAMP_MAX(ptb->pressure, max_pressure); + r_gps->points[i].pressure = pt->pressure + pressure * influence; + return true; } @@ -1213,57 +1216,127 @@ bool BKE_gpencil_stroke_smooth_thickness(bGPDstroke *gps, int point_index, float /** \name Stroke Smooth UV * \{ */ -bool BKE_gpencil_stroke_smooth_uv(bGPDstroke *gps, int point_index, float influence) +bool BKE_gpencil_stroke_smooth_uv( + struct bGPDstroke *gps, int i, float influence, int iterations, struct bGPDstroke *r_gps) { - bGPDspoint *ptb = &gps->points[point_index]; + /* If nothing to do, return early */ + if (gps->totpoints <= 2 || iterations <= 0) { + return false; + } + + /* See BKE_gpencil_stroke_smooth_point for details on the algorithm. */ + + const bGPDspoint *pt = &gps->points[i]; const bool is_cyclic = (gps->flag & GP_STROKE_CYCLIC) != 0; - /* Do nothing if not enough points */ - if (gps->totpoints <= 2) { - return false; + /* If don't change the caps. */ + if (!is_cyclic && ELEM(i, 0, gps->totpoints - 1)) { + r_gps->points[i].uv_rot = pt->uv_rot; + r_gps->points[i].uv_fac = pt->uv_fac; + return true; } - /* Compute theoretical optimal value */ - bGPDspoint *pta, *ptc; - int before = point_index - 1; - int after = point_index + 1; + float uv_rot = 0.0f; + float uv_fac = 0.0f; + const int n_half = iterations * iterations + iterations; + double w = 1.0; + double total_w = 0.0; + for (int step = iterations; step > 0; step--) { + int before = i - step; + int after = i + step; + float w_before = (float)w; + float w_after = (float)w; - if (is_cyclic) { - if (before < 0) { - /* Sub to end point (before is already negative). */ - before = gps->totpoints + before; - CLAMP(before, 0, gps->totpoints - 1); + if (is_cyclic) { + before = (before % gps->totpoints + gps->totpoints) % gps->totpoints; + after = after % gps->totpoints; } - if (after > gps->totpoints - 1) { - /* Add to start point. */ - after = after - gps->totpoints; - CLAMP(after, 0, gps->totpoints - 1); + else { + if (before < 0) { + w_before *= -before / (float)i; + before = 0; + } + if (after > gps->totpoints - 1) { + w_after *= (after - (gps->totpoints - 1)) / (float)(gps->totpoints - 1 - i); + after = gps->totpoints - 1; + } } - } - else { - CLAMP_MIN(before, 0); - CLAMP_MAX(after, gps->totpoints - 1); - } - pta = &gps->points[before]; - ptc = &gps->points[after]; - /* the optimal value is the corresponding to the interpolation of the pressure - * at the distance of point b - */ - float fac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x); - /* sometimes the factor can be wrong due stroke geometry, so use middle point */ - if ((fac < 0.0f) || (fac > 1.0f)) { - fac = 0.5f; + /* Add both these points in relative coordinates to the weighted average sum. */ + uv_rot += w_before * (gps->points[before].uv_rot - pt->uv_rot); + uv_rot += w_after * (gps->points[after].uv_rot - pt->uv_rot); + uv_fac += w_before * (gps->points[before].uv_fac - pt->uv_fac); + uv_fac += w_after * (gps->points[after].uv_fac - pt->uv_fac); + + total_w += w_before; + total_w += w_after; + + w *= (n_half + step) / (double)(n_half + 1 - step); } - float optimal = interpf(ptc->uv_rot, pta->uv_rot, fac); + total_w += w; + /* The accumulated weight total_w should be + * ~sqrt(M_PI * n_half) * exp((iterations * iterations) / n_half) < 100 + * here, but sometimes not quite. */ + uv_rot /= total_w; + uv_fac /= total_w; - /* Based on influence factor, blend between original and optimal */ - ptb->uv_rot = interpf(optimal, ptb->uv_rot, influence); - CLAMP(ptb->uv_rot, -M_PI_2, M_PI_2); + /* Based on influence factor, blend between original and optimal smoothed value. */ + r_gps->points[i].uv_rot = pt->uv_rot + uv_rot * influence; + r_gps->points[i].uv_fac = pt->uv_fac + uv_fac * influence; return true; } +void BKE_gpencil_stroke_smooth(bGPDstroke *gps, + const float influence, + const int iterations, + const bool smooth_position, + const bool smooth_strength, + const bool smooth_thickness, + const bool smooth_uv, + const bool keep_shape, + const float *weights) +{ + if (influence <= 0 || iterations <= 0) { + return; + } + + /* Make a copy of the point data to avoid directionality of the smooth operation. */ + bGPDstroke gps_old = *gps; + gps_old.points = (bGPDspoint *)MEM_dupallocN(gps->points); + + /* Smooth stroke. */ + for (int i = 0; i < gps->totpoints; i++) { + float val = influence; + if (weights != NULL) { + val *= weights[i]; + if (val <= 0.0f) { + continue; + } + } + + /* TODO: Currently the weights only control the influence, but is would be much better if they + * would control the distribution used in smooth, similar to how the ends are handled. */ + + /* Perform smoothing. */ + if (smooth_position) { + BKE_gpencil_stroke_smooth_point(&gps_old, i, val, iterations, false, keep_shape, gps); + } + if (smooth_strength) { + BKE_gpencil_stroke_smooth_strength(&gps_old, i, val, iterations, gps); + } + if (smooth_thickness) { + BKE_gpencil_stroke_smooth_thickness(&gps_old, i, val, iterations, gps); + } + if (smooth_uv) { + BKE_gpencil_stroke_smooth_uv(&gps_old, i, val, iterations, gps); + } + } + + /* Free the copied points array. */ + MEM_freeN(gps_old.points); +} + void BKE_gpencil_stroke_2d_flat(const bGPDspoint *points, int totpoints, float (*points2d)[2], @@ -3443,7 +3516,7 @@ void BKE_gpencil_stroke_join(bGPDstroke *gps_a, for (i = start; i < end; i++) { pt = &gps_a->points[i]; pt->pressure += (avg_pressure - pt->pressure) * ratio; - BKE_gpencil_stroke_smooth_point(gps_a, i, ratio * 0.6f, false); + BKE_gpencil_stroke_smooth_point(gps_a, i, ratio * 0.6f, 2, false, true, gps_a); ratio += step; /* In the center, reverse the ratio. */ diff --git a/source/blender/blenkernel/intern/image.cc b/source/blender/blenkernel/intern/image.cc index cfdd048495d..3eade265bf2 100644 --- a/source/blender/blenkernel/intern/image.cc +++ b/source/blender/blenkernel/intern/image.cc @@ -9,6 +9,7 @@ #include <cmath> #include <cstdio> #include <cstring> +#include <ctime> #include <fcntl.h> #ifndef WIN32 # include <unistd.h> @@ -16,7 +17,8 @@ # include <io.h> #endif -#include <ctime> +#include <regex> +#include <string> #include "BLI_array.hh" @@ -237,7 +239,7 @@ static void image_foreach_cache(ID *id, auto gputexture_offset = [image](int target, int eye, int resolution) { constexpr size_t base_offset = offsetof(Image, gputexture); - const auto first = &image->gputexture[0][0][0]; + struct GPUTexture **first = &image->gputexture[0][0][0]; const size_t array_offset = sizeof(*first) * (&image->gputexture[target][eye][resolution] - first); return base_offset + array_offset; @@ -466,7 +468,9 @@ constexpr IDTypeInfo get_type_info() IDTypeInfo IDType_ID_IM = get_type_info(); /* prototypes */ -static int image_num_files(struct Image *ima); +static int image_num_viewfiles(Image *ima); +static ImBuf *image_load_image_file( + Image *ima, ImageUser *iuser, int entry, int cfra, bool is_sequence); static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock); static void image_update_views_format(Image *ima, ImageUser *iuser); static void image_add_view(Image *ima, const char *viewname, const char *filepath); @@ -487,9 +491,9 @@ static void image_add_view(Image *ima, const char *viewname, const char *filepat /** \name Image Cache * \{ */ -typedef struct ImageCacheKey { +struct ImageCacheKey { int index; -} ImageCacheKey; +}; static unsigned int imagecache_hashhash(const void *key_v) { @@ -1275,9 +1279,9 @@ bool BKE_image_memorypack(Image *ima) void BKE_image_packfiles(ReportList *reports, Image *ima, const char *basepath) { - const int totfiles = image_num_files(ima); + const int tot_viewfiles = image_num_viewfiles(ima); - if (totfiles == 1) { + if (tot_viewfiles == 1) { ImagePackedFile *imapf = static_cast<ImagePackedFile *>( MEM_mallocN(sizeof(ImagePackedFile), "Image packed file")); BLI_addtail(&ima->packedfiles, imapf); @@ -1311,9 +1315,9 @@ void BKE_image_packfiles_from_mem(ReportList *reports, char *data, const size_t data_len) { - const int totfiles = image_num_files(ima); + const int tot_viewfiles = image_num_viewfiles(ima); - if (totfiles != 1) { + if (tot_viewfiles != 1) { BKE_report(reports, RPT_ERROR, "Cannot pack multiview images from raw data currently..."); } else { @@ -2942,9 +2946,9 @@ void BKE_image_signal(Main *bmain, Image *ima, ImageUser *iuser, int signal) case IMA_SIGNAL_RELOAD: /* try to repack file */ if (BKE_image_has_packedfile(ima)) { - const int totfiles = image_num_files(ima); + const int tot_viewfiles = image_num_viewfiles(ima); - if (totfiles != BLI_listbase_count_at_most(&ima->packedfiles, totfiles + 1)) { + if (tot_viewfiles != BLI_listbase_count_at_most(&ima->packedfiles, tot_viewfiles + 1)) { /* in case there are new available files to be loaded */ image_free_packedfiles(ima); BKE_image_packfiles(nullptr, ima, ID_BLEND_PATH(bmain, &ima->id)); @@ -3111,14 +3115,15 @@ bool BKE_image_get_tile_info(char *filepath, ListBase *tiles, int *tile_start, i int max_udim = 0; int id; - struct direntry *dir; - uint totfile = BLI_filelist_dir_contents(dirname, &dir); - for (int i = 0; i < totfile; i++) { - if (!(dir[i].type & S_IFREG)) { + struct direntry *dirs; + const uint dirs_num = BLI_filelist_dir_contents(dirname, &dirs); + for (int i = 0; i < dirs_num; i++) { + if (!(dirs[i].type & S_IFREG)) { continue; } - if (!BKE_image_get_tile_number_from_filepath(dir[i].relname, udim_pattern, tile_format, &id)) { + if (!BKE_image_get_tile_number_from_filepath( + dirs[i].relname, udim_pattern, tile_format, &id)) { continue; } @@ -3131,7 +3136,7 @@ bool BKE_image_get_tile_info(char *filepath, ListBase *tiles, int *tile_start, i min_udim = min_ii(min_udim, id); max_udim = max_ii(max_udim, id); } - BLI_filelist_free(dir, totfile); + BLI_filelist_free(dirs, dirs_num); MEM_SAFE_FREE(udim_pattern); if (is_udim && min_udim <= IMA_UDIM_MAX) { @@ -3316,69 +3321,24 @@ void BKE_image_ensure_tile_token(char *filename) return; } - /* Is there a sequence of digits in the filename? */ - ushort digits; - char head[FILE_MAX], tail[FILE_MAX]; - BLI_path_sequence_decode(filename, head, tail, &digits); - if (digits == 4) { - sprintf(filename, "%s<UDIM>%s", head, tail); - return; - } - - /* Is there a sequence like u##_v#### in the filename? */ - uint cur = 0; - uint name_end = strlen(filename); - uint u_digits = 0; - uint v_digits = 0; - uint u_start = (uint)-1; - bool u_found = false; - bool v_found = false; - bool sep_found = false; - while (cur < name_end) { - if (filename[cur] == 'u') { - u_found = true; - u_digits = 0; - u_start = cur; - } - else if (filename[cur] == 'v') { - v_found = true; - v_digits = 0; - } - else if (u_found && !v_found) { - if (isdigit(filename[cur]) && u_digits < 2) { - u_digits++; - } - else if (filename[cur] == '_') { - sep_found = true; - } - else { - u_found = false; - } - } - else if (u_found && u_digits > 0 && v_found) { - if (isdigit(filename[cur])) { - if (v_digits < 4) { - v_digits++; - } - else { - u_found = false; - v_found = false; - } - } - else if (v_digits > 0) { - break; - } - } + std::string path(filename); + std::smatch match; - cur++; + /* General 4-digit "udim" pattern. As this format is susceptible to ambiguity + * with other digit sequences, we can leverage the supported range of roughly + * 1000 through 2000 to provide better detection. + */ + std::regex pattern(R"((^|.*?\D)([12]\d{3})(\D.*))"); + if (std::regex_search(path, match, pattern)) { + BLI_strncpy(filename, match.format("$1<UDIM>$3").c_str(), FILE_MAX); + return; } - if (u_found && sep_found && v_found && (u_digits + v_digits > 1)) { - const char *token = "<UVTILE>"; - const size_t token_length = strlen(token); - memmove(filename + u_start + token_length, filename + cur, name_end - cur); - memcpy(filename + u_start, token, token_length); - filename[u_start + token_length + (name_end - cur)] = '\0'; + /* General `u##_v###` `uvtile` pattern. */ + pattern = std::regex(R"((.*)(u\d{1,2}_v\d{1,3})(\D.*))"); + if (std::regex_search(path, match, pattern)) { + BLI_strncpy(filename, match.format("$1<UVTILE>$3").c_str(), FILE_MAX); + return; } } @@ -3393,15 +3353,15 @@ bool BKE_image_tile_filepath_exists(const char *filepath) char *udim_pattern = BKE_image_get_tile_strformat(filepath, &tile_format); bool found = false; - struct direntry *dir; - uint totfile = BLI_filelist_dir_contents(dirname, &dir); - for (int i = 0; i < totfile; i++) { - if (!(dir[i].type & S_IFREG)) { + struct direntry *dirs; + const uint dirs_num = BLI_filelist_dir_contents(dirname, &dirs); + for (int i = 0; i < dirs_num; i++) { + if (!(dirs[i].type & S_IFREG)) { continue; } int id; - if (!BKE_image_get_tile_number_from_filepath(dir[i].path, udim_pattern, tile_format, &id)) { + if (!BKE_image_get_tile_number_from_filepath(dirs[i].path, udim_pattern, tile_format, &id)) { continue; } @@ -3412,7 +3372,7 @@ bool BKE_image_tile_filepath_exists(const char *filepath) found = true; break; } - BLI_filelist_free(dir, totfile); + BLI_filelist_free(dirs, dirs_num); MEM_SAFE_FREE(udim_pattern); return found; @@ -3781,7 +3741,7 @@ static int imbuf_alpha_flags_for_image(Image *ima) /** * \return the number of files will vary according to the stereo format. */ -static int image_num_files(Image *ima) +static int image_num_viewfiles(Image *ima) { const bool is_multiview = BKE_image_is_multiview(ima); @@ -3796,117 +3756,6 @@ static int image_num_files(Image *ima) return BLI_listbase_count(&ima->views); } -static ImBuf *load_sequence_single( - Image *ima, ImageUser *iuser, int frame, const int view_id, bool *r_cache_ibuf) -{ - struct ImBuf *ibuf; - char name[FILE_MAX]; - int flag; - ImageUser iuser_t{}; - - *r_cache_ibuf = true; - - ima->lastframe = frame; - - if (iuser) { - iuser_t = *iuser; - } - else { - /* BKE_image_user_file_path() uses this value for file name for sequences. */ - iuser_t.framenr = frame; - /* TODO(sergey): Do we need to initialize something else here? */ - } - - iuser_t.view = view_id; - BKE_image_user_file_path(&iuser_t, ima, name); - - flag = IB_rect | IB_multilayer | IB_metadata; - flag |= imbuf_alpha_flags_for_image(ima); - - /* read ibuf */ - ibuf = IMB_loadiffname(name, flag, ima->colorspace_settings.name); - -#if 0 - if (ibuf) { - printf(AT " loaded %s\n", name); - } - else { - printf(AT " missed %s\n", name); - } -#endif - - if (ibuf) { -#ifdef WITH_OPENEXR - if (ibuf->ftype == IMB_FTYPE_OPENEXR && ibuf->userdata) { - /* Handle multilayer and multiview cases, don't assign ibuf here. - * will be set layer in BKE_image_acquire_ibuf from ima->rr. */ - if (IMB_exr_has_multilayer(ibuf->userdata)) { - image_create_multilayer(ima, ibuf, frame); - ima->type = IMA_TYPE_MULTILAYER; - IMB_freeImBuf(ibuf); - ibuf = nullptr; - /* Null ibuf in the cache means the image failed to load. However for multilayer we load - * pixels into RenderResult instead and intentionally leave ibuf null. */ - *r_cache_ibuf = false; - } - } - else { - image_init_after_load(ima, iuser, ibuf); - } -#else - image_init_after_load(ima, iuser, ibuf); -#endif - } - - return ibuf; -} - -static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int entry, int frame) -{ - struct ImBuf *ibuf = nullptr; - const bool is_multiview = BKE_image_is_multiview(ima); - const int totfiles = image_num_files(ima); - - if (!is_multiview) { - bool put_in_cache; - ibuf = load_sequence_single(ima, iuser, frame, 0, &put_in_cache); - if (put_in_cache) { - image_assign_ibuf(ima, ibuf, 0, entry); - } - } - else { - const int totviews = BLI_listbase_count(&ima->views); - Array<ImBuf *> ibuf_arr(totviews); - Array<bool> cache_ibuf_arr(totviews); - - for (int i = 0; i < totfiles; i++) { - ibuf_arr[i] = load_sequence_single(ima, iuser, frame, i, &cache_ibuf_arr[i]); - } - - if (BKE_image_is_stereo(ima) && ima->views_format == R_IMF_VIEWS_STEREO_3D) { - IMB_ImBufFromStereo3d(ima->stereo3d_format, ibuf_arr[0], &ibuf_arr[0], &ibuf_arr[1]); - } - - /* return the original requested ImBuf */ - ibuf = ibuf_arr[(iuser ? iuser->multi_index : 0)]; - - for (int i = 0; i < totviews; i++) { - if (cache_ibuf_arr[i]) { - image_assign_ibuf(ima, ibuf_arr[i], i, entry); - } - } - - /* "remove" the others (decrease their refcount) */ - for (int i = 0; i < totviews; i++) { - if (ibuf_arr[i] != ibuf) { - IMB_freeImBuf(ibuf_arr[i]); - } - } - } - - return ibuf; -} - static ImBuf *image_load_sequence_multilayer(Image *ima, ImageUser *iuser, int entry, int frame) { struct ImBuf *ibuf = nullptr; @@ -3925,7 +3774,7 @@ static ImBuf *image_load_sequence_multilayer(Image *ima, ImageUser *iuser, int e ima->rr = nullptr; } - ibuf = image_load_sequence_file(ima, iuser, entry, frame); + ibuf = image_load_image_file(ima, iuser, entry, frame, true); if (ibuf) { /* actually an error */ ima->type = IMA_TYPE_IMAGE; @@ -4012,12 +3861,12 @@ static ImBuf *image_load_movie_file(Image *ima, ImageUser *iuser, int frame) { struct ImBuf *ibuf = nullptr; const bool is_multiview = BKE_image_is_multiview(ima); - const int totfiles = image_num_files(ima); + const int tot_viewfiles = image_num_viewfiles(ima); - if (totfiles != BLI_listbase_count_at_most(&ima->anims, totfiles + 1)) { + if (tot_viewfiles != BLI_listbase_count_at_most(&ima->anims, tot_viewfiles + 1)) { image_free_anims(ima); - for (int i = 0; i < totfiles; i++) { + for (int i = 0; i < tot_viewfiles; i++) { /* allocate the ImageAnim */ ImageAnim *ia = MEM_cnew<ImageAnim>("Image Anim"); BLI_addtail(&ima->anims, ia); @@ -4032,7 +3881,7 @@ static ImBuf *image_load_movie_file(Image *ima, ImageUser *iuser, int frame) const int totviews = BLI_listbase_count(&ima->views); Array<ImBuf *> ibuf_arr(totviews); - for (int i = 0; i < totfiles; i++) { + for (int i = 0; i < tot_viewfiles; i++) { ibuf_arr[i] = load_movie_single(ima, iuser, frame, i); } @@ -4063,23 +3912,21 @@ static ImBuf *load_image_single(Image *ima, int cfra, const int view_id, const bool has_packed, + const bool is_sequence, bool *r_cache_ibuf) { char filepath[FILE_MAX]; struct ImBuf *ibuf = nullptr; - int flag; + int flag = IB_rect | IB_multilayer; *r_cache_ibuf = true; /* is there a PackedFile with this image ? */ - if (has_packed) { - ImagePackedFile *imapf; - - flag = IB_rect | IB_multilayer; - flag |= imbuf_alpha_flags_for_image(ima); - - imapf = static_cast<ImagePackedFile *>(BLI_findlink(&ima->packedfiles, view_id)); + if (has_packed && !is_sequence) { + ImagePackedFile *imapf = static_cast<ImagePackedFile *>( + BLI_findlink(&ima->packedfiles, view_id)); if (imapf->packedfile) { + flag |= imbuf_alpha_flags_for_image(ima); ibuf = IMB_ibImageFromMemory((unsigned char *)imapf->packedfile->data, imapf->packedfile->size, flag, @@ -4088,14 +3935,17 @@ static ImBuf *load_image_single(Image *ima, } } else { - ImageUser iuser_t{}; - - flag = IB_rect | IB_multilayer | IB_metadata; - flag |= imbuf_alpha_flags_for_image(ima); + if (is_sequence) { + ima->lastframe = cfra; + } /* get the correct filepath */ - BKE_image_user_frame_calc(ima, iuser, cfra); + const bool is_tiled = (ima->source == IMA_SRC_TILED); + if (!(is_sequence || is_tiled)) { + BKE_image_user_frame_calc(ima, iuser, cfra); + } + ImageUser iuser_t{}; if (iuser) { iuser_t = *iuser; } @@ -4108,6 +3958,8 @@ static ImBuf *load_image_single(Image *ima, BKE_image_user_file_path(&iuser_t, ima, filepath); /* read ibuf */ + flag |= IB_metadata; + flag |= imbuf_alpha_flags_for_image(ima); ibuf = IMB_loadiffname(filepath, flag, ima->colorspace_settings.name); } @@ -4132,7 +3984,7 @@ static ImBuf *load_image_single(Image *ima, image_init_after_load(ima, iuser, ibuf); /* Make packed file for auto-pack. */ - if ((has_packed == false) && (G.fileflags & G_FILE_AUTOPACK)) { + if (!is_sequence && (has_packed == false) && (G.fileflags & G_FILE_AUTOPACK)) { ImagePackedFile *imapf = static_cast<ImagePackedFile *>( MEM_mallocN(sizeof(ImagePackedFile), "Image Pack-file")); BLI_addtail(&ima->packedfiles, imapf); @@ -4150,18 +4002,23 @@ static ImBuf *load_image_single(Image *ima, /* warning, 'iuser' can be null * NOTE: Image->views was already populated (in image_update_views_format) */ -static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra) +static ImBuf *image_load_image_file( + Image *ima, ImageUser *iuser, int entry, int cfra, bool is_sequence) { struct ImBuf *ibuf = nullptr; const bool is_multiview = BKE_image_is_multiview(ima); - const int totfiles = image_num_files(ima); + const bool is_tiled = (ima->source == IMA_SRC_TILED); + const int tot_viewfiles = image_num_viewfiles(ima); bool has_packed = BKE_image_has_packedfile(ima); - /* always ensure clean ima */ - BKE_image_free_buffers(ima); + if (!(is_sequence || is_tiled)) { + /* ensure clean ima */ + BKE_image_free_buffers(ima); + } /* this should never happen, but just playing safe */ - if (has_packed) { + if (!is_sequence && has_packed) { + const int totfiles = tot_viewfiles * BLI_listbase_count(&ima->tiles); if (totfiles != BLI_listbase_count_at_most(&ima->packedfiles, totfiles + 1)) { image_free_packedfiles(ima); has_packed = false; @@ -4170,9 +4027,10 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra) if (!is_multiview) { bool put_in_cache; - ibuf = load_image_single(ima, iuser, cfra, 0, has_packed, &put_in_cache); + ibuf = load_image_single(ima, iuser, cfra, 0, has_packed, is_sequence, &put_in_cache); if (put_in_cache) { - image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0); + const int index = (is_sequence || is_tiled) ? 0 : IMA_NO_INDEX; + image_assign_ibuf(ima, ibuf, index, entry); } } else { @@ -4182,28 +4040,29 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra) Array<ImBuf *> ibuf_arr(totviews); Array<bool> cache_ibuf_arr(totviews); - for (int i = 0; i < totfiles; i++) { - ibuf_arr[i] = load_image_single(ima, iuser, cfra, i, has_packed, &cache_ibuf_arr[i]); + for (int i = 0; i < tot_viewfiles; i++) { + ibuf_arr[i] = load_image_single( + ima, iuser, cfra, i, has_packed, is_sequence, &cache_ibuf_arr[i]); } /* multi-views/multi-layers OpenEXR files directly populate ima, and return null ibuf... */ if (BKE_image_is_stereo(ima) && ima->views_format == R_IMF_VIEWS_STEREO_3D && ibuf_arr[0] && - totfiles == 1 && totviews >= 2) { + tot_viewfiles == 1 && totviews >= 2) { IMB_ImBufFromStereo3d(ima->stereo3d_format, ibuf_arr[0], &ibuf_arr[0], &ibuf_arr[1]); } /* return the original requested ImBuf */ - int i = (iuser && iuser->multi_index < totviews) ? iuser->multi_index : 0; - ibuf = ibuf_arr[i]; + const int ibuf_index = (iuser && iuser->multi_index < totviews) ? iuser->multi_index : 0; + ibuf = ibuf_arr[ibuf_index]; - for (i = 0; i < totviews; i++) { + for (int i = 0; i < totviews; i++) { if (cache_ibuf_arr[i]) { - image_assign_ibuf(ima, ibuf_arr[i], i, 0); + image_assign_ibuf(ima, ibuf_arr[i], i, entry); } } /* "remove" the others (decrease their refcount) */ - for (i = 0; i < totviews; i++) { + for (int i = 0; i < totviews; i++) { if (ibuf_arr[i] != ibuf) { IMB_freeImBuf(ibuf_arr[i]); } @@ -4218,7 +4077,7 @@ static ImBuf *image_get_ibuf_multilayer(Image *ima, ImageUser *iuser) ImBuf *ibuf = nullptr; if (ima->rr == nullptr) { - ibuf = image_load_image_file(ima, iuser, 0); + ibuf = image_load_image_file(ima, iuser, 0, 0, false); if (ibuf) { /* actually an error */ ima->type = IMA_TYPE_IMAGE; return ibuf; @@ -4595,7 +4454,7 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock) else if (ima->source == IMA_SRC_SEQUENCE) { if (ima->type == IMA_TYPE_IMAGE) { /* Regular files, ibufs in flip-book, allows saving. */ - ibuf = image_load_sequence_file(ima, iuser, entry, entry); + ibuf = image_load_image_file(ima, iuser, entry, entry, true); } /* no else; on load the ima type can change */ if (ima->type == IMA_TYPE_MULTILAYER) { @@ -4606,7 +4465,7 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock) else if (ima->source == IMA_SRC_TILED) { if (ima->type == IMA_TYPE_IMAGE) { /* Regular files, ibufs in flip-book, allows saving */ - ibuf = image_load_sequence_file(ima, iuser, entry, 0); + ibuf = image_load_image_file(ima, iuser, entry, 0, false); } /* no else; on load the ima type can change */ if (ima->type == IMA_TYPE_MULTILAYER) { @@ -4617,7 +4476,8 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock) else if (ima->source == IMA_SRC_FILE) { if (ima->type == IMA_TYPE_IMAGE) { - ibuf = image_load_image_file(ima, iuser, entry); /* cfra only for '#', this global is OK */ + ibuf = image_load_image_file( + ima, iuser, 0, entry, false); /* cfra only for '#', this global is OK */ } /* no else; on load the ima type can change */ if (ima->type == IMA_TYPE_MULTILAYER) { @@ -5096,7 +4956,7 @@ void BKE_image_user_file_path_ex(ImageUser *iuser, Image *ima, char *filepath, b bool BKE_image_has_alpha(Image *image) { void *lock; - ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, &lock); + ImBuf *ibuf = BKE_image_acquire_ibuf(image, nullptr, &lock); const int planes = (ibuf ? ibuf->planes : 0); BKE_image_release_ibuf(image, ibuf, lock); diff --git a/source/blender/blenkernel/intern/image_format.cc b/source/blender/blenkernel/intern/image_format.cc index 44aa9e21195..3ff0b3da963 100644 --- a/source/blender/blenkernel/intern/image_format.cc +++ b/source/blender/blenkernel/intern/image_format.cc @@ -5,7 +5,7 @@ * \ingroup bke */ -#include <string.h> +#include <cstring> #include "DNA_defaults.h" #include "DNA_scene_types.h" @@ -120,6 +120,12 @@ int BKE_imtype_to_ftype(const char imtype, ImbFormatOptions *r_options) return IMB_FTYPE_JP2; } #endif +#ifdef WITH_WEBP + if (imtype == R_IMF_IMTYPE_WEBP) { + r_options->quality = 90; + return IMB_FTYPE_WEBP; + } +#endif r_options->quality = 90; return IMB_FTYPE_JPG; @@ -177,6 +183,11 @@ char BKE_ftype_to_imtype(const int ftype, const ImbFormatOptions *options) return R_IMF_IMTYPE_JP2; } #endif +#ifdef WITH_WEBP + if (ftype == IMB_FTYPE_WEBP) { + return R_IMF_IMTYPE_WEBP; + } +#endif return R_IMF_IMTYPE_JPEG90; } @@ -220,6 +231,7 @@ bool BKE_imtype_supports_quality(const char imtype) case R_IMF_IMTYPE_JPEG90: case R_IMF_IMTYPE_JP2: case R_IMF_IMTYPE_AVIJPEG: + case R_IMF_IMTYPE_WEBP: return true; } return false; @@ -259,6 +271,7 @@ char BKE_imtype_valid_channels(const char imtype, bool write_file) case R_IMF_IMTYPE_DDS: case R_IMF_IMTYPE_JP2: case R_IMF_IMTYPE_DPX: + case R_IMF_IMTYPE_WEBP: chan_flag |= IMA_CHAN_FLAG_ALPHA; break; } @@ -379,6 +392,11 @@ char BKE_imtype_from_arg(const char *imtype_arg) return R_IMF_IMTYPE_JP2; } #endif +#ifdef WITH_WEBP + if (STREQ(imtype_arg, "WEBP")) { + return R_IMF_IMTYPE_WEBP; + } +#endif return R_IMF_IMTYPE_INVALID; } @@ -494,6 +512,12 @@ static bool do_add_image_extension(char *string, } } #endif +#ifdef WITH_WEBP + else if (imtype == R_IMF_IMTYPE_WEBP) { + if (!BLI_path_extension_check(string, extension_test = ".webp")) + extension = extension_test; + } +#endif else { // R_IMF_IMTYPE_AVIRAW, R_IMF_IMTYPE_AVIJPEG, R_IMF_IMTYPE_JPEG90 etc if (!(BLI_path_extension_check_n(string, extension_test = ".jpg", ".jpeg", nullptr))) { extension = extension_test; @@ -732,6 +756,12 @@ void BKE_image_format_to_imbuf(ImBuf *ibuf, const ImageFormatData *imf) } } #endif +#ifdef WITH_WEBP + else if (imtype == R_IMF_IMTYPE_WEBP) { + ibuf->ftype = IMB_FTYPE_WEBP; + ibuf->foptions.quality = quality; + } +#endif else { /* #R_IMF_IMTYPE_JPEG90, etc. default to JPEG. */ if (quality < 10) { @@ -864,6 +894,12 @@ void BKE_image_format_from_imbuf(ImageFormatData *im_format, const ImBuf *imbuf) } } #endif +#ifdef WITH_WEBP + else if (ftype == IMB_FTYPE_WEBP) { + im_format->imtype = R_IMF_IMTYPE_WEBP; + im_format->quality = quality; + } +#endif else { im_format->imtype = R_IMF_IMTYPE_JPEG90; diff --git a/source/blender/blenkernel/intern/image_partial_update.cc b/source/blender/blenkernel/intern/image_partial_update.cc index 4606a14ab69..c77ee77a5f2 100644 --- a/source/blender/blenkernel/intern/image_partial_update.cc +++ b/source/blender/blenkernel/intern/image_partial_update.cc @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later * Copyright 2021 Blender Foundation. */ /** - * \file image_gpu_partial_update.cc + * \file * \ingroup bke * * To reduce the overhead of image processing this file contains a mechanism to detect areas of the diff --git a/source/blender/blenkernel/intern/image_save.cc b/source/blender/blenkernel/intern/image_save.cc index f530183f967..0d7d238f3b2 100644 --- a/source/blender/blenkernel/intern/image_save.cc +++ b/source/blender/blenkernel/intern/image_save.cc @@ -391,6 +391,10 @@ static bool image_save_single(ReportList *reports, } } + if (rr) { + BKE_image_release_renderresult(opts->scene, ima); + } + return ok; } @@ -693,7 +697,7 @@ bool BKE_image_render_write(ReportList *reports, RenderResult *rr, const Scene *scene, const bool stamp, - const char *filename) + const char *filepath_basis) { bool ok = true; @@ -711,8 +715,8 @@ bool BKE_image_render_write(ReportList *reports, const float dither = scene->r.dither_intensity; if (image_format.views_format == R_IMF_VIEWS_MULTIVIEW && is_exr_rr) { - ok = BKE_image_render_write_exr(reports, rr, filename, &image_format, true, nullptr, -1); - image_render_print_save_message(reports, filename, ok, errno); + ok = BKE_image_render_write_exr(reports, rr, filepath_basis, &image_format, true, nullptr, -1); + image_render_print_save_message(reports, filepath_basis, ok, errno); } /* mono, legacy code */ @@ -722,10 +726,10 @@ bool BKE_image_render_write(ReportList *reports, rv = rv->next, view_id++) { char filepath[FILE_MAX]; if (is_mono) { - STRNCPY(filepath, filename); + STRNCPY(filepath, filepath_basis); } else { - BKE_scene_multiview_view_filepath_get(&scene->r, filename, rv->name, filepath); + BKE_scene_multiview_view_filepath_get(&scene->r, filepath_basis, rv->name, filepath); } if (is_exr_rr) { @@ -768,7 +772,7 @@ bool BKE_image_render_write(ReportList *reports, BLI_assert(image_format.views_format == R_IMF_VIEWS_STEREO_3D); char filepath[FILE_MAX]; - STRNCPY(filepath, filename); + STRNCPY(filepath, filepath_basis); if (image_format.imtype == R_IMF_IMTYPE_MULTILAYER) { printf("Stereo 3D not supported for MultiLayer image: %s\n", filepath); diff --git a/source/blender/blenkernel/intern/image_test.cc b/source/blender/blenkernel/intern/image_test.cc new file mode 100644 index 00000000000..9c15fc62d21 --- /dev/null +++ b/source/blender/blenkernel/intern/image_test.cc @@ -0,0 +1,186 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2022 Blender Foundation. */ + +#include "BLI_path_util.h" +#include "BLI_string.h" + +#include "BKE_image.h" + +#include "MEM_guardedalloc.h" + +#include "testing/testing.h" + +namespace blender::bke::tests { + +TEST(udim, image_ensure_tile_token) +{ + auto verify = [](const char *original, const char *expected) { + char result[FILE_MAX]; + + BLI_strncpy(result, original, sizeof(result)); + BKE_image_ensure_tile_token(result); + EXPECT_STREQ(result, expected); + }; + + /* Already present tokens. */ + verify("test.<UDIM>.png", "test.<UDIM>.png"); + verify("test.<UVTILE>.png", "test.<UVTILE>.png"); + + /* UDIM pattern detection. */ + verify("test.1002.png", "test.<UDIM>.png"); + verify("test-1002-ao.png", "test-<UDIM>-ao.png"); + verify("test_1002_ao.png", "test_<UDIM>_ao.png"); + verify("test.1002.ver0023.png", "test.<UDIM>.ver0023.png"); + verify("test.ver0023.1002.png", "test.ver0023.<UDIM>.png"); + verify("1002test.png", "<UDIM>test.png"); + verify("test1002.png", "test<UDIM>.png"); + + /* UVTILE pattern detection. */ + verify("uv-test.u2_v10.png", "uv-test.<UVTILE>.png"); + verify("uv-test-u2_v10-ao.png", "uv-test-<UVTILE>-ao.png"); + verify("uv-test_u2_v10_ao.png", "uv-test_<UVTILE>_ao.png"); + verify("uv-test.u10_v100.png", "uv-test.<UVTILE>.png"); + verify("u_v-test.u2_v10.png", "u_v-test.<UVTILE>.png"); + verify("u2_v10uv-test.png", "<UVTILE>uv-test.png"); + verify("u2_v10u_v-test.png", "<UVTILE>u_v-test.png"); + + /* Incorrect patterns. */ + for (const char *incorrect : {"test.123.png", + "test.12345.png", + "test.uv.png", + "test.u1v.png", + "test.uv1.png", + "test.u_v.png", + "test.u1_v.png", + "test.u_v2.png", + "test.u2v3.png", + "test.u123_v1.png", + "test.u1_v12345.png"}) { + /* These should not result in modifications happening. */ + verify(incorrect, incorrect); + } +} + +TEST(udim, image_get_tile_strformat) +{ + eUDIM_TILE_FORMAT tile_format; + char *udim_pattern; + + /* Parameter validation. */ + udim_pattern = BKE_image_get_tile_strformat(nullptr, &tile_format); + EXPECT_EQ(udim_pattern, nullptr); + + udim_pattern = BKE_image_get_tile_strformat("", nullptr); + EXPECT_EQ(udim_pattern, nullptr); + + /* Typical usage. */ + udim_pattern = BKE_image_get_tile_strformat("", &tile_format); + EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_NONE); + EXPECT_EQ(udim_pattern, nullptr); + + udim_pattern = BKE_image_get_tile_strformat("test.<UNKNOWN>.png", &tile_format); + EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_NONE); + EXPECT_EQ(udim_pattern, nullptr); + + udim_pattern = BKE_image_get_tile_strformat("test.<UDIM>.png", &tile_format); + EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_UDIM); + EXPECT_STREQ(udim_pattern, "test.%d.png"); + MEM_freeN(udim_pattern); + + udim_pattern = BKE_image_get_tile_strformat("test.<UVTILE>.png", &tile_format); + EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_UVTILE); + EXPECT_STREQ(udim_pattern, "test.u%d_v%d.png"); + MEM_freeN(udim_pattern); +} + +TEST(udim, image_get_tile_number_from_filepath) +{ + eUDIM_TILE_FORMAT tile_format; + char *udim_pattern; + int tile_number; + + udim_pattern = BKE_image_get_tile_strformat("test.<UDIM>.png", &tile_format); + EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_UDIM); + EXPECT_NE(udim_pattern, nullptr); + + /* Parameter validation. */ + EXPECT_FALSE( + BKE_image_get_tile_number_from_filepath(nullptr, udim_pattern, tile_format, &tile_number)); + EXPECT_FALSE(BKE_image_get_tile_number_from_filepath( + "test.1004.png", nullptr, tile_format, &tile_number)); + EXPECT_FALSE(BKE_image_get_tile_number_from_filepath( + "test.1004.png", udim_pattern, UDIM_TILE_FORMAT_NONE, &tile_number)); + EXPECT_FALSE(BKE_image_get_tile_number_from_filepath( + "test.1004.png", udim_pattern, tile_format, nullptr)); + + /* UDIM tile format tests. */ + EXPECT_TRUE(BKE_image_get_tile_number_from_filepath( + "test.1004.png", udim_pattern, tile_format, &tile_number)); + EXPECT_EQ(tile_number, 1004); + + EXPECT_FALSE(BKE_image_get_tile_number_from_filepath( + "has_no_number.png", udim_pattern, tile_format, &tile_number)); + EXPECT_FALSE(BKE_image_get_tile_number_from_filepath( + "test.X.png", udim_pattern, tile_format, &tile_number)); + EXPECT_FALSE(BKE_image_get_tile_number_from_filepath( + "wrong.1004.png", udim_pattern, tile_format, &tile_number)); + + MEM_freeN(udim_pattern); + + /* UVTILE tile format tests. */ + udim_pattern = BKE_image_get_tile_strformat("test.<UVTILE>.png", &tile_format); + EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_UVTILE); + EXPECT_NE(udim_pattern, nullptr); + + EXPECT_TRUE(BKE_image_get_tile_number_from_filepath( + "test.u2_v2.png", udim_pattern, tile_format, &tile_number)); + EXPECT_EQ(tile_number, 1012); + + EXPECT_FALSE(BKE_image_get_tile_number_from_filepath( + "has_no_number.png", udim_pattern, tile_format, &tile_number)); + EXPECT_FALSE(BKE_image_get_tile_number_from_filepath( + "test.u1_vX.png", udim_pattern, tile_format, &tile_number)); + EXPECT_FALSE(BKE_image_get_tile_number_from_filepath( + "test.uX_v1.png", udim_pattern, tile_format, &tile_number)); + EXPECT_FALSE(BKE_image_get_tile_number_from_filepath( + "wrong.u2_v2.png", udim_pattern, tile_format, &tile_number)); + + MEM_freeN(udim_pattern); +} + +TEST(udim, image_set_filepath_from_tile_number) +{ + eUDIM_TILE_FORMAT tile_format; + char *udim_pattern; + + udim_pattern = BKE_image_get_tile_strformat("test.<UDIM>.png", &tile_format); + EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_UDIM); + EXPECT_NE(udim_pattern, nullptr); + + char filepath[FILE_MAX]; + + /* Parameter validation. */ + BLI_strncpy(filepath, "xxxx", FILE_MAX); + + BKE_image_set_filepath_from_tile_number(nullptr, udim_pattern, tile_format, 1028); + BKE_image_set_filepath_from_tile_number(filepath, nullptr, tile_format, 1028); + EXPECT_STREQ(filepath, "xxxx"); + BKE_image_set_filepath_from_tile_number(filepath, udim_pattern, UDIM_TILE_FORMAT_NONE, 1028); + EXPECT_STREQ(filepath, "xxxx"); + + /* UDIM tile format tests. */ + BKE_image_set_filepath_from_tile_number(filepath, udim_pattern, tile_format, 1028); + EXPECT_STREQ(filepath, "test.1028.png"); + MEM_freeN(udim_pattern); + + /* UVTILE tile format tests. */ + udim_pattern = BKE_image_get_tile_strformat("test.<UVTILE>.png", &tile_format); + EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_UVTILE); + EXPECT_NE(udim_pattern, nullptr); + + BKE_image_set_filepath_from_tile_number(filepath, udim_pattern, tile_format, 1028); + EXPECT_STREQ(filepath, "test.u8_v3.png"); + MEM_freeN(udim_pattern); +} + +} // namespace blender::bke::tests diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 782d5442c99..5afc3c0be3b 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -199,7 +199,7 @@ static void mesh_foreach_path(ID *id, BPathForeachPathData *bpath_data) { Mesh *me = (Mesh *)id; if (me->ldata.external) { - BKE_bpath_foreach_path_fixed_process(bpath_data, me->ldata.external->filename); + BKE_bpath_foreach_path_fixed_process(bpath_data, me->ldata.external->filepath); } } diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index 40c6fbcf67e..dc9ec002d1a 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -910,18 +910,20 @@ static void curve_to_mesh_eval_ensure(Object &object) * * So we create temporary copy of the object which will use same data as the original bevel, but * will have no modifiers. */ - Object bevel_object = {{nullptr}}; + Object bevel_object; + blender::dna::zero_memory(bevel_object); if (curve.bevobj != nullptr) { - memcpy(&bevel_object, curve.bevobj, sizeof(bevel_object)); + blender::dna::copy_memory(bevel_object, *curve.bevobj); BLI_listbase_clear(&bevel_object.modifiers); BKE_object_runtime_reset(&bevel_object); curve.bevobj = &bevel_object; } /* Same thing for taper. */ - Object taper_object = {{nullptr}}; + Object taper_object; + blender::dna::zero_memory(taper_object); if (curve.taperobj != nullptr) { - memcpy(&taper_object, curve.taperobj, sizeof(taper_object)); + blender::dna::copy_memory(taper_object, *curve.taperobj); BLI_listbase_clear(&taper_object.modifiers); BKE_object_runtime_reset(&taper_object); curve.taperobj = &taper_object; @@ -1066,7 +1068,7 @@ static Mesh *mesh_new_from_mesh_object_with_layers(Depsgraph *depsgraph, } Object object_for_eval; - memcpy(&object_for_eval, object, sizeof(object_for_eval)); + blender::dna::copy_memory(object_for_eval, *object); if (object_for_eval.runtime.data_orig != nullptr) { object_for_eval.data = object_for_eval.runtime.data_orig; } diff --git a/source/blender/blenkernel/intern/mesh_evaluate.cc b/source/blender/blenkernel/intern/mesh_evaluate.cc index da0bd1f021d..6c5a5de31fc 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.cc +++ b/source/blender/blenkernel/intern/mesh_evaluate.cc @@ -695,7 +695,7 @@ static void bm_corners_to_loops_ex(ID *id, if (CustomData_external_test(fdata, CD_MDISPS)) { if (id && fdata->external) { - CustomData_external_add(ldata, id, CD_MDISPS, totloop, fdata->external->filename); + CustomData_external_add(ldata, id, CD_MDISPS, totloop, fdata->external->filepath); } } diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c index e9c26c80141..9c4098e2db6 100644 --- a/source/blender/blenkernel/intern/mesh_mapping.c +++ b/source/blender/blenkernel/intern/mesh_mapping.c @@ -561,7 +561,7 @@ void BKE_mesh_origindex_map_create_looptri(MeshElemMap **r_map, typedef bool (*MeshRemap_CheckIslandBoundary)(const struct MPoly *mpoly, const struct MLoop *mloop, const struct MEdge *medge, - const int nbr_edge_users, + const int edge_user_count, const struct MPoly *mpoly_array, const struct MeshElemMap *edge_poly_map, void *user_data); @@ -764,14 +764,14 @@ static void poly_edge_loop_islands_calc(const MEdge *medge, static bool poly_is_island_boundary_smooth_cb(const MPoly *mp, const MLoop *UNUSED(ml), const MEdge *me, - const int nbr_edge_users, + const int edge_user_count, const MPoly *mpoly_array, const MeshElemMap *edge_poly_map, void *UNUSED(user_data)) { /* Edge is sharp if one of its polys is flat, or edge itself is sharp, * or edge is not used by exactly two polygons. */ - if ((mp->flag & ME_SMOOTH) && !(me->flag & ME_SHARP) && (nbr_edge_users == 2)) { + if ((mp->flag & ME_SMOOTH) && !(me->flag & ME_SHARP) && (edge_user_count == 2)) { /* In that case, edge appears to be smooth, but we need to check its other poly too. */ const MPoly *mp_other = (mp == &mpoly_array[edge_poly_map->indices[0]]) ? &mpoly_array[edge_poly_map->indices[1]] : @@ -935,7 +935,7 @@ typedef struct MeshCheckIslandBoundaryUv { static bool mesh_check_island_boundary_uv(const MPoly *UNUSED(mp), const MLoop *ml, const MEdge *me, - const int UNUSED(nbr_edge_users), + const int UNUSED(edge_user_count), const MPoly *UNUSED(mpoly_array), const MeshElemMap *UNUSED(edge_poly_map), void *user_data) diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc index 7633a3155ba..ba1004e8371 100644 --- a/source/blender/blenkernel/intern/mesh_normals.cc +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -532,7 +532,7 @@ void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr, lnors_spacearr->loops_pool = (LinkNode *)BLI_memarena_alloc( mem, sizeof(LinkNode) * (size_t)numLoops); - lnors_spacearr->num_spaces = 0; + lnors_spacearr->spaces_num = 0; } BLI_assert(ELEM(data_type, MLNOR_SPACEARR_BMLOOP_PTR, MLNOR_SPACEARR_LOOP_INDEX)); lnors_spacearr->data_type = data_type; @@ -550,7 +550,7 @@ void BKE_lnor_spacearr_tls_join(MLoopNorSpaceArray *lnors_spacearr, { BLI_assert(lnors_spacearr->data_type == lnors_spacearr_tls->data_type); BLI_assert(lnors_spacearr->mem != lnors_spacearr_tls->mem); - lnors_spacearr->num_spaces += lnors_spacearr_tls->num_spaces; + lnors_spacearr->spaces_num += lnors_spacearr_tls->spaces_num; BLI_memarena_merge(lnors_spacearr->mem, lnors_spacearr_tls->mem); BLI_memarena_free(lnors_spacearr_tls->mem); lnors_spacearr_tls->mem = nullptr; @@ -559,7 +559,7 @@ void BKE_lnor_spacearr_tls_join(MLoopNorSpaceArray *lnors_spacearr, void BKE_lnor_spacearr_clear(MLoopNorSpaceArray *lnors_spacearr) { - lnors_spacearr->num_spaces = 0; + lnors_spacearr->spaces_num = 0; lnors_spacearr->lspacearr = nullptr; lnors_spacearr->loops_pool = nullptr; if (lnors_spacearr->mem != nullptr) { @@ -569,7 +569,7 @@ void BKE_lnor_spacearr_clear(MLoopNorSpaceArray *lnors_spacearr) void BKE_lnor_spacearr_free(MLoopNorSpaceArray *lnors_spacearr) { - lnors_spacearr->num_spaces = 0; + lnors_spacearr->spaces_num = 0; lnors_spacearr->lspacearr = nullptr; lnors_spacearr->loops_pool = nullptr; BLI_memarena_free(lnors_spacearr->mem); @@ -578,7 +578,7 @@ void BKE_lnor_spacearr_free(MLoopNorSpaceArray *lnors_spacearr) MLoopNorSpace *BKE_lnor_space_create(MLoopNorSpaceArray *lnors_spacearr) { - lnors_spacearr->num_spaces++; + lnors_spacearr->spaces_num++; return (MLoopNorSpace *)BLI_memarena_calloc(lnors_spacearr->mem, sizeof(MLoopNorSpace)); } @@ -613,19 +613,19 @@ void BKE_lnor_space_define(MLoopNorSpace *lnor_space, /* Compute ref alpha, average angle of all available edge vectors to lnor. */ if (edge_vectors) { float alpha = 0.0f; - int nbr = 0; + int count = 0; while (!BLI_stack_is_empty(edge_vectors)) { const float *vec = (const float *)BLI_stack_peek(edge_vectors); alpha += saacosf(dot_v3v3(vec, lnor)); BLI_stack_discard(edge_vectors); - nbr++; + count++; } - /* NOTE: In theory, this could be `nbr > 2`, + /* NOTE: In theory, this could be `count > 2`, * but there is one case where we only have two edges for two loops: * a smooth vertex with only two edges and two faces (our Monkey's nose has that, e.g.). */ - BLI_assert(nbr >= 2); /* This piece of code shall only be called for more than one loop. */ - lnor_space->ref_alpha = alpha / (float)nbr; + BLI_assert(count >= 2); /* This piece of code shall only be called for more than one loop. */ + lnor_space->ref_alpha = alpha / (float)count; } else { lnor_space->ref_alpha = (saacosf(dot_v3v3(vec_ref, lnor)) + @@ -1134,7 +1134,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli /* We validate clnors data on the fly - cheapest way to do! */ int clnors_avg[2] = {0, 0}; short(*clnor_ref)[2] = nullptr; - int clnors_nbr = 0; + int clnors_count = 0; bool clnors_invalid = false; /* Temp loop normal stack. */ @@ -1194,7 +1194,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli if (clnors_data) { /* Accumulate all clnors, if they are not all equal we have to fix that! */ short(*clnor)[2] = &clnors_data[mlfan_vert_index]; - if (clnors_nbr) { + if (clnors_count) { clnors_invalid |= ((*clnor_ref)[0] != (*clnor)[0] || (*clnor_ref)[1] != (*clnor)[1]); } else { @@ -1202,7 +1202,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli } clnors_avg[0] += (*clnor)[0]; clnors_avg[1] += (*clnor)[1]; - clnors_nbr++; + clnors_count++; /* We store here a pointer to all custom lnors processed. */ BLI_SMALLSTACK_PUSH(clnors, (short *)*clnor); } @@ -1262,8 +1262,8 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli if (clnors_invalid) { short *clnor; - clnors_avg[0] /= clnors_nbr; - clnors_avg[1] /= clnors_nbr; + clnors_avg[0] /= clnors_count; + clnors_avg[1] /= clnors_count; /* Fix/update all clnors of this fan with computed average value. */ if (G.debug & G_DEBUG) { printf("Invalid clnors in this fan!\n"); @@ -1952,7 +1952,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, BLI_BITMAP_DISABLE(done_loops, i); } else { - int nbr_nors = 0; + int avg_nor_count = 0; float avg_nor[3]; short clnor_data_tmp[2], *clnor_data; @@ -1962,7 +1962,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, const int nidx = use_vertices ? (int)mloops[lidx].v : lidx; float *nor = r_custom_loopnors[nidx]; - nbr_nors++; + avg_nor_count++; add_v3_v3(avg_nor, nor); BLI_SMALLSTACK_PUSH(clnors_data, (short *)r_clnors_data[lidx]); @@ -1970,7 +1970,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, BLI_BITMAP_DISABLE(done_loops, lidx); } - mul_v3_fl(avg_nor, 1.0f / (float)nbr_nors); + mul_v3_fl(avg_nor, 1.0f / (float)avg_nor_count); BKE_lnor_space_custom_normal_to_data(lnors_spacearr.lspacearr[i], avg_nor, clnor_data_tmp); while ((clnor_data = (short *)BLI_SMALLSTACK_POP(clnors_data))) { @@ -2088,8 +2088,8 @@ void BKE_mesh_normals_loop_to_vertex(const int numVerts, const float (*clnors)[3], float (*r_vert_clnors)[3]) { - int *vert_loops_nbr = (int *)MEM_calloc_arrayN( - (size_t)numVerts, sizeof(*vert_loops_nbr), __func__); + int *vert_loops_count = (int *)MEM_calloc_arrayN( + (size_t)numVerts, sizeof(*vert_loops_count), __func__); copy_vn_fl((float *)r_vert_clnors, 3 * numVerts, 0.0f); @@ -2099,14 +2099,14 @@ void BKE_mesh_normals_loop_to_vertex(const int numVerts, const uint v = ml->v; add_v3_v3(r_vert_clnors[v], clnors[i]); - vert_loops_nbr[v]++; + vert_loops_count[v]++; } for (i = 0; i < numVerts; i++) { - mul_v3_fl(r_vert_clnors[i], 1.0f / (float)vert_loops_nbr[i]); + mul_v3_fl(r_vert_clnors[i], 1.0f / (float)vert_loops_count[i]); } - MEM_freeN(vert_loops_nbr); + MEM_freeN(vert_loops_count); } #undef LNOR_SPACE_TRIGO_THRESHOLD diff --git a/source/blender/blenkernel/intern/mesh_validate.cc b/source/blender/blenkernel/intern/mesh_validate.cc index 4374659bff8..6af765d7de5 100644 --- a/source/blender/blenkernel/intern/mesh_validate.cc +++ b/source/blender/blenkernel/intern/mesh_validate.cc @@ -577,7 +577,8 @@ bool BKE_mesh_validate_arrays(Mesh *mesh, else if (mp->loopstart + mp->totloop > totloop) { /* Invalid loop data. */ PRINT_ERR( - "\tPoly %u uses loops out of range (loopstart: %d, loopend: %d, max nbr of loops: %u)", + "\tPoly %u uses loops out of range " + "(loopstart: %d, loopend: %d, max number of loops: %u)", sp->index, mp->loopstart, mp->loopstart + mp->totloop - 1, diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc index 1e3b5d77fa7..4714a79de58 100644 --- a/source/blender/blenkernel/intern/object.cc +++ b/source/blender/blenkernel/intern/object.cc @@ -766,7 +766,7 @@ static void object_blend_read_data(BlendDataReader *reader, ID *id) hmd->indexar = hook->indexar; hmd->object = hook->parent; memcpy(hmd->parentinv, hook->parentinv, sizeof(hmd->parentinv)); - hmd->totindex = hook->totindex; + hmd->indexar_num = hook->totindex; BLI_addhead(&ob->modifiers, hmd); BLI_remlink(&ob->hooks, hook); @@ -1236,7 +1236,7 @@ IDTypeInfo IDType_ID_OB = { void BKE_object_workob_clear(Object *workob) { - memset(workob, 0, sizeof(Object)); + blender::dna::zero_memory(*workob); workob->scale[0] = workob->scale[1] = workob->scale[2] = 1.0f; workob->dscale[0] = workob->dscale[1] = workob->dscale[2] = 1.0f; @@ -3946,7 +3946,7 @@ bool BKE_object_minmax_dupli(Depsgraph *depsgraph, /* pass */ } else { - Object temp_ob = *dob->ob; + Object temp_ob = blender::dna::shallow_copy(*dob->ob); /* Do not modify the original boundbox. */ temp_ob.runtime.bb = nullptr; BKE_object_replace_data_on_shallow_copy(&temp_ob, dob->ob_data); diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c index 4c5fefefd8e..e7ed100ed03 100644 --- a/source/blender/blenkernel/intern/packedFile.c +++ b/source/blender/blenkernel/intern/packedFile.c @@ -174,16 +174,16 @@ PackedFile *BKE_packedfile_new_from_memory(void *mem, int memlen) return pf; } -PackedFile *BKE_packedfile_new(ReportList *reports, const char *filename, const char *basepath) +PackedFile *BKE_packedfile_new(ReportList *reports, const char *filepath, const char *basepath) { PackedFile *pf = NULL; int file, filelen; char name[FILE_MAX]; void *data; - /* render result has no filename and can be ignored + /* render result has no filepath and can be ignored * any other files with no name can be ignored too */ - if (filename[0] == '\0') { + if (filepath[0] == '\0') { return pf; } @@ -191,7 +191,7 @@ PackedFile *BKE_packedfile_new(ReportList *reports, const char *filename, const /* convert relative filenames to absolute filenames */ - BLI_strncpy(name, filename, sizeof(name)); + BLI_strncpy(name, filepath, sizeof(name)); BLI_path_abs(name, basepath); /* open the file @@ -285,7 +285,7 @@ void BKE_packedfile_pack_all(Main *bmain, ReportList *reports, bool verbose) int BKE_packedfile_write_to_file(ReportList *reports, const char *ref_file_name, - const char *filename, + const char *filepath, PackedFile *pf, const bool guimode) { @@ -299,7 +299,7 @@ int BKE_packedfile_write_to_file(ReportList *reports, if (guimode) { } // XXX waitcursor(1); - BLI_strncpy(name, filename, sizeof(name)); + BLI_strncpy(name, filepath, sizeof(name)); BLI_path_abs(name, ref_file_name); if (BLI_exists(name)) { @@ -358,7 +358,7 @@ int BKE_packedfile_write_to_file(ReportList *reports, } enum ePF_FileCompare BKE_packedfile_compare_to_file(const char *ref_file_name, - const char *filename, + const char *filepath, PackedFile *pf) { BLI_stat_t st; @@ -366,7 +366,7 @@ enum ePF_FileCompare BKE_packedfile_compare_to_file(const char *ref_file_name, char buf[4096]; char name[FILE_MAX]; - BLI_strncpy(name, filename, sizeof(name)); + BLI_strncpy(name, filepath, sizeof(name)); BLI_path_abs(name, ref_file_name); if (BLI_stat(name, &st) == -1) { diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index c47b22dcd34..9ea1336a95a 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -2661,8 +2661,8 @@ void psys_find_parents(ParticleSimulationData *sim, const bool use_render_params int from = PART_FROM_FACE; totparent = (int)(totchild * part->parents * 0.3f); - if (use_render_params && part->child_nbr && part->ren_child_nbr) { - totparent *= (float)part->child_nbr / (float)part->ren_child_nbr; + if (use_render_params && part->child_percent && part->child_render_percent) { + totparent *= (float)part->child_percent / (float)part->child_render_percent; } /* hard limit, workaround for it being ignored above */ @@ -2736,8 +2736,8 @@ static bool psys_thread_context_init_path(ParticleThreadContext *ctx, if (totchild && part->childtype == PART_CHILD_FACES) { totparent = (int)(totchild * part->parents * 0.3f); - if (use_render_params && part->child_nbr && part->ren_child_nbr) { - totparent *= (float)part->child_nbr / (float)part->ren_child_nbr; + if (use_render_params && part->child_percent && part->child_render_percent) { + totparent *= (float)part->child_percent / (float)part->child_render_percent; } /* part->parents could still be 0 so we can't test with totparent */ diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c index 83fb52ce1ef..d2c3776d4ea 100644 --- a/source/blender/blenkernel/intern/particle_distribute.c +++ b/source/blender/blenkernel/intern/particle_distribute.c @@ -64,14 +64,14 @@ static void distribute_simple_children(Scene *scene, { ChildParticle *cpa = NULL; int i, p; - int child_nbr = psys_get_child_number(scene, psys, use_render_params); - int totpart = psys_get_tot_child(scene, psys, use_render_params); + const int child_num = psys_get_child_number(scene, psys, use_render_params); + const int totpart = psys_get_tot_child(scene, psys, use_render_params); RNG *rng = BLI_rng_new_srandom(31415926 + psys->seed + psys->child_seed); alloc_child_particles(psys, totpart); cpa = psys->child; - for (i = 0; i < child_nbr; i++) { + for (i = 0; i < child_num; i++) { for (p = 0; p < psys->totpart; p++, cpa++) { float length = 2.0; cpa->parent = p; diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 3a1aefec2d3..7fdc60a265b 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -98,9 +98,9 @@ float psys_get_current_display_percentage(ParticleSystem *psys, const bool use_r ParticleSettings *part = psys->part; if ((use_render_params && - !particles_are_dynamic(psys)) || /* non-dynamic particles can be rendered fully */ - (part->child_nbr && part->childtype) || /* display percentage applies to children */ - (psys->pointcache->flag & PTCACHE_BAKING)) /* baking is always done with full amount */ + !particles_are_dynamic(psys)) || /* non-dynamic particles can be rendered fully */ + (part->child_percent && part->childtype) || /* display percentage applies to children */ + (psys->pointcache->flag & PTCACHE_BAKING)) /* baking is always done with full amount */ { return 1.0f; } @@ -280,20 +280,20 @@ static void realloc_particles(ParticleSimulationData *sim, int new_totpart) int psys_get_child_number(Scene *scene, ParticleSystem *psys, const bool use_render_params) { - int nbr; + int child_num; if (!psys->part->childtype) { return 0; } if (use_render_params) { - nbr = psys->part->ren_child_nbr; + child_num = psys->part->child_render_percent; } else { - nbr = psys->part->child_nbr; + child_num = psys->part->child_percent; } - return get_render_child_particle_number(&scene->r, nbr, use_render_params); + return get_render_child_particle_number(&scene->r, child_num, use_render_params); } int psys_get_tot_child(Scene *scene, ParticleSystem *psys, const bool use_render_params) diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.cc index 6797538d190..cebe4482eb7 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.cc @@ -8,9 +8,9 @@ /* Allow using deprecated functionality for .blend file I/O. */ #define DNA_DEPRECATED_ALLOW -#include <stddef.h> -#include <stdio.h> -#include <string.h> +#include <cstddef> +#include <cstdio> +#include <cstring> #include "MEM_guardedalloc.h" @@ -183,11 +183,11 @@ static void scene_init_data(ID *id) /* multiview - stereo */ BKE_scene_add_render_view(scene, STEREO_LEFT_NAME); - srv = scene->r.views.first; + srv = static_cast<SceneRenderView *>(scene->r.views.first); BLI_strncpy(srv->suffix, STEREO_LEFT_SUFFIX, sizeof(srv->suffix)); BKE_scene_add_render_view(scene, STEREO_RIGHT_NAME); - srv = scene->r.views.last; + srv = static_cast<SceneRenderView *>(scene->r.views.last); BLI_strncpy(srv->suffix, STEREO_RIGHT_SUFFIX, sizeof(srv->suffix)); BKE_sound_reset_scene_runtime(scene); @@ -218,14 +218,14 @@ static void scene_init_data(ID *id) /* Master Collection */ scene->master_collection = BKE_collection_master_add(); - BKE_view_layer_add(scene, "ViewLayer", NULL, VIEWLAYER_ADD_NEW); + BKE_view_layer_add(scene, "ViewLayer", nullptr, VIEWLAYER_ADD_NEW); } static void scene_copy_markers(Scene *scene_dst, const Scene *scene_src, const int flag) { BLI_duplicatelist(&scene_dst->markers, &scene_src->markers); LISTBASE_FOREACH (TimeMarker *, marker, &scene_dst->markers) { - if (marker->prop != NULL) { + if (marker->prop != nullptr) { marker->prop = IDP_CopyProperty_ex(marker->prop, flag); } } @@ -240,9 +240,9 @@ static void scene_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int /* We always need allocation of our private ID data. */ const int flag_private_id_data = flag & ~LIB_ID_CREATE_NO_ALLOCATE; - scene_dst->ed = NULL; - scene_dst->depsgraph_hash = NULL; - scene_dst->fps_info = NULL; + scene_dst->ed = nullptr; + scene_dst->depsgraph_hash = nullptr; + scene_dst->fps_info = nullptr; /* Master Collection */ if (scene_src->master_collection) { @@ -254,8 +254,8 @@ static void scene_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int /* View Layers */ BLI_duplicatelist(&scene_dst->view_layers, &scene_src->view_layers); - for (ViewLayer *view_layer_src = scene_src->view_layers.first, - *view_layer_dst = scene_dst->view_layers.first; + for (ViewLayer *view_layer_src = static_cast<ViewLayer *>(scene_src->view_layers.first), + *view_layer_dst = static_cast<ViewLayer *>(scene_dst->view_layers.first); view_layer_src; view_layer_src = view_layer_src->next, view_layer_dst = view_layer_dst->next) { BKE_view_layer_copy_data(scene_dst, scene_src, view_layer_dst, view_layer_src, flag_subdata); @@ -299,7 +299,8 @@ static void scene_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int /* make a private copy of the avicodecdata */ if (scene_src->r.avicodecdata) { - scene_dst->r.avicodecdata = MEM_dupallocN(scene_src->r.avicodecdata); + scene_dst->r.avicodecdata = static_cast<AviCodecData *>( + MEM_dupallocN(scene_src->r.avicodecdata)); scene_dst->r.avicodecdata->lpFormat = MEM_dupallocN(scene_dst->r.avicodecdata->lpFormat); scene_dst->r.avicodecdata->lpParms = MEM_dupallocN(scene_dst->r.avicodecdata->lpParms); } @@ -312,7 +313,7 @@ static void scene_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int /* Copy sequencer, this is local data! */ if (scene_src->ed) { - scene_dst->ed = MEM_callocN(sizeof(*scene_dst->ed), __func__); + scene_dst->ed = MEM_cnew<Editing>(__func__); scene_dst->ed->seqbasep = &scene_dst->ed->seqbase; SEQ_sequence_base_dupli_recursive(scene_src, scene_dst, @@ -326,7 +327,7 @@ static void scene_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int BKE_previewimg_id_copy(&scene_dst->id, &scene_src->id); } else { - scene_dst->preview = NULL; + scene_dst->preview = nullptr; } BKE_scene_copy_data_eevee(scene_dst, scene_src); @@ -335,7 +336,7 @@ static void scene_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int static void scene_free_markers(Scene *scene, bool do_id_user) { LISTBASE_FOREACH_MUTABLE (TimeMarker *, marker, &scene->markers) { - if (marker->prop != NULL) { + if (marker->prop != nullptr) { IDP_FreePropertyContent_ex(marker->prop, do_id_user); MEM_freeN(marker->prop); } @@ -357,22 +358,22 @@ static void scene_free_data(ID *id) if (scene->nodetree) { ntreeFreeEmbeddedTree(scene->nodetree); MEM_freeN(scene->nodetree); - scene->nodetree = NULL; + scene->nodetree = nullptr; } if (scene->rigidbody_world) { /* Prevent rigidbody freeing code to follow other IDs pointers, this should never be allowed * nor necessary from here, and with new undo code, those pointers may be fully invalid or * worse, pointing to data actually belonging to new BMain! */ - scene->rigidbody_world->constraints = NULL; - scene->rigidbody_world->group = NULL; + scene->rigidbody_world->constraints = nullptr; + scene->rigidbody_world->group = nullptr; BKE_rigidbody_free_world(scene); } if (scene->r.avicodecdata) { free_avicodecdata(scene->r.avicodecdata); MEM_freeN(scene->r.avicodecdata); - scene->r.avicodecdata = NULL; + scene->r.avicodecdata = nullptr; } scene_free_markers(scene, do_id_user); @@ -380,7 +381,7 @@ static void scene_free_data(ID *id) BLI_freelistN(&scene->r.views); BKE_toolsettings_free(scene->toolsettings); - scene->toolsettings = NULL; + scene->toolsettings = nullptr; BKE_scene_free_depsgraph_hash(scene); @@ -395,10 +396,7 @@ static void scene_free_data(ID *id) BKE_previewimg_free(&scene->preview); BKE_curvemapping_free_data(&scene->r.mblur_shutter_curve); - for (ViewLayer *view_layer = scene->view_layers.first, *view_layer_next; view_layer; - view_layer = view_layer_next) { - view_layer_next = view_layer->next; - + LISTBASE_FOREACH_MUTABLE (ViewLayer *, view_layer, &scene->view_layers) { BLI_remlink(&scene->view_layers, view_layer); BKE_view_layer_free_ex(view_layer, do_id_user); } @@ -412,21 +410,21 @@ static void scene_free_data(ID *id) BKE_collection_free_data(scene->master_collection); BKE_libblock_free_data_py(&scene->master_collection->id); MEM_freeN(scene->master_collection); - scene->master_collection = NULL; + scene->master_collection = nullptr; } if (scene->eevee.light_cache_data) { EEVEE_lightcache_free(scene->eevee.light_cache_data); - scene->eevee.light_cache_data = NULL; + scene->eevee.light_cache_data = nullptr; } if (scene->display.shading.prop) { IDP_FreeProperty(scene->display.shading.prop); - scene->display.shading.prop = NULL; + scene->display.shading.prop = nullptr; } /* These are freed on doversion. */ - BLI_assert(scene->layer_properties == NULL); + BLI_assert(scene->layer_properties == nullptr); } static void scene_foreach_rigidbodyworldSceneLooper(struct RigidBodyWorld *UNUSED(rbw), @@ -443,14 +441,14 @@ static void scene_foreach_rigidbodyworldSceneLooper(struct RigidBodyWorld *UNUSE * This code is shared by both the regular `foreach_id` looper, and the code trying to restore or * preserve ID pointers like brushes across undo-steps. */ -typedef enum eSceneForeachUndoPreserveProcess { +enum eSceneForeachUndoPreserveProcess { /* Undo when preserving tool-settings from old scene, we also want to try to preserve that ID * pointer from its old scene's value. */ SCENE_FOREACH_UNDO_RESTORE, /* Undo when preserving tool-settings from old scene, we want to keep the new value of that ID * pointer. */ SCENE_FOREACH_UNDO_NO_RESTORE, -} eSceneForeachUndoPreserveProcess; +}; static void scene_foreach_toolsettings_id_pointer_process( ID **id_p, @@ -464,9 +462,10 @@ static void scene_foreach_toolsettings_id_pointer_process( ID *id_old = *id_old_p; /* Old data has not been remapped to new values of the pointers, if we want to keep the old * pointer here we need its new address. */ - ID *id_old_new = id_old != NULL ? BLO_read_get_new_id_address(reader, id_old->lib, id_old) : - NULL; - if (id_old_new != NULL) { + ID *id_old_new = id_old != nullptr ? + BLO_read_get_new_id_address(reader, id_old->lib, id_old) : + nullptr; + if (id_old_new != nullptr) { BLI_assert(ELEM(id_old, id_old_new, id_old_new->orig_id)); *id_old_p = id_old_new; if (cb_flag & IDWALK_CB_USER) { @@ -489,7 +488,7 @@ static void scene_foreach_toolsettings_id_pointer_process( /* Special handling is needed here, as `scene_foreach_toolsettings` (and its dependency * `scene_foreach_paint`) are also used by `scene_undo_preserve`, where `LibraryForeachIDData - * *data` is NULL. */ + * *data` is nullptr. */ #define BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER( \ __data, __id, __do_undo_restore, __action, __reader, __id_old, __cb_flag) \ { \ @@ -498,7 +497,7 @@ static void scene_foreach_toolsettings_id_pointer_process( (ID **)&(__id), __action, __reader, (ID **)&(__id_old), __cb_flag); \ } \ else { \ - BLI_assert((__data) != NULL); \ + BLI_assert((__data) != nullptr); \ BKE_LIB_FOREACHID_PROCESS_IDSUPER(__data, __id, __cb_flag); \ } \ } \ @@ -511,7 +510,7 @@ static void scene_foreach_toolsettings_id_pointer_process( __func_call; \ } \ else { \ - BLI_assert((__data) != NULL); \ + BLI_assert((__data) != nullptr); \ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(__data, __func_call); \ } \ } \ @@ -536,10 +535,10 @@ static void scene_foreach_paint(LibraryForeachIDData *data, * this is equivalent to simply looping over slots from `paint`. * - In case we do `undo_restore`, we only want to consider the slots from the old one, since * those are the one we keep in the end. - * + In case the new data has less valid slots, we feed in a dummy NULL pointer. + * + In case the new data has less valid slots, we feed in a dummy null pointer. * + In case the new data has more valid slots, the extra ones are ignored. */ - Brush *brush_tmp = NULL; + Brush *brush_tmp = nullptr; Brush **brush_p = i < paint->tool_slots_len ? &paint->tool_slots[i].brush : &brush_tmp; BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER(data, *brush_p, @@ -725,7 +724,7 @@ static void scene_foreach_layer_collection(LibraryForeachIDData *data, ListBase LISTBASE_FOREACH (LayerCollection *, lc, lb) { /* XXX This is very weak. The whole idea of keeping pointers to private IDs is very bad * anyway... */ - const int cb_flag = (lc->collection != NULL && + const int cb_flag = (lc->collection != nullptr && (lc->collection->id.flag & LIB_EMBEDDED_DATA) != 0) ? IDWALK_CB_EMBEDDED : IDWALK_CB_NOP; @@ -760,7 +759,7 @@ static bool seq_foreach_member_id_cb(Sequence *seq, void *user_data) } if (seq->type == SEQ_TYPE_TEXT && seq->effectdata) { - TextVars *text_data = seq->effectdata; + TextVars *text_data = static_cast<TextVars *>(seq->effectdata); FOREACHID_PROCESS_IDSUPER(data, text_data->text_font, IDWALK_CB_USER); } @@ -792,8 +791,8 @@ static void scene_foreach_id(ID *id, LibraryForeachIDData *data) BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data, BKE_keyingsets_foreach_id(data, &scene->keyingsets)); - /* This pointer can be NULL during old files reading, better be safe than sorry. */ - if (scene->master_collection != NULL) { + /* This pointer can be nullptr during old files reading, better be safe than sorry. */ + if (scene->master_collection != nullptr) { BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL( data, BKE_library_foreach_ID_embedded(data, (ID **)&scene->master_collection)); } @@ -839,7 +838,7 @@ static void scene_foreach_id(ID *id, LibraryForeachIDData *data) ToolSettings *toolsett = scene->toolsettings; if (toolsett) { BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL( - data, scene_foreach_toolsettings(data, toolsett, false, NULL, toolsett)); + data, scene_foreach_toolsettings(data, toolsett, false, nullptr, toolsett)); } if (scene->rigidbody_world) { @@ -855,11 +854,10 @@ static void scene_foreach_cache(ID *id, void *user_data) { Scene *scene = (Scene *)id; - IDCacheKey key = { - .id_session_uuid = id->session_uuid, - .offset_in_ID = offsetof(Scene, eevee.light_cache_data), - .cache_v = scene->eevee.light_cache_data, - }; + IDCacheKey key{}; + key.id_session_uuid = id->session_uuid; + key.offset_in_ID = offsetof(Scene, eevee.light_cache_data); + key.cache_v = scene->eevee.light_cache_data; function_callback(id, &key, @@ -902,7 +900,7 @@ static bool seq_foreach_path_callback(Sequence *seq, void *user_data) static void scene_foreach_path(ID *id, BPathForeachPathData *bpath_data) { Scene *scene = (Scene *)id; - if (scene->ed != NULL) { + if (scene->ed != nullptr) { SEQ_for_each_callback(&scene->ed->seqbase, seq_foreach_path_callback, bpath_data); } } @@ -1012,7 +1010,7 @@ static void scene_blend_write(BlendWriter *writer, ID *id, const void *id_addres LISTBASE_FOREACH (TimeMarker *, marker, &sce->markers) { BLO_write_struct(writer, TimeMarker, marker); - if (marker->prop != NULL) { + if (marker->prop != nullptr) { IDP_BlendWrite(writer, marker->prop); } } @@ -1069,7 +1067,7 @@ static void scene_blend_write(BlendWriter *writer, ID *id, const void *id_addres BKE_screen_view3d_shading_blend_write(writer, &sce->display.shading); /* Freed on doversion. */ - BLI_assert(sce->layer_properties == NULL); + BLI_assert(sce->layer_properties == nullptr); } static void direct_link_paint_helper(BlendDataReader *reader, const Scene *scene, Paint **paint) @@ -1102,8 +1100,8 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id) { Scene *sce = (Scene *)id; - sce->depsgraph_hash = NULL; - sce->fps_info = NULL; + sce->depsgraph_hash = nullptr; + sce->fps_info = nullptr; memset(&sce->customdata_mask, 0, sizeof(sce->customdata_mask)); memset(&sce->customdata_mask_modal, 0, sizeof(sce->customdata_mask_modal)); @@ -1144,10 +1142,10 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id) BKE_paint_blend_read_data(reader, sce, &sce->toolsettings->imapaint.paint); - sce->toolsettings->particle.paintcursor = NULL; - sce->toolsettings->particle.scene = NULL; - sce->toolsettings->particle.object = NULL; - sce->toolsettings->gp_sculpt.paintcursor = NULL; + sce->toolsettings->particle.paintcursor = nullptr; + sce->toolsettings->particle.scene = nullptr; + sce->toolsettings->particle.object = nullptr; + sce->toolsettings->gp_sculpt.paintcursor = nullptr; /* relink grease pencil interpolation curves */ BLO_read_data_address(reader, &sce->toolsettings->gp_interpolate.custom_ipo); @@ -1181,9 +1179,9 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id) Editing *ed = sce->ed; BLO_read_data_address(reader, &ed->act_seq); - ed->cache = NULL; - ed->prefetch_job = NULL; - ed->runtime.sequence_lookup = NULL; + ed->cache = nullptr; + ed->prefetch_job = nullptr; + ed->runtime.sequence_lookup = nullptr; /* recursive link sequences, lb will be correctly initialized */ link_recurs_seq(reader, &ed->seqbase); @@ -1275,9 +1273,9 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id) if (rbw) { BLO_read_data_address(reader, &rbw->shared); - if (rbw->shared == NULL) { + if (rbw->shared == nullptr) { /* Link deprecated caches if they exist, so we can use them for versioning. - * We should only do this when rbw->shared == NULL, because those pointers + * We should only do this when rbw->shared == nullptr, because those pointers * are always set (for compatibility with older Blenders). We mustn't link * the same pointcache twice. */ BKE_ptcache_blend_read_data(reader, &rbw->ptcaches, &rbw->pointcache, false); @@ -1291,7 +1289,7 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id) /* must nullify the reference to physics sim object, since it no-longer exist * (and will need to be recalculated) */ - rbw->shared->physics_world = NULL; + rbw->shared->physics_world = nullptr; /* link caches */ BKE_ptcache_blend_read_data(reader, &rbw->shared->ptcaches, &rbw->shared->pointcache, false); @@ -1301,13 +1299,13 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id) rbw->ltime = (float)rbw->shared->pointcache->startframe; } } - rbw->objects = NULL; + rbw->objects = nullptr; rbw->numbodies = 0; /* set effector weights */ BLO_read_data_address(reader, &rbw->effector_weights); if (!rbw->effector_weights) { - rbw->effector_weights = BKE_effector_add_weights(NULL); + rbw->effector_weights = BKE_effector_add_weights(nullptr); } } @@ -1352,7 +1350,7 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id) static void composite_patch(bNodeTree *ntree, Scene *scene) { LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { - if (node->id == NULL && + if (node->id == nullptr && ((node->type == CMP_NODE_R_LAYERS) || (node->type == CMP_NODE_CRYPTOMATTE && node->custom1 == CMP_CRYPTOMATTE_SRC_RENDER))) { node->id = &scene->id; @@ -1423,14 +1421,14 @@ static void scene_blend_read_lib(BlendLibReader *reader, ID *id) LISTBASE_FOREACH_MUTABLE (Base *, base_legacy, &sce->base) { BLO_read_id_address(reader, sce->id.lib, &base_legacy->object); - if (base_legacy->object == NULL) { + if (base_legacy->object == nullptr) { BLO_reportf_wrap(BLO_read_lib_reports(reader), RPT_WARNING, TIP_("LIB: object lost from scene: '%s'"), sce->id.name + 2); BLI_remlink(&sce->base, base_legacy); if (base_legacy == sce->basact) { - sce->basact = NULL; + sce->basact = nullptr; } MEM_freeN(base_legacy); } @@ -1494,7 +1492,7 @@ static void scene_blend_read_lib(BlendLibReader *reader, ID *id) } #ifdef USE_SETSCENE_CHECK - if (sce->set != NULL) { + if (sce->set != nullptr) { sce->flag |= SCE_READFILE_LIBLINK_NEED_SETSCENE_CHECK; } #endif @@ -1588,12 +1586,12 @@ static void scene_undo_preserve(BlendLibReader *reader, ID *id_new, ID *id_old) Scene *scene_old = (Scene *)id_old; SWAP(View3DCursor, scene_old->cursor, scene_new->cursor); - if (scene_new->toolsettings != NULL && scene_old->toolsettings != NULL) { + if (scene_new->toolsettings != nullptr && scene_old->toolsettings != nullptr) { /* First try to restore ID pointers that can be and should be preserved (like brushes or * palettes), and counteract the swap of the whole ToolSettings structs below for the others * (like object ones). */ scene_foreach_toolsettings( - NULL, scene_new->toolsettings, true, reader, scene_old->toolsettings); + nullptr, scene_new->toolsettings, true, reader, scene_old->toolsettings); SWAP(ToolSettings, *scene_old->toolsettings, *scene_new->toolsettings); } } @@ -1602,46 +1600,50 @@ static void scene_lib_override_apply_post(ID *id_dst, ID *UNUSED(id_src)) { Scene *scene = (Scene *)id_dst; - if (scene->rigidbody_world != NULL) { + if (scene->rigidbody_world != nullptr) { PTCacheID pid; - BKE_ptcache_id_from_rigidbody(&pid, NULL, scene->rigidbody_world); + BKE_ptcache_id_from_rigidbody(&pid, nullptr, scene->rigidbody_world); LISTBASE_FOREACH (PointCache *, point_cache, pid.ptcaches) { point_cache->flag |= PTCACHE_FLAG_INFO_DIRTY; } } } -IDTypeInfo IDType_ID_SCE = { - .id_code = ID_SCE, - .id_filter = FILTER_ID_SCE, - .main_listbase_index = INDEX_ID_SCE, - .struct_size = sizeof(Scene), - .name = "Scene", - .name_plural = "scenes", - .translation_context = BLT_I18NCONTEXT_ID_SCENE, - .flags = 0, - .asset_type_info = NULL, +constexpr IDTypeInfo get_type_info() +{ + IDTypeInfo info{}; + info.id_code = ID_SCE; + info.id_filter = FILTER_ID_SCE; + info.main_listbase_index = INDEX_ID_SCE; + info.struct_size = sizeof(Scene); + info.name = "Scene"; + info.name_plural = "scenes"; + info.translation_context = BLT_I18NCONTEXT_ID_SCENE; + info.flags = 0; + info.asset_type_info = nullptr; - .init_data = scene_init_data, - .copy_data = scene_copy_data, - .free_data = scene_free_data, - /* For now default `BKE_lib_id_make_local_generic()` should work, may need more work though to - * support all possible corner cases. */ - .make_local = NULL, - .foreach_id = scene_foreach_id, - .foreach_cache = scene_foreach_cache, - .foreach_path = scene_foreach_path, - .owner_get = NULL, + info.init_data = scene_init_data; + info.copy_data = scene_copy_data; + info.free_data = scene_free_data; + /* For now default `BKE_lib_id_make_local_generic()` should work, may need more work though to + * support all possible corner cases. */ + info.make_local = nullptr; + info.foreach_id = scene_foreach_id; + info.foreach_cache = scene_foreach_cache; + info.foreach_path = scene_foreach_path; + info.owner_get = nullptr; - .blend_write = scene_blend_write, - .blend_read_data = scene_blend_read_data, - .blend_read_lib = scene_blend_read_lib, - .blend_read_expand = scene_blend_read_expand, + info.blend_write = scene_blend_write; + info.blend_read_data = scene_blend_read_data; + info.blend_read_lib = scene_blend_read_lib; + info.blend_read_expand = scene_blend_read_expand; - .blend_read_undo_preserve = scene_undo_preserve, + info.blend_read_undo_preserve = scene_undo_preserve; - .lib_override_apply_post = scene_lib_override_apply_post, -}; + info.lib_override_apply_post = scene_lib_override_apply_post; + return info; +} +IDTypeInfo IDType_ID_SCE = get_type_info(); const char *RE_engine_id_BLENDER_EEVEE = "BLENDER_EEVEE"; const char *RE_engine_id_BLENDER_WORKBENCH = "BLENDER_WORKBENCH"; @@ -1652,12 +1654,12 @@ void free_avicodecdata(AviCodecData *acd) if (acd) { if (acd->lpFormat) { MEM_freeN(acd->lpFormat); - acd->lpFormat = NULL; + acd->lpFormat = nullptr; acd->cbFormat = 0; } if (acd->lpParms) { MEM_freeN(acd->lpParms); - acd->lpParms = NULL; + acd->lpParms = nullptr; acd->cbParms = 0; } } @@ -1668,11 +1670,7 @@ static void remove_sequencer_fcurves(Scene *sce) AnimData *adt = BKE_animdata_from_id(&sce->id); if (adt && adt->action) { - FCurve *fcu, *nextfcu; - - for (fcu = adt->action->curves.first; fcu; fcu = nextfcu) { - nextfcu = fcu->next; - + LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, &adt->action->curves) { if ((fcu->rna_path) && strstr(fcu->rna_path, "sequences_all")) { action_groups_remove_channel(adt->action, fcu); BKE_fcurve_free(fcu); @@ -1683,51 +1681,51 @@ static void remove_sequencer_fcurves(Scene *sce) ToolSettings *BKE_toolsettings_copy(ToolSettings *toolsettings, const int flag) { - if (toolsettings == NULL) { - return NULL; + if (toolsettings == nullptr) { + return nullptr; } - ToolSettings *ts = MEM_dupallocN(toolsettings); + ToolSettings *ts = static_cast<ToolSettings *>(MEM_dupallocN(toolsettings)); if (ts->vpaint) { - ts->vpaint = MEM_dupallocN(ts->vpaint); + ts->vpaint = static_cast<VPaint *>(MEM_dupallocN(ts->vpaint)); BKE_paint_copy(&ts->vpaint->paint, &ts->vpaint->paint, flag); } if (ts->wpaint) { - ts->wpaint = MEM_dupallocN(ts->wpaint); + ts->wpaint = static_cast<VPaint *>(MEM_dupallocN(ts->wpaint)); BKE_paint_copy(&ts->wpaint->paint, &ts->wpaint->paint, flag); } if (ts->sculpt) { - ts->sculpt = MEM_dupallocN(ts->sculpt); + ts->sculpt = static_cast<Sculpt *>(MEM_dupallocN(ts->sculpt)); BKE_paint_copy(&ts->sculpt->paint, &ts->sculpt->paint, flag); } if (ts->uvsculpt) { - ts->uvsculpt = MEM_dupallocN(ts->uvsculpt); + ts->uvsculpt = static_cast<UvSculpt *>(MEM_dupallocN(ts->uvsculpt)); BKE_paint_copy(&ts->uvsculpt->paint, &ts->uvsculpt->paint, flag); } if (ts->gp_paint) { - ts->gp_paint = MEM_dupallocN(ts->gp_paint); + ts->gp_paint = static_cast<GpPaint *>(MEM_dupallocN(ts->gp_paint)); BKE_paint_copy(&ts->gp_paint->paint, &ts->gp_paint->paint, flag); } if (ts->gp_vertexpaint) { - ts->gp_vertexpaint = MEM_dupallocN(ts->gp_vertexpaint); + ts->gp_vertexpaint = static_cast<GpVertexPaint *>(MEM_dupallocN(ts->gp_vertexpaint)); BKE_paint_copy(&ts->gp_vertexpaint->paint, &ts->gp_vertexpaint->paint, flag); } if (ts->gp_sculptpaint) { - ts->gp_sculptpaint = MEM_dupallocN(ts->gp_sculptpaint); + ts->gp_sculptpaint = static_cast<GpSculptPaint *>(MEM_dupallocN(ts->gp_sculptpaint)); BKE_paint_copy(&ts->gp_sculptpaint->paint, &ts->gp_sculptpaint->paint, flag); } if (ts->gp_weightpaint) { - ts->gp_weightpaint = MEM_dupallocN(ts->gp_weightpaint); + ts->gp_weightpaint = static_cast<GpWeightPaint *>(MEM_dupallocN(ts->gp_weightpaint)); BKE_paint_copy(&ts->gp_weightpaint->paint, &ts->gp_weightpaint->paint, flag); } if (ts->curves_sculpt) { - ts->curves_sculpt = MEM_dupallocN(ts->curves_sculpt); + ts->curves_sculpt = static_cast<CurvesSculpt *>(MEM_dupallocN(ts->curves_sculpt)); BKE_paint_copy(&ts->curves_sculpt->paint, &ts->curves_sculpt->paint, flag); } BKE_paint_copy(&ts->imapaint.paint, &ts->imapaint.paint, flag); - ts->particle.paintcursor = NULL; - ts->particle.scene = NULL; - ts->particle.object = NULL; + ts->particle.paintcursor = nullptr; + ts->particle.scene = nullptr; + ts->particle.object = nullptr; /* duplicate Grease Pencil interpolation curve */ ts->gp_interpolate.custom_ipo = BKE_curvemapping_copy(ts->gp_interpolate.custom_ipo); @@ -1743,7 +1741,7 @@ ToolSettings *BKE_toolsettings_copy(ToolSettings *toolsettings, const int flag) void BKE_toolsettings_free(ToolSettings *toolsettings) { - if (toolsettings == NULL) { + if (toolsettings == nullptr) { return; } if (toolsettings->vpaint) { @@ -1811,7 +1809,7 @@ void BKE_scene_copy_data_eevee(Scene *sce_dst, const Scene *sce_src) { /* Copy eevee data between scenes. */ sce_dst->eevee = sce_src->eevee; - sce_dst->eevee.light_cache_data = NULL; + sce_dst->eevee.light_cache_data = nullptr; sce_dst->eevee.light_cache_info[0] = '\0'; /* TODO: Copy the cache. */ } @@ -1862,7 +1860,7 @@ Scene *BKE_scene_duplicate(Main *bmain, Scene *sce, eSceneCopyMethod type) /* make a private copy of the avicodecdata */ if (sce->r.avicodecdata) { - sce_copy->r.avicodecdata = MEM_dupallocN(sce->r.avicodecdata); + sce_copy->r.avicodecdata = static_cast<AviCodecData *>(MEM_dupallocN(sce->r.avicodecdata)); sce_copy->r.avicodecdata->lpFormat = MEM_dupallocN(sce_copy->r.avicodecdata->lpFormat); sce_copy->r.avicodecdata->lpParms = MEM_dupallocN(sce_copy->r.avicodecdata->lpParms); } @@ -1870,14 +1868,14 @@ Scene *BKE_scene_duplicate(Main *bmain, Scene *sce, eSceneCopyMethod type) BKE_sound_reset_scene_runtime(sce_copy); /* grease pencil */ - sce_copy->gpd = NULL; + sce_copy->gpd = nullptr; - sce_copy->preview = NULL; + sce_copy->preview = nullptr; return sce_copy; } - eDupli_ID_Flags duplicate_flags = U.dupflag | USER_DUP_OBJECT; + eDupli_ID_Flags duplicate_flags = (eDupli_ID_Flags)(U.dupflag | USER_DUP_OBJECT); sce_copy = (Scene *)BKE_id_copy(bmain, (ID *)sce); id_us_min(&sce_copy->id); @@ -1900,7 +1898,7 @@ Scene *BKE_scene_duplicate(Main *bmain, Scene *sce, eSceneCopyMethod type) /* In case root duplicated ID is linked, assume we want to get a local copy of it and * duplicate all expected linked data. */ if (ID_IS_LINKED(sce)) { - duplicate_flags |= USER_DUP_LINKED_ID; + duplicate_flags = (eDupli_ID_Flags)(duplicate_flags | USER_DUP_LINKED_ID); } } @@ -1919,22 +1917,25 @@ Scene *BKE_scene_duplicate(Main *bmain, Scene *sce, eSceneCopyMethod type) /* Deep-duplicate collections and objects (using preferences' settings for which sub-data to * duplicate along the object itself). */ - BKE_collection_duplicate( - bmain, NULL, sce_copy->master_collection, duplicate_flags, LIB_ID_DUPLICATE_IS_SUBPROCESS); + BKE_collection_duplicate(bmain, + nullptr, + sce_copy->master_collection, + duplicate_flags, + LIB_ID_DUPLICATE_IS_SUBPROCESS); /* Rigid body world collections may not be instantiated as scene's collections, ensure they * also get properly duplicated. */ - if (sce_copy->rigidbody_world != NULL) { - if (sce_copy->rigidbody_world->group != NULL) { + if (sce_copy->rigidbody_world != nullptr) { + if (sce_copy->rigidbody_world->group != nullptr) { BKE_collection_duplicate(bmain, - NULL, + nullptr, sce_copy->rigidbody_world->group, duplicate_flags, LIB_ID_DUPLICATE_IS_SUBPROCESS); } - if (sce_copy->rigidbody_world->constraints != NULL) { + if (sce_copy->rigidbody_world->constraints != nullptr) { BKE_collection_duplicate(bmain, - NULL, + nullptr, sce_copy->rigidbody_world->constraints, duplicate_flags, LIB_ID_DUPLICATE_IS_SUBPROCESS); @@ -1995,9 +1996,7 @@ bool BKE_scene_can_be_removed(const Main *bmain, const Scene *scene) Scene *BKE_scene_add(Main *bmain, const char *name) { - Scene *sce; - - sce = BKE_id_new(bmain, ID_SCE, name); + Scene *sce = static_cast<Scene *>(BKE_id_new(bmain, ID_SCE, name)); id_us_min(&sce->id); id_us_ensure_real(&sce->id); @@ -2023,25 +2022,22 @@ Object *BKE_scene_object_find_by_name(const Scene *scene, const char *name) } } } - return NULL; + return nullptr; } void BKE_scene_set_background(Main *bmain, Scene *scene) { - Object *ob; - /* check for cyclic sets, for reading old files but also for definite security (py?) */ BKE_scene_validate_setscene(bmain, scene); /* deselect objects (for dataselect) */ - for (ob = bmain->objects.first; ob; ob = ob->id.next) { + LISTBASE_FOREACH (Object *, ob, &bmain->objects) { ob->flag &= ~SELECT; } /* copy layers and flags from bases to objects */ LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) { LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) { - ob = base->object; /* collection patch... */ BKE_scene_object_base_flag_sync_from_base(base); } @@ -2060,7 +2056,7 @@ Scene *BKE_scene_set_name(Main *bmain, const char *name) } printf("Can't find scene: '%s' in file: '%s'\n", name, BKE_main_blendfile_path(bmain)); - return NULL; + return nullptr; } int BKE_scene_base_iter_next( @@ -2071,9 +2067,9 @@ int BKE_scene_base_iter_next( /* init */ if (val == 0) { iter->phase = F_START; - iter->dupob = NULL; - iter->duplilist = NULL; - iter->dupli_refob = NULL; + iter->dupob = nullptr; + iter->duplilist = nullptr; + iter->dupli_refob = nullptr; } else { /* run_again is set when a duplilist has been ended */ @@ -2084,7 +2080,7 @@ int BKE_scene_base_iter_next( if (iter->phase == F_START) { ViewLayer *view_layer = (depsgraph) ? DEG_get_evaluated_view_layer(depsgraph) : BKE_view_layer_context_active_PLACEHOLDER(*scene); - *base = view_layer->object_bases.first; + *base = static_cast<Base *>(view_layer->object_bases.first); if (*base) { *ob = (*base)->object; iter->phase = F_SCENE; @@ -2095,7 +2091,7 @@ int BKE_scene_base_iter_next( (*scene) = (*scene)->set; ViewLayer *view_layer_set = BKE_view_layer_default_render(*scene); if (view_layer_set->object_bases.first) { - *base = view_layer_set->object_bases.first; + *base = static_cast<Base *>(view_layer_set->object_bases.first); *ob = (*base)->object; iter->phase = F_SCENE; break; @@ -2116,7 +2112,7 @@ int BKE_scene_base_iter_next( (*scene) = (*scene)->set; ViewLayer *view_layer_set = BKE_view_layer_default_render(*scene); if (view_layer_set->object_bases.first) { - *base = view_layer_set->object_bases.first; + *base = static_cast<Base *>(view_layer_set->object_bases.first); *ob = (*base)->object; break; } @@ -2126,7 +2122,7 @@ int BKE_scene_base_iter_next( } } - if (*base == NULL) { + if (*base == nullptr) { iter->phase = F_START; } else { @@ -2135,16 +2131,16 @@ int BKE_scene_base_iter_next( /* Collections cannot be duplicated for meta-balls yet, * this enters eternal loop because of * makeDispListMBall getting called inside of collection_duplilist */ - if ((*base)->object->instance_collection == NULL) { + if ((*base)->object->instance_collection == nullptr) { iter->duplilist = object_duplilist(depsgraph, (*scene), (*base)->object); - iter->dupob = iter->duplilist->first; + iter->dupob = static_cast<DupliObject *>(iter->duplilist->first); if (!iter->dupob) { free_object_duplilist(iter->duplilist); - iter->duplilist = NULL; + iter->duplilist = nullptr; } - iter->dupli_refob = NULL; + iter->dupli_refob = nullptr; } } } @@ -2174,11 +2170,11 @@ int BKE_scene_base_iter_next( if (iter->dupli_refob) { /* Restore last object's real matrix. */ copy_m4_m4(iter->dupli_refob->obmat, iter->omat); - iter->dupli_refob = NULL; + iter->dupli_refob = nullptr; } free_object_duplilist(iter->duplilist); - iter->duplilist = NULL; + iter->duplilist = nullptr; run_again = true; } } @@ -2195,7 +2191,7 @@ bool BKE_scene_has_view_layer(const Scene *scene, const ViewLayer *layer) Scene *BKE_scene_find_from_collection(const Main *bmain, const Collection *collection) { - for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) { + LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { LISTBASE_FOREACH (ViewLayer *, layer, &scene->view_layers) { if (BKE_view_layer_has_collection(layer, collection)) { return scene; @@ -2203,21 +2199,21 @@ Scene *BKE_scene_find_from_collection(const Main *bmain, const Collection *colle } } - return NULL; + return nullptr; } #ifdef DURIAN_CAMERA_SWITCH Object *BKE_scene_camera_switch_find(Scene *scene) { if (scene->r.mode & R_NO_CAMERA_SWITCH) { - return NULL; + return nullptr; } const int ctime = (int)BKE_scene_ctime_get(scene); int frame = -(MAXFRAME + 1); int min_frame = MAXFRAME + 1; - Object *camera = NULL; - Object *first_camera = NULL; + Object *camera = nullptr; + Object *first_camera = nullptr; LISTBASE_FOREACH (TimeMarker *, m, &scene->markers) { if (m->camera && (m->camera->visibility_flag & OB_HIDE_RENDER) == 0) { @@ -2237,7 +2233,7 @@ Object *BKE_scene_camera_switch_find(Scene *scene) } } - if (camera == NULL) { + if (camera == nullptr) { /* If there's no marker to the left of current frame, * use camera from left-most marker to solve all sort * of Schrodinger uncertainties. @@ -2270,7 +2266,10 @@ const char *BKE_scene_find_marker_name(const Scene *scene, int frame) const TimeMarker *m1, *m2; /* search through markers for match */ - for (m1 = markers->first, m2 = markers->last; m1 && m2; m1 = m1->next, m2 = m2->prev) { + for (m1 = static_cast<const TimeMarker *>(markers->first), + m2 = static_cast<const TimeMarker *>(markers->last); + m1 && m2; + m1 = m1->next, m2 = m2->prev) { if (m1->frame == frame) { return m1->name; } @@ -2284,14 +2283,14 @@ const char *BKE_scene_find_marker_name(const Scene *scene, int frame) } } - return NULL; + return nullptr; } const char *BKE_scene_find_last_marker_name(const Scene *scene, int frame) { - const TimeMarker *marker, *best_marker = NULL; + const TimeMarker *best_marker = nullptr; int best_frame = -MAXFRAME * 2; - for (marker = scene->markers.first; marker; marker = marker->next) { + LISTBASE_FOREACH (const TimeMarker *, marker, &scene->markers) { if (marker->frame == frame) { return marker->name; } @@ -2302,7 +2301,7 @@ const char *BKE_scene_find_last_marker_name(const Scene *scene, int frame) } } - return best_marker ? best_marker->name : NULL; + return best_marker ? best_marker->name : nullptr; } int BKE_scene_frame_snap_by_seconds(Scene *scene, double interval_in_seconds, int frame) @@ -2335,7 +2334,7 @@ bool BKE_scene_validate_setscene(Main *bmain, Scene *sce) Scene *sce_iter; int a, totscene; - if (sce->set == NULL) { + if (sce->set == nullptr) { return true; } totscene = BLI_listbase_count(&bmain->scenes); @@ -2344,7 +2343,7 @@ bool BKE_scene_validate_setscene(Main *bmain, Scene *sce) /* more iterations than scenes means we have a cycle */ if (a > totscene) { /* the tested scene gets zero'ed, that's typically current scene */ - sce->set = NULL; + sce->set = nullptr; return false; } } @@ -2437,9 +2436,8 @@ int BKE_scene_orientation_get_index_from_flag(Scene *scene, int flag) static bool check_rendered_viewport_visible(Main *bmain) { - wmWindowManager *wm = bmain->wm.first; - wmWindow *window; - for (window = wm->windows.first; window != NULL; window = window->next) { + wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first); + LISTBASE_FOREACH (const wmWindow *, window, &wm->windows) { const bScreen *screen = BKE_workspace_active_screen_get(window->workspace_hook); Scene *scene = window->scene; RenderEngineType *type = RE_engines_find(scene->r.engine); @@ -2448,8 +2446,8 @@ static bool check_rendered_viewport_visible(Main *bmain) continue; } - for (ScrArea *area = screen->areabase.first; area != NULL; area = area->next) { - View3D *v3d = area->spacedata.first; + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + View3D *v3d = static_cast<View3D *>(area->spacedata.first); if (area->spacetype != SPACE_VIEW3D) { continue; } @@ -2462,7 +2460,7 @@ static bool check_rendered_viewport_visible(Main *bmain) } /* TODO(campbell): shouldn't we be able to use 'DEG_get_view_layer' here? - * Currently this is NULL on load, so don't. */ + * Currently this is nullptr on load, so don't. */ static void prepare_mesh_for_viewport_render(Main *bmain, const ViewLayer *view_layer) { /* This is needed to prepare mesh to be used by the render @@ -2476,18 +2474,15 @@ static void prepare_mesh_for_viewport_render(Main *bmain, const ViewLayer *view_ Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer); if (obedit) { - Mesh *mesh = obedit->data; + Mesh *mesh = static_cast<Mesh *>(obedit->data); if ((obedit->type == OB_MESH) && ((obedit->id.recalc & ID_RECALC_ALL) || (mesh->id.recalc & ID_RECALC_ALL))) { if (check_rendered_viewport_visible(bmain)) { BMesh *bm = mesh->edit_mesh->bm; - BM_mesh_bm_to_me(bmain, - bm, - mesh, - (&(struct BMeshToMeshParams){ - .calc_object_remap = true, - .update_shapekey_indices = true, - })); + BMeshToMeshParams params{}; + params.calc_object_remap = true; + params.update_shapekey_indices = true; + BM_mesh_bm_to_me(bmain, bm, mesh, ¶ms); DEG_id_tag_update(&mesh->id, 0); } } @@ -2697,13 +2692,11 @@ void BKE_scene_view_layer_graph_evaluated_ensure(Main *bmain, Scene *scene, View SceneRenderView *BKE_scene_add_render_view(Scene *sce, const char *name) { - SceneRenderView *srv; - if (!name) { name = DATA_("RenderView"); } - srv = MEM_callocN(sizeof(SceneRenderView), "new render view"); + SceneRenderView *srv = MEM_cnew<SceneRenderView>(__func__); BLI_strncpy(srv->name, name, sizeof(srv->name)); BLI_uniquename(&sce->r.views, srv, @@ -2751,17 +2744,17 @@ int get_render_subsurf_level(const RenderData *r, int lvl, bool for_render) return lvl; } -int get_render_child_particle_number(const RenderData *r, int num, bool for_render) +int get_render_child_particle_number(const RenderData *r, int child_num, bool for_render) { if (r->mode & R_SIMPLIFY) { if (for_render) { - return (int)(r->simplify_particles_render * num); + return (int)(r->simplify_particles_render * child_num); } - return (int)(r->simplify_particles * num); + return (int)(r->simplify_particles * child_num); } - return num; + return child_num; } Base *_setlooper_base_step(Scene **sce_iter, ViewLayer *view_layer, Base *base) @@ -2770,7 +2763,7 @@ Base *_setlooper_base_step(Scene **sce_iter, ViewLayer *view_layer, Base *base) /* Common case, step to the next. */ return base->next; } - if ((base == NULL) && (view_layer != NULL)) { + if ((base == nullptr) && (view_layer != nullptr)) { /* First time looping, return the scenes first base. */ /* For the first loop we should get the layer from workspace when available. */ if (view_layer->object_bases.first) { @@ -2792,7 +2785,7 @@ Base *_setlooper_base_step(Scene **sce_iter, ViewLayer *view_layer, Base *base) } } - return NULL; + return nullptr; } bool BKE_scene_use_shading_nodes_custom(Scene *scene) @@ -2823,10 +2816,10 @@ bool BKE_scene_uses_cycles(const Scene *scene) } /* This enumeration has to match the one defined in the Cycles addon. */ -typedef enum eCyclesFeatureSet { +enum eCyclesFeatureSet { CYCLES_FEATURES_SUPPORTED = 0, CYCLES_FEATURES_EXPERIMENTAL = 1, -} eCyclesFeatureSet; +}; bool BKE_scene_uses_cycles_experimental_features(Scene *scene) { @@ -2845,7 +2838,7 @@ bool BKE_scene_uses_cycles_experimental_features(Scene *scene) void BKE_scene_base_flag_to_objects(ViewLayer *view_layer) { - Base *base = view_layer->object_bases.first; + Base *base = static_cast<Base *>(view_layer->object_bases.first); while (base) { BKE_scene_object_base_flag_sync_from_base(base); @@ -2954,7 +2947,6 @@ double BKE_scene_unit_scale(const UnitSettings *unit, const int unit_type, doubl int BKE_scene_multiview_num_views_get(const RenderData *rd) { - SceneRenderView *srv; int totviews = 0; if ((rd->scemode & R_MULTIVIEW) == 0) { @@ -2962,18 +2954,20 @@ int BKE_scene_multiview_num_views_get(const RenderData *rd) } if (rd->views_format == SCE_VIEWS_FORMAT_STEREO_3D) { - srv = BLI_findstring(&rd->views, STEREO_LEFT_NAME, offsetof(SceneRenderView, name)); + SceneRenderView *srv = static_cast<SceneRenderView *>( + BLI_findstring(&rd->views, STEREO_LEFT_NAME, offsetof(SceneRenderView, name))); if ((srv && srv->viewflag & SCE_VIEW_DISABLE) == 0) { totviews++; } - srv = BLI_findstring(&rd->views, STEREO_RIGHT_NAME, offsetof(SceneRenderView, name)); + srv = static_cast<SceneRenderView *>( + BLI_findstring(&rd->views, STEREO_RIGHT_NAME, offsetof(SceneRenderView, name))); if ((srv && srv->viewflag & SCE_VIEW_DISABLE) == 0) { totviews++; } } else { - for (srv = rd->views.first; srv; srv = srv->next) { + LISTBASE_FOREACH (SceneRenderView *, srv, &rd->views) { if ((srv->viewflag & SCE_VIEW_DISABLE) == 0) { totviews++; } @@ -3001,7 +2995,7 @@ bool BKE_scene_multiview_is_stereo3d(const RenderData *rd) bool BKE_scene_multiview_is_render_view_active(const RenderData *rd, const SceneRenderView *srv) { - if (srv == NULL) { + if (srv == nullptr) { return false; } @@ -3027,8 +3021,6 @@ bool BKE_scene_multiview_is_render_view_active(const RenderData *rd, const Scene bool BKE_scene_multiview_is_render_view_first(const RenderData *rd, const char *viewname) { - SceneRenderView *srv; - if ((rd->scemode & R_MULTIVIEW) == 0) { return true; } @@ -3037,7 +3029,7 @@ bool BKE_scene_multiview_is_render_view_first(const RenderData *rd, const char * return true; } - for (srv = rd->views.first; srv; srv = srv->next) { + LISTBASE_FOREACH (const SceneRenderView *, srv, &rd->views) { if (BKE_scene_multiview_is_render_view_active(rd, srv)) { return STREQ(viewname, srv->name); } @@ -3048,8 +3040,6 @@ bool BKE_scene_multiview_is_render_view_first(const RenderData *rd, const char * bool BKE_scene_multiview_is_render_view_last(const RenderData *rd, const char *viewname) { - SceneRenderView *srv; - if ((rd->scemode & R_MULTIVIEW) == 0) { return true; } @@ -3058,7 +3048,7 @@ bool BKE_scene_multiview_is_render_view_last(const RenderData *rd, const char *v return true; } - for (srv = rd->views.last; srv; srv = srv->prev) { + LISTBASE_FOREACH_BACKWARD (const SceneRenderView *, srv, &rd->views) { if (BKE_scene_multiview_is_render_view_active(rd, srv)) { return STREQ(viewname, srv->name); } @@ -3073,10 +3063,10 @@ SceneRenderView *BKE_scene_multiview_render_view_findindex(const RenderData *rd, size_t nr; if ((rd->scemode & R_MULTIVIEW) == 0) { - return NULL; + return nullptr; } - for (srv = rd->views.first, nr = 0; srv; srv = srv->next) { + for (srv = static_cast<SceneRenderView *>(rd->views.first), nr = 0; srv; srv = srv->next) { if (BKE_scene_multiview_is_render_view_active(rd, srv)) { if (nr++ == view_id) { return srv; @@ -3110,7 +3100,7 @@ int BKE_scene_multiview_view_id_get(const RenderData *rd, const char *viewname) return 0; } - for (srv = rd->views.first, nr = 0; srv; srv = srv->next) { + for (srv = static_cast<SceneRenderView *>(rd->views.first), nr = 0; srv; srv = srv->next) { if (BKE_scene_multiview_is_render_view_active(rd, srv)) { if (STREQ(viewname, srv->name)) { return nr; @@ -3139,7 +3129,8 @@ void BKE_scene_multiview_view_filepath_get(const RenderData *rd, SceneRenderView *srv; char suffix[FILE_MAX]; - srv = BLI_findstring(&rd->views, viewname, offsetof(SceneRenderView, name)); + srv = static_cast<SceneRenderView *>( + BLI_findstring(&rd->views, viewname, offsetof(SceneRenderView, name))); if (srv) { BLI_strncpy(suffix, srv->suffix, sizeof(suffix)); } @@ -3155,11 +3146,12 @@ const char *BKE_scene_multiview_view_suffix_get(const RenderData *rd, const char { SceneRenderView *srv; - if ((viewname == NULL) || (viewname[0] == '\0')) { + if ((viewname == nullptr) || (viewname[0] == '\0')) { return viewname; } - srv = BLI_findstring(&rd->views, viewname, offsetof(SceneRenderView, name)); + srv = static_cast<SceneRenderView *>( + BLI_findstring(&rd->views, viewname, offsetof(SceneRenderView, name))); if (srv) { return srv->suffix; } @@ -3182,7 +3174,6 @@ void BKE_scene_multiview_view_prefix_get(Scene *scene, char *r_prefix, const char **r_ext) { - SceneRenderView *srv; size_t index_act; const char *suf_act; const char delims[] = {'.', '\0'}; @@ -3191,13 +3182,13 @@ void BKE_scene_multiview_view_prefix_get(Scene *scene, /* begin of extension */ index_act = BLI_str_rpartition(name, delims, r_ext, &suf_act); - if (*r_ext == NULL) { + if (*r_ext == nullptr) { return; } BLI_assert(index_act > 0); UNUSED_VARS_NDEBUG(index_act); - for (srv = scene->r.views.first; srv; srv = srv->next) { + LISTBASE_FOREACH (SceneRenderView *, srv, &scene->r.views) { if (BKE_scene_multiview_is_render_view_active(&scene->r, srv)) { const size_t len = strlen(srv->suffix); const size_t ext_len = strlen(*r_ext); @@ -3250,16 +3241,16 @@ int BKE_scene_multiview_num_videos_get(const RenderData *rd) /* Manipulation of depsgraph storage. */ /* This is a key which identifies depsgraph. */ -typedef struct DepsgraphKey { +struct DepsgraphKey { const ViewLayer *view_layer; /* TODO(sergey): Need to include window somehow (same layer might be in a * different states in different windows). */ -} DepsgraphKey; +}; static unsigned int depsgraph_key_hash(const void *key_v) { - const DepsgraphKey *key = key_v; + const DepsgraphKey *key = static_cast<const DepsgraphKey *>(key_v); unsigned int hash = BLI_ghashutil_ptrhash(key->view_layer); /* TODO(sergey): Include hash from other fields in the key. */ return hash; @@ -3267,21 +3258,21 @@ static unsigned int depsgraph_key_hash(const void *key_v) static bool depsgraph_key_compare(const void *key_a_v, const void *key_b_v) { - const DepsgraphKey *key_a = key_a_v; - const DepsgraphKey *key_b = key_b_v; + const DepsgraphKey *key_a = static_cast<const DepsgraphKey *>(key_a_v); + const DepsgraphKey *key_b = static_cast<const DepsgraphKey *>(key_b_v); /* TODO(sergey): Compare rest of. */ return !(key_a->view_layer == key_b->view_layer); } static void depsgraph_key_free(void *key_v) { - DepsgraphKey *key = key_v; + DepsgraphKey *key = static_cast<DepsgraphKey *>(key_v); MEM_freeN(key); } static void depsgraph_key_value_free(void *value) { - Depsgraph *depsgraph = value; + Depsgraph *depsgraph = static_cast<Depsgraph *>(value); DEG_graph_free(depsgraph); } @@ -3293,23 +3284,23 @@ void BKE_scene_allocate_depsgraph_hash(Scene *scene) void BKE_scene_ensure_depsgraph_hash(Scene *scene) { - if (scene->depsgraph_hash == NULL) { + if (scene->depsgraph_hash == nullptr) { BKE_scene_allocate_depsgraph_hash(scene); } } void BKE_scene_free_depsgraph_hash(Scene *scene) { - if (scene->depsgraph_hash == NULL) { + if (scene->depsgraph_hash == nullptr) { return; } BLI_ghash_free(scene->depsgraph_hash, depsgraph_key_free, depsgraph_key_value_free); - scene->depsgraph_hash = NULL; + scene->depsgraph_hash = nullptr; } void BKE_scene_free_view_layer_depsgraph(Scene *scene, ViewLayer *view_layer) { - if (scene->depsgraph_hash != NULL) { + if (scene->depsgraph_hash != nullptr) { DepsgraphKey key = {view_layer}; BLI_ghash_remove(scene->depsgraph_hash, &key, depsgraph_key_free, depsgraph_key_value_free); } @@ -3321,17 +3312,17 @@ static Depsgraph **scene_get_depsgraph_p(Scene *scene, ViewLayer *view_layer, const bool allocate_ghash_entry) { - /* bmain may be NULL here! */ - BLI_assert(scene != NULL); - BLI_assert(view_layer != NULL); + /* bmain may be nullptr here! */ + BLI_assert(scene != nullptr); + BLI_assert(view_layer != nullptr); BLI_assert(BKE_scene_has_view_layer(scene, view_layer)); /* Make sure hash itself exists. */ if (allocate_ghash_entry) { BKE_scene_ensure_depsgraph_hash(scene); } - if (scene->depsgraph_hash == NULL) { - return NULL; + if (scene->depsgraph_hash == nullptr) { + return nullptr; } DepsgraphKey key; @@ -3350,23 +3341,23 @@ static Depsgraph **scene_get_depsgraph_p(Scene *scene, } /* Depsgraph was not found in the ghash, but the key still needs allocating. */ - *key_ptr = MEM_mallocN(sizeof(DepsgraphKey), __func__); + *key_ptr = MEM_new<DepsgraphKey>(__func__); **key_ptr = key; - *depsgraph_ptr = NULL; + *depsgraph_ptr = nullptr; return depsgraph_ptr; } static Depsgraph **scene_ensure_depsgraph_p(Main *bmain, Scene *scene, ViewLayer *view_layer) { - BLI_assert(bmain != NULL); + BLI_assert(bmain != nullptr); Depsgraph **depsgraph_ptr = scene_get_depsgraph_p(scene, view_layer, true); - if (depsgraph_ptr == NULL) { + if (depsgraph_ptr == nullptr) { /* The scene has no depsgraph hash. */ - return NULL; + return nullptr; } - if (*depsgraph_ptr != NULL) { + if (*depsgraph_ptr != nullptr) { /* The depsgraph was found, no need to allocate. */ return depsgraph_ptr; } @@ -3393,25 +3384,25 @@ Depsgraph *BKE_scene_get_depsgraph(const Scene *scene, const ViewLayer *view_lay { BLI_assert(BKE_scene_has_view_layer(scene, view_layer)); - if (scene->depsgraph_hash == NULL) { - return NULL; + if (scene->depsgraph_hash == nullptr) { + return nullptr; } DepsgraphKey key; key.view_layer = view_layer; - return BLI_ghash_lookup(scene->depsgraph_hash, &key); + return static_cast<Depsgraph *>(BLI_ghash_lookup(scene->depsgraph_hash, &key)); } Depsgraph *BKE_scene_ensure_depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer) { Depsgraph **depsgraph_ptr = scene_ensure_depsgraph_p(bmain, scene, view_layer); - return (depsgraph_ptr != NULL) ? *depsgraph_ptr : NULL; + return (depsgraph_ptr != nullptr) ? *depsgraph_ptr : nullptr; } static char *scene_undo_depsgraph_gen_key(Scene *scene, ViewLayer *view_layer, char *key_full) { - if (key_full == NULL) { - key_full = MEM_callocN(MAX_ID_NAME + FILE_MAX + MAX_NAME, __func__); + if (key_full == nullptr) { + key_full = static_cast<char *>(MEM_callocN(MAX_ID_NAME + FILE_MAX + MAX_NAME, __func__)); } size_t key_full_offset = BLI_strncpy_rlen(key_full, scene->id.name, MAX_ID_NAME); @@ -3430,24 +3421,23 @@ GHash *BKE_scene_undo_depsgraphs_extract(Main *bmain) GHash *depsgraph_extract = BLI_ghash_new( BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, __func__); - for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) { - if (scene->depsgraph_hash == NULL) { + LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { + if (scene->depsgraph_hash == nullptr) { /* In some cases, e.g. when undo has to perform multiple steps at once, no depsgraph will - * be built so this pointer may be NULL. */ + * be built so this pointer may be nullptr. */ continue; } - for (ViewLayer *view_layer = scene->view_layers.first; view_layer != NULL; - view_layer = view_layer->next) { + LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) { DepsgraphKey key; key.view_layer = view_layer; Depsgraph **depsgraph = (Depsgraph **)BLI_ghash_lookup_p(scene->depsgraph_hash, &key); - if (depsgraph != NULL && *depsgraph != NULL) { - char *key_full = scene_undo_depsgraph_gen_key(scene, view_layer, NULL); + if (depsgraph != nullptr && *depsgraph != nullptr) { + char *key_full = scene_undo_depsgraph_gen_key(scene, view_layer, nullptr); /* We steal the depsgraph from the scene. */ BLI_ghash_insert(depsgraph_extract, key_full, *depsgraph); - *depsgraph = NULL; + *depsgraph = nullptr; } } } @@ -3457,22 +3447,21 @@ GHash *BKE_scene_undo_depsgraphs_extract(Main *bmain) void BKE_scene_undo_depsgraphs_restore(Main *bmain, GHash *depsgraph_extract) { - for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) { - for (ViewLayer *view_layer = scene->view_layers.first; view_layer != NULL; - view_layer = view_layer->next) { + LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { + LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) { char key_full[MAX_ID_NAME + FILE_MAX + MAX_NAME] = {0}; scene_undo_depsgraph_gen_key(scene, view_layer, key_full); Depsgraph **depsgraph_extract_ptr = (Depsgraph **)BLI_ghash_lookup_p(depsgraph_extract, key_full); - if (depsgraph_extract_ptr == NULL) { + if (depsgraph_extract_ptr == nullptr) { continue; } - BLI_assert(*depsgraph_extract_ptr != NULL); + BLI_assert(*depsgraph_extract_ptr != nullptr); Depsgraph **depsgraph_scene_ptr = scene_get_depsgraph_p(scene, view_layer, true); - BLI_assert(depsgraph_scene_ptr != NULL); - BLI_assert(*depsgraph_scene_ptr == NULL); + BLI_assert(depsgraph_scene_ptr != nullptr); + BLI_assert(*depsgraph_scene_ptr == nullptr); /* We steal the depsgraph back from our 'extract' storage to the scene. */ Depsgraph *depsgraph = *depsgraph_extract_ptr; @@ -3482,7 +3471,7 @@ void BKE_scene_undo_depsgraphs_restore(Main *bmain, GHash *depsgraph_extract) DEG_graph_tag_relations_update(depsgraph); *depsgraph_scene_ptr = depsgraph; - *depsgraph_extract_ptr = NULL; + *depsgraph_extract_ptr = nullptr; } } @@ -3515,7 +3504,7 @@ void BKE_scene_transform_orientation_remove(Scene *scene, TransformOrientation * TransformOrientation *BKE_scene_transform_orientation_find(const Scene *scene, const int index) { - return BLI_findlink(&scene->transform_spaces, index); + return static_cast<TransformOrientation *>(BLI_findlink(&scene->transform_spaces, index)); } int BKE_scene_transform_orientation_get_index(const Scene *scene, diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c index 7d0c6598440..f17450ac3f4 100644 --- a/source/blender/blenkernel/intern/studiolight.c +++ b/source/blender/blenkernel/intern/studiolight.c @@ -1166,18 +1166,18 @@ static void studiolight_add_files_from_datafolder(const int folder_id, const char *subfolder, int flag) { - struct direntry *dir; + struct direntry *dirs; const char *folder = BKE_appdir_folder_id(folder_id, subfolder); if (folder) { - uint totfile = BLI_filelist_dir_contents(folder, &dir); + const uint dirs_num = BLI_filelist_dir_contents(folder, &dirs); int i; - for (i = 0; i < totfile; i++) { - if (dir[i].type & S_IFREG) { - studiolight_add_file(dir[i].path, flag); + for (i = 0; i < dirs_num; i++) { + if (dirs[i].type & S_IFREG) { + studiolight_add_file(dirs[i].path, flag); } } - BLI_filelist_free(dir, totfile); - dir = NULL; + BLI_filelist_free(dirs, dirs_num); + dirs = NULL; } } diff --git a/source/blender/blenkernel/intern/subdiv.c b/source/blender/blenkernel/intern/subdiv.c index 7b1ebd5df1f..ee1976d5946 100644 --- a/source/blender/blenkernel/intern/subdiv.c +++ b/source/blender/blenkernel/intern/subdiv.c @@ -106,7 +106,7 @@ Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings, * The thing here is: OpenSubdiv can only deal with faces, but our * side of subdiv also deals with loose vertices and edges. */ } - Subdiv *subdiv = MEM_callocN(sizeof(Subdiv), "subdiv from converetr"); + Subdiv *subdiv = MEM_callocN(sizeof(Subdiv), "subdiv from converter"); subdiv->settings = *settings; subdiv->topology_refiner = osd_topology_refiner; subdiv->evaluator = NULL; diff --git a/source/blender/blenlib/BLI_enumerable_thread_specific.hh b/source/blender/blenlib/BLI_enumerable_thread_specific.hh index 51bf8d06cf1..a5bd79d5826 100644 --- a/source/blender/blenlib/BLI_enumerable_thread_specific.hh +++ b/source/blender/blenlib/BLI_enumerable_thread_specific.hh @@ -3,23 +3,20 @@ #pragma once #ifdef WITH_TBB - -# ifdef WITH_TBB /* Quiet top level deprecation message, unrelated to API usage here. */ -# if defined(WIN32) && !defined(NOMINMAX) +# if defined(WIN32) && !defined(NOMINMAX) /* TBB includes Windows.h which will define min/max macros causing issues * when we try to use std::min and std::max later on. */ -# define NOMINMAX -# define TBB_MIN_MAX_CLEANUP -# endif -# include <tbb/enumerable_thread_specific.h> -# ifdef WIN32 +# define NOMINMAX +# define TBB_MIN_MAX_CLEANUP +# endif +# include <tbb/enumerable_thread_specific.h> +# ifdef WIN32 /* We cannot keep this defined, since other parts of the code deal with this on their own, leading * to multiple define warnings unless we un-define this, however we can only undefine this if we * were the ones that made the definition earlier. */ -# ifdef TBB_MIN_MAX_CLEANUP -# undef NOMINMAX -# endif +# ifdef TBB_MIN_MAX_CLEANUP +# undef NOMINMAX # endif # endif #endif diff --git a/source/blender/blenlib/BLI_math_base.hh b/source/blender/blenlib/BLI_math_base.hh index 6a988eda8a9..83f414f853a 100644 --- a/source/blender/blenlib/BLI_math_base.hh +++ b/source/blender/blenlib/BLI_math_base.hh @@ -12,7 +12,6 @@ #include <type_traits> #include "BLI_math_base_safe.h" -#include "BLI_math_vec_types.hh" #include "BLI_utildefines.h" #ifdef WITH_GMP @@ -21,6 +20,15 @@ namespace blender::math { +template<typename T> +inline constexpr bool is_math_float_type = (std::is_floating_point_v<T> +#ifdef WITH_GMP + || std::is_same_v<T, mpq_class> +#endif +); + +template<typename T> inline constexpr bool is_math_integral_type = std::is_integral_v<T>; + template<typename T> inline bool is_zero(const T &a) { return a == T(0); @@ -84,19 +92,23 @@ template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))> inline T ceil(const return std::ceil(a); } +template<typename T> inline T distance(const T &a, const T &b) +{ + return std::abs(a - b); +} + template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))> inline T fract(const T &a) { return a - std::floor(a); } -template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))> -inline T interpolate(const T &a, const T &b, const T &t) +template<typename T, typename FactorT, BLI_ENABLE_IF((is_math_float_type<FactorT>))> +inline T interpolate(const T &a, const T &b, const FactorT &t) { return a * (1 - t) + b * t; } -template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))> -inline T midpoint(const T &a, const T &b) +template<typename T> inline T midpoint(const T &a, const T &b) { return (a + b) * T(0.5); } diff --git a/source/blender/blenlib/BLI_math_statistics.h b/source/blender/blenlib/BLI_math_statistics.h index d33d4be360a..501a250e1a0 100644 --- a/source/blender/blenlib/BLI_math_statistics.h +++ b/source/blender/blenlib/BLI_math_statistics.h @@ -28,7 +28,7 @@ extern "C" { * * \param n: the dimension of the vectors (and hence, of the covariance matrix to compute). * \param cos_vn: the nD points to compute covariance from. - * \param nbr_cos_vn: the number of nD coordinates in cos_vn. + * \param cos_vn_num: the number of nD coordinates in cos_vn. * \param center: the center (or mean point) of cos_vn. If NULL, * it is assumed cos_vn is already centered. * \param use_sample_correction: whether to apply sample correction @@ -37,7 +37,7 @@ extern "C" { */ void BLI_covariance_m_vn_ex(int n, const float *cos_vn, - int nbr_cos_vn, + int cos_vn_num, const float *center, bool use_sample_correction, float *r_covmat); @@ -45,12 +45,12 @@ void BLI_covariance_m_vn_ex(int n, * \brief Compute the covariance matrix of given set of 3D coordinates. * * \param cos_v3: the 3D points to compute covariance from. - * \param nbr_cos_v3: the number of 3D coordinates in cos_v3. + * \param cos_v3_num: the number of 3D coordinates in cos_v3. * \return r_covmat the computed covariance matrix. * \return r_center the computed center (mean) of 3D points (may be NULL). */ void BLI_covariance_m3_v3n(const float (*cos_v3)[3], - int nbr_cos_v3, + int cos_v3_num, bool use_sample_correction, float r_covmat[3][3], float r_center[3]); diff --git a/source/blender/blenlib/BLI_math_vec_types.hh b/source/blender/blenlib/BLI_math_vec_types.hh index 389307e331d..d9524eae746 100644 --- a/source/blender/blenlib/BLI_math_vec_types.hh +++ b/source/blender/blenlib/BLI_math_vec_types.hh @@ -321,7 +321,7 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size> BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] * b[i]); } - friend vec_base operator*(const vec_base &a, T b) + template<typename FactorT> friend vec_base operator*(const vec_base &a, FactorT b) { BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] * b); } @@ -579,13 +579,4 @@ using double2 = vec_base<double, 2>; using double3 = vec_base<double, 3>; using double4 = vec_base<double, 4>; -template<typename T> -inline constexpr bool is_math_float_type = (std::is_floating_point_v<T> -#ifdef WITH_GMP - || std::is_same_v<T, mpq_class> -#endif -); - -template<typename T> inline constexpr bool is_math_integral_type = std::is_integral_v<T>; - } // namespace blender diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index 4689072bcce..f3283371a3c 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -389,7 +389,7 @@ void mid_v3_v3v3v3(float v[3], const float v1[3], const float v2[3], const float void mid_v2_v2v2v2(float v[2], const float v1[2], const float v2[2], const float v3[2]); void mid_v3_v3v3v3v3( float v[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3]); -void mid_v3_v3_array(float r[3], const float (*vec_arr)[3], unsigned int nbr); +void mid_v3_v3_array(float r[3], const float (*vec_arr)[3], unsigned int vec_arr_num); /** * Specialized function for calculating normals. @@ -660,7 +660,10 @@ void minmax_v4v4_v4(float min[4], float max[4], const float vec[4]); void minmax_v3v3_v3(float min[3], float max[3], const float vec[3]); void minmax_v2v2_v2(float min[2], float max[2], const float vec[2]); -void minmax_v3v3_v3_array(float r_min[3], float r_max[3], const float (*vec_arr)[3], int nbr); +void minmax_v3v3_v3_array(float r_min[3], + float r_max[3], + const float (*vec_arr)[3], + int var_arr_num); /** ensure \a v1 is \a dist from \a v2 */ void dist_ensure_v3_v3fl(float v1[3], const float v2[3], float dist); diff --git a/source/blender/blenlib/BLI_math_vector.hh b/source/blender/blenlib/BLI_math_vector.hh index b1a3242ae52..b9f0939674e 100644 --- a/source/blender/blenlib/BLI_math_vector.hh +++ b/source/blender/blenlib/BLI_math_vector.hh @@ -10,7 +10,7 @@ #include <cmath> #include <type_traits> -#include "BLI_math_base_safe.h" +#include "BLI_math_base.hh" #include "BLI_math_vec_types.hh" #include "BLI_span.hh" #include "BLI_utildefines.h" @@ -339,10 +339,10 @@ inline vec_base<T, 3> cross_poly(Span<vec_base<T, 3>> poly) return n; } -template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))> +template<typename T, typename FactorT, int Size, BLI_ENABLE_IF((is_math_float_type<FactorT>))> inline vec_base<T, Size> interpolate(const vec_base<T, Size> &a, const vec_base<T, Size> &b, - const T &t) + const FactorT &t) { return a * (1 - t) + b * t; } diff --git a/source/blender/blenlib/BLI_timeit.hh b/source/blender/blenlib/BLI_timeit.hh index 31e1b5d2a03..8da0a020d99 100644 --- a/source/blender/blenlib/BLI_timeit.hh +++ b/source/blender/blenlib/BLI_timeit.hh @@ -38,6 +38,41 @@ class ScopedTimer { } }; +class ScopedTimerAveraged { + private: + std::string name_; + TimePoint start_; + + int64_t &total_count_; + Nanoseconds &total_time_; + Nanoseconds &min_time_; + + public: + ScopedTimerAveraged(std::string name, + int64_t &total_count, + Nanoseconds &total_time, + Nanoseconds &min_time) + : name_(std::move(name)), + total_count_(total_count), + total_time_(total_time), + min_time_(min_time) + { + start_ = Clock::now(); + } + + ~ScopedTimerAveraged(); +}; + } // namespace blender::timeit #define SCOPED_TIMER(name) blender::timeit::ScopedTimer scoped_timer(name) + +/** + * Print the average and minimum runtime of the timer's scope. + * \warning This uses static variables, so it is not thread-safe. + */ +#define SCOPED_TIMER_AVERAGED(name) \ + static int64_t total_count_; \ + static blender::timeit::Nanoseconds total_time_; \ + static blender::timeit::Nanoseconds min_time_ = blender::timeit::Nanoseconds::max(); \ + blender::timeit::ScopedTimerAveraged scoped_timer(name, total_count_, total_time_, min_time_) diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index af71c96fc10..647726722b1 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -165,8 +165,8 @@ set(SRC BLI_bitmap.h BLI_bitmap_draw_2d.h BLI_blenlib.h - BLI_boxpack_2d.h BLI_bounds.hh + BLI_boxpack_2d.h BLI_buffer.h BLI_color.hh BLI_compiler_attrs.h @@ -174,8 +174,8 @@ set(SRC BLI_compiler_typecheck.h BLI_console.h BLI_convexhull_2d.h - BLI_cpp_type_make.hh BLI_cpp_type.hh + BLI_cpp_type_make.hh BLI_delaunay_2d.h BLI_dial_2d.h BLI_disjoint_set.hh @@ -235,8 +235,8 @@ set(SRC BLI_map.hh BLI_map_slots.hh BLI_math.h - BLI_math_base.hh BLI_math_base.h + BLI_math_base.hh BLI_math_base_safe.h BLI_math_bits.h BLI_math_boolean.hh diff --git a/source/blender/blenlib/intern/BLI_filelist.c b/source/blender/blenlib/intern/BLI_filelist.c index 9f1f8fe0448..76fc5b6342a 100644 --- a/source/blender/blenlib/intern/BLI_filelist.c +++ b/source/blender/blenlib/intern/BLI_filelist.c @@ -97,8 +97,8 @@ static int bli_compare(struct direntry *entry1, struct direntry *entry2) } struct BuildDirCtx { - struct direntry *files; /* array[nrfiles] */ - int nrfiles; + struct direntry *files; /* array[files_num] */ + int files_num; }; /** @@ -154,7 +154,7 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) if (newnum) { if (dir_ctx->files) { void *const tmp = MEM_reallocN(dir_ctx->files, - (dir_ctx->nrfiles + newnum) * sizeof(struct direntry)); + (dir_ctx->files_num + newnum) * sizeof(struct direntry)); if (tmp) { dir_ctx->files = (struct direntry *)tmp; } @@ -171,7 +171,7 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) if (dir_ctx->files) { struct dirlink *dlink = (struct dirlink *)dirbase.first; - struct direntry *file = &dir_ctx->files[dir_ctx->nrfiles]; + struct direntry *file = &dir_ctx->files[dir_ctx->files_num]; while (dlink) { char fullname[PATH_MAX]; memset(file, 0, sizeof(struct direntry)); @@ -186,7 +186,7 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) * does not support stat on '\\SERVER\foo\..', sigh... */ file->type |= S_IFDIR; } - dir_ctx->nrfiles++; + dir_ctx->files_num++; file++; dlink = dlink->next; } @@ -199,7 +199,7 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) BLI_freelist(&dirbase); if (dir_ctx->files) { qsort(dir_ctx->files, - dir_ctx->nrfiles, + dir_ctx->files_num, sizeof(struct direntry), (int (*)(const void *, const void *))bli_compare); } @@ -219,7 +219,7 @@ unsigned int BLI_filelist_dir_contents(const char *dirname, struct direntry **r_ { struct BuildDirCtx dir_ctx; - dir_ctx.nrfiles = 0; + dir_ctx.files_num = 0; dir_ctx.files = NULL; bli_builddir(&dir_ctx, dirname); @@ -233,7 +233,7 @@ unsigned int BLI_filelist_dir_contents(const char *dirname, struct direntry **r_ *r_filelist = MEM_mallocN(sizeof(**r_filelist), __func__); } - return dir_ctx.nrfiles; + return dir_ctx.files_num; } void BLI_filelist_entry_size_to_string(const struct stat *st, diff --git a/source/blender/blenlib/intern/delaunay_2d.cc b/source/blender/blenlib/intern/delaunay_2d.cc index e6164c98402..3039b72128d 100644 --- a/source/blender/blenlib/intern/delaunay_2d.cc +++ b/source/blender/blenlib/intern/delaunay_2d.cc @@ -2188,17 +2188,19 @@ static int power_of_10_greater_equal_to(int x) } /** - Incrementally each edge of each input face as an edge constraint. + * Incrementally each edge of each input face as an edge constraint. * The code will ensure that the #CDTEdge's created will have ids that tie them * back to the original face edge (using a numbering system for those edges * that starts with cdt->face_edge_offset, and continues with the edges in * order around each face in turn. And then the next face starts at * cdt->face_edge_offset beyond the start for the previous face. + * Return the number of faces added, which may be less than input.face.size() + * in the case that some faces have less than 3 sides. */ template<typename T> -void add_face_constraints(CDT_state<T> *cdt_state, - const CDT_input<T> &input, - CDT_output_type output_type) +int add_face_constraints(CDT_state<T> *cdt_state, + const CDT_input<T> &input, + CDT_output_type output_type) { int nv = input.vert.size(); int nf = input.face.size(); @@ -2216,6 +2218,7 @@ void add_face_constraints(CDT_state<T> *cdt_state, * together the are >= INT_MAX, then the Delaunay calculation will take unreasonably long anyway. */ BLI_assert(INT_MAX / cdt_state->face_edge_offset > nf); + int faces_added = 0; for (int f = 0; f < nf; f++) { int flen = input.face[f].size(); if (flen <= 2) { @@ -2231,6 +2234,7 @@ void add_face_constraints(CDT_state<T> *cdt_state, /* Ignore face edges with invalid vertices. */ continue; } + ++faces_added; CDTVert<T> *v1 = cdt->get_vert_resolve_merge(iv1); CDTVert<T> *v2 = cdt->get_vert_resolve_merge(iv2); LinkNode *edge_list; @@ -2265,6 +2269,7 @@ void add_face_constraints(CDT_state<T> *cdt_state, } } } + return faces_added; } /* Delete_edge but try not to mess up outer face. @@ -2642,7 +2647,8 @@ CDT_result<T> get_cdt_output(CDT_state<T> *cdt_state, const CDT_input<T> UNUSED(input), CDT_output_type output_type) { - prepare_cdt_for_output(cdt_state, output_type); + CDT_output_type oty = output_type; + prepare_cdt_for_output(cdt_state, oty); CDT_result<T> result; CDTArrangement<T> *cdt = &cdt_state->cdt; result.face_edge_offset = cdt_state->face_edge_offset; @@ -2774,7 +2780,11 @@ CDT_result<T> delaunay_calc(const CDT_input<T> &input, CDT_output_type output_ty add_input_verts(&cdt_state, input); initial_triangulation(&cdt_state.cdt); add_edge_constraints(&cdt_state, input); - add_face_constraints(&cdt_state, input, output_type); + int actual_nf = add_face_constraints(&cdt_state, input, output_type); + if (actual_nf == 0 && !ELEM(output_type, CDT_FULL, CDT_INSIDE, CDT_CONSTRAINTS)) { + /* Can't look for faces or holes if there were no valid input faces. */ + output_type = CDT_INSIDE; + } return get_cdt_output(&cdt_state, input, output_type); } diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c index 27f8f1d4bc8..26a0479f445 100644 --- a/source/blender/blenlib/intern/fileops.c +++ b/source/blender/blenlib/intern/fileops.c @@ -382,9 +382,9 @@ static bool delete_recursive(const char *dir) { struct direntry *filelist, *fl; bool err = false; - uint nbr, i; + uint filelist_num, i; - i = nbr = BLI_filelist_dir_contents(dir, &filelist); + i = filelist_num = BLI_filelist_dir_contents(dir, &filelist); fl = filelist; while (i--) { const char *file = BLI_path_basename(fl->path); @@ -415,7 +415,7 @@ static bool delete_recursive(const char *dir) err = true; } - BLI_filelist_free(filelist, nbr); + BLI_filelist_free(filelist, filelist_num); return err; } diff --git a/source/blender/blenlib/intern/generic_virtual_array.cc b/source/blender/blenlib/intern/generic_virtual_array.cc index c6abf3624e1..8a6ef8e792f 100644 --- a/source/blender/blenlib/intern/generic_virtual_array.cc +++ b/source/blender/blenlib/intern/generic_virtual_array.cc @@ -391,10 +391,7 @@ void GVMutableArray_GSpan::save() if (data_ != owned_data_) { return; } - const int64_t element_size = type_->size(); - for (int64_t i : IndexRange(size_)) { - varray_.set_by_copy(i, POINTER_OFFSET(owned_data_, element_size * i)); - } + varray_.set_all(owned_data_); } void GVMutableArray_GSpan::disable_not_applied_warning() diff --git a/source/blender/blenlib/intern/math_statistics.c b/source/blender/blenlib/intern/math_statistics.c index 14baca891c0..53fbc16f3fc 100644 --- a/source/blender/blenlib/intern/math_statistics.c +++ b/source/blender/blenlib/intern/math_statistics.c @@ -21,7 +21,7 @@ typedef struct CovarianceData { float *r_covmat; float covfac; int n; - int nbr_cos_vn; + int cos_vn_num; } CovarianceData; static void covariance_m_vn_ex_task_cb(void *__restrict userdata, @@ -33,7 +33,7 @@ static void covariance_m_vn_ex_task_cb(void *__restrict userdata, const float *center = data->center; float *r_covmat = data->r_covmat; const int n = data->n; - const int nbr_cos_vn = data->nbr_cos_vn; + const int cos_vn_num = data->cos_vn_num; int k; @@ -55,12 +55,12 @@ static void covariance_m_vn_ex_task_cb(void *__restrict userdata, } if (center) { - for (k = 0; k < nbr_cos_vn; k++) { + for (k = 0; k < cos_vn_num; k++) { r_covmat[a] += (cos_vn[k * n + i] - center[i]) * (cos_vn[k * n + j] - center[j]); } } else { - for (k = 0; k < nbr_cos_vn; k++) { + for (k = 0; k < cos_vn_num; k++) { r_covmat[a] += cos_vn[k * n + i] * cos_vn[k * n + j]; } } @@ -73,7 +73,7 @@ static void covariance_m_vn_ex_task_cb(void *__restrict userdata, void BLI_covariance_m_vn_ex(const int n, const float *cos_vn, - const int nbr_cos_vn, + const int cos_vn_num, const float *center, const bool use_sample_correction, float *r_covmat) @@ -81,7 +81,7 @@ void BLI_covariance_m_vn_ex(const int n, /* Note about that division: see https://en.wikipedia.org/wiki/Bessel%27s_correction. * In a nutshell, it must be 1 / (n - 1) for 'sample data', and 1 / n for 'population data'... */ - const float covfac = 1.0f / (float)(use_sample_correction ? nbr_cos_vn - 1 : nbr_cos_vn); + const float covfac = 1.0f / (float)(use_sample_correction ? cos_vn_num - 1 : cos_vn_num); memset(r_covmat, 0, sizeof(*r_covmat) * (size_t)(n * n)); @@ -91,27 +91,27 @@ void BLI_covariance_m_vn_ex(const int n, .r_covmat = r_covmat, .covfac = covfac, .n = n, - .nbr_cos_vn = nbr_cos_vn, + .cos_vn_num = cos_vn_num, }; TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); - settings.use_threading = ((nbr_cos_vn * n * n) >= 10000); + settings.use_threading = ((cos_vn_num * n * n) >= 10000); BLI_task_parallel_range(0, n * n, &data, covariance_m_vn_ex_task_cb, &settings); } void BLI_covariance_m3_v3n(const float (*cos_v3)[3], - const int nbr_cos_v3, + const int cos_v3_num, const bool use_sample_correction, float r_covmat[3][3], float r_center[3]) { float center[3]; - const float mean_fac = 1.0f / (float)nbr_cos_v3; + const float mean_fac = 1.0f / (float)cos_v3_num; int i; zero_v3(center); - for (i = 0; i < nbr_cos_v3; i++) { + for (i = 0; i < cos_v3_num; i++) { /* Applying mean_fac here rather than once at the end reduce compute errors... */ madd_v3_v3fl(center, cos_v3[i], mean_fac); } @@ -121,5 +121,5 @@ void BLI_covariance_m3_v3n(const float (*cos_v3)[3], } BLI_covariance_m_vn_ex( - 3, (const float *)cos_v3, nbr_cos_v3, center, use_sample_correction, (float *)r_covmat); + 3, (const float *)cos_v3, cos_v3_num, center, use_sample_correction, (float *)r_covmat); } diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c index da6a6dff16f..5dcdabaf760 100644 --- a/source/blender/blenlib/intern/math_vector.c +++ b/source/blender/blenlib/intern/math_vector.c @@ -268,12 +268,12 @@ void mid_v3_v3v3v3v3( v[2] = (v1[2] + v2[2] + v3[2] + v4[2]) / 4.0f; } -void mid_v3_v3_array(float r[3], const float (*vec_arr)[3], const uint nbr) +void mid_v3_v3_array(float r[3], const float (*vec_arr)[3], const uint vec_arr_num) { - const float factor = 1.0f / (float)nbr; + const float factor = 1.0f / (float)vec_arr_num; zero_v3(r); - for (uint i = 0; i < nbr; i++) { + for (uint i = 0; i < vec_arr_num; i++) { madd_v3_v3fl(r, vec_arr[i], factor); } } @@ -904,9 +904,12 @@ void minmax_v2v2_v2(float min[2], float max[2], const float vec[2]) } } -void minmax_v3v3_v3_array(float r_min[3], float r_max[3], const float (*vec_arr)[3], int nbr) +void minmax_v3v3_v3_array(float r_min[3], + float r_max[3], + const float (*vec_arr)[3], + int var_arr_num) { - while (nbr--) { + while (var_arr_num--) { minmax_v3v3_v3(r_min, r_max, *vec_arr++); } } diff --git a/source/blender/blenlib/intern/timeit.cc b/source/blender/blenlib/intern/timeit.cc index 2dcfe2e6ab1..f11f9c4ad94 100644 --- a/source/blender/blenlib/intern/timeit.cc +++ b/source/blender/blenlib/intern/timeit.cc @@ -2,6 +2,8 @@ #include "BLI_timeit.hh" +#include <algorithm> + namespace blender::timeit { void print_duration(Nanoseconds duration) @@ -17,4 +19,20 @@ void print_duration(Nanoseconds duration) } } +ScopedTimerAveraged::~ScopedTimerAveraged() +{ + const TimePoint end = Clock::now(); + const Nanoseconds duration = end - start_; + + total_count_++; + total_time_ += duration; + min_time_ = std::min(duration, min_time_); + + std::cout << "Timer '" << name_ << "': (Average: "; + print_duration(total_time_ / total_count_); + std::cout << ", Min: "; + print_duration(min_time_); + std::cout << ")\n"; +} + } // namespace blender::timeit diff --git a/source/blender/blenlib/tests/BLI_math_base_test.cc b/source/blender/blenlib/tests/BLI_math_base_test.cc index 62f2b2775d0..dd35deef4a8 100644 --- a/source/blender/blenlib/tests/BLI_math_base_test.cc +++ b/source/blender/blenlib/tests/BLI_math_base_test.cc @@ -151,4 +151,9 @@ TEST(math_base, Midpoint) EXPECT_NEAR(math::midpoint(100.0f, 200.0f), 150.0f, 1e-4f); } +TEST(math_base, InterpolateInt) +{ + EXPECT_EQ(math::interpolate(100, 200, 0.4f), 140); +} + } // namespace blender::tests diff --git a/source/blender/blenlib/tests/BLI_math_vector_test.cc b/source/blender/blenlib/tests/BLI_math_vector_test.cc index 8c310645d6d..282be5f1963 100644 --- a/source/blender/blenlib/tests/BLI_math_vector_test.cc +++ b/source/blender/blenlib/tests/BLI_math_vector_test.cc @@ -85,4 +85,24 @@ TEST(math_vector, Clamp) EXPECT_EQ(result_2.z, -50); } +TEST(math_vector, InterpolateInt) +{ + const int3 a(0, -100, 50); + const int3 b(0, 100, 100); + const int3 result = math::interpolate(a, b, 0.75); + EXPECT_EQ(result.x, 0); + EXPECT_EQ(result.y, 50); + EXPECT_EQ(result.z, 87); +} + +TEST(math_vector, InterpolateFloat) +{ + const float3 a(40.0f, -100.0f, 50.0f); + const float3 b(20.0f, 100.0f, 100.0f); + const float3 result = math::interpolate(a, b, 0.5); + EXPECT_FLOAT_EQ(result.x, 30.0f); + EXPECT_FLOAT_EQ(result.y, 0.0f); + EXPECT_FLOAT_EQ(result.z, 75.0f); +} + } // namespace blender::tests diff --git a/source/blender/blenlib/tests/performance/BLI_ghash_performance_test.cc b/source/blender/blenlib/tests/performance/BLI_ghash_performance_test.cc index eae90f130cd..0ff488202c2 100644 --- a/source/blender/blenlib/tests/performance/BLI_ghash_performance_test.cc +++ b/source/blender/blenlib/tests/performance/BLI_ghash_performance_test.cc @@ -177,17 +177,17 @@ TEST(ghash, TextMurmur2a) /* Int: uniform 100M first integers. */ -static void int_ghash_tests(GHash *ghash, const char *id, const unsigned int nbr) +static void int_ghash_tests(GHash *ghash, const char *id, const unsigned int count) { printf("\n========== STARTING %s ==========\n", id); { - unsigned int i = nbr; + unsigned int i = count; TIMEIT_START(int_insert); #ifdef GHASH_RESERVE - BLI_ghash_reserve(ghash, nbr); + BLI_ghash_reserve(ghash, count); #endif while (i--) { @@ -200,7 +200,7 @@ static void int_ghash_tests(GHash *ghash, const char *id, const unsigned int nbr PRINTF_GHASH_STATS(ghash); { - unsigned int i = nbr; + unsigned int i = count; TIMEIT_START(int_lookup); @@ -266,17 +266,17 @@ TEST(ghash, IntMurmur2a100000000) /* Int: random 50M integers. */ -static void randint_ghash_tests(GHash *ghash, const char *id, const unsigned int nbr) +static void randint_ghash_tests(GHash *ghash, const char *id, const unsigned int count) { printf("\n========== STARTING %s ==========\n", id); - unsigned int *data = (unsigned int *)MEM_mallocN(sizeof(*data) * (size_t)nbr, __func__); + unsigned int *data = (unsigned int *)MEM_mallocN(sizeof(*data) * (size_t)count, __func__); unsigned int *dt; unsigned int i; { RNG *rng = BLI_rng_new(1); - for (i = nbr, dt = data; i--; dt++) { + for (i = count, dt = data; i--; dt++) { *dt = BLI_rng_get_uint(rng); } BLI_rng_free(rng); @@ -286,10 +286,10 @@ static void randint_ghash_tests(GHash *ghash, const char *id, const unsigned int TIMEIT_START(int_insert); #ifdef GHASH_RESERVE - BLI_ghash_reserve(ghash, nbr); + BLI_ghash_reserve(ghash, count); #endif - for (i = nbr, dt = data; i--; dt++) { + for (i = count, dt = data; i--; dt++) { BLI_ghash_insert(ghash, POINTER_FROM_UINT(*dt), POINTER_FROM_UINT(*dt)); } @@ -301,7 +301,7 @@ static void randint_ghash_tests(GHash *ghash, const char *id, const unsigned int { TIMEIT_START(int_lookup); - for (i = nbr, dt = data; i--; dt++) { + for (i = count, dt = data; i--; dt++) { void *v = BLI_ghash_lookup(ghash, POINTER_FROM_UINT(*dt)); EXPECT_EQ(POINTER_AS_UINT(v), *dt); } @@ -375,18 +375,18 @@ TEST(ghash, Int4NoHash50000000) /* Int_v4: 20M of randomly-generated integer vectors. */ -static void int4_ghash_tests(GHash *ghash, const char *id, const unsigned int nbr) +static void int4_ghash_tests(GHash *ghash, const char *id, const unsigned int count) { printf("\n========== STARTING %s ==========\n", id); - void *data_v = MEM_mallocN(sizeof(unsigned int[4]) * (size_t)nbr, __func__); + void *data_v = MEM_mallocN(sizeof(unsigned int[4]) * (size_t)count, __func__); unsigned int(*data)[4] = (unsigned int(*)[4])data_v; unsigned int(*dt)[4]; unsigned int i, j; { RNG *rng = BLI_rng_new(1); - for (i = nbr, dt = data; i--; dt++) { + for (i = count, dt = data; i--; dt++) { for (j = 4; j--;) { (*dt)[j] = BLI_rng_get_uint(rng); } @@ -398,10 +398,10 @@ static void int4_ghash_tests(GHash *ghash, const char *id, const unsigned int nb TIMEIT_START(int_v4_insert); #ifdef GHASH_RESERVE - BLI_ghash_reserve(ghash, nbr); + BLI_ghash_reserve(ghash, count); #endif - for (i = nbr, dt = data; i--; dt++) { + for (i = count, dt = data; i--; dt++) { BLI_ghash_insert(ghash, *dt, POINTER_FROM_UINT(i)); } @@ -413,7 +413,7 @@ static void int4_ghash_tests(GHash *ghash, const char *id, const unsigned int nb { TIMEIT_START(int_v4_lookup); - for (i = nbr, dt = data; i--; dt++) { + for (i = count, dt = data; i--; dt++) { void *v = BLI_ghash_lookup(ghash, (void *)(*dt)); EXPECT_EQ(POINTER_AS_UINT(v), i); } @@ -483,25 +483,25 @@ TEST(ghash, Int2NoHash50000000) /* MultiSmall: create and manipulate a lot of very small ghash's * (90% < 10 items, 9% < 100 items, 1% < 1000 items). */ -static void multi_small_ghash_tests_one(GHash *ghash, RNG *rng, const unsigned int nbr) +static void multi_small_ghash_tests_one(GHash *ghash, RNG *rng, const unsigned int count) { - unsigned int *data = (unsigned int *)MEM_mallocN(sizeof(*data) * (size_t)nbr, __func__); + unsigned int *data = (unsigned int *)MEM_mallocN(sizeof(*data) * (size_t)count, __func__); unsigned int *dt; unsigned int i; - for (i = nbr, dt = data; i--; dt++) { + for (i = count, dt = data; i--; dt++) { *dt = BLI_rng_get_uint(rng); } #ifdef GHASH_RESERVE - BLI_ghash_reserve(ghash, nbr); + BLI_ghash_reserve(ghash, count); #endif - for (i = nbr, dt = data; i--; dt++) { + for (i = count, dt = data; i--; dt++) { BLI_ghash_insert(ghash, POINTER_FROM_UINT(*dt), POINTER_FROM_UINT(*dt)); } - for (i = nbr, dt = data; i--; dt++) { + for (i = count, dt = data; i--; dt++) { void *v = BLI_ghash_lookup(ghash, POINTER_FROM_UINT(*dt)); EXPECT_EQ(POINTER_AS_UINT(v), *dt); } @@ -510,7 +510,7 @@ static void multi_small_ghash_tests_one(GHash *ghash, RNG *rng, const unsigned i MEM_freeN(data); } -static void multi_small_ghash_tests(GHash *ghash, const char *id, const unsigned int nbr) +static void multi_small_ghash_tests(GHash *ghash, const char *id, const unsigned int count) { printf("\n========== STARTING %s ==========\n", id); @@ -518,22 +518,22 @@ static void multi_small_ghash_tests(GHash *ghash, const char *id, const unsigned TIMEIT_START(multi_small_ghash); - unsigned int i = nbr; + unsigned int i = count; while (i--) { - const int nbr = 1 + (BLI_rng_get_int(rng) % TESTCASE_SIZE_SMALL) * - (!(i % 100) ? 100 : (!(i % 10) ? 10 : 1)); - multi_small_ghash_tests_one(ghash, rng, nbr); + const int count = 1 + (BLI_rng_get_int(rng) % TESTCASE_SIZE_SMALL) * + (!(i % 100) ? 100 : (!(i % 10) ? 10 : 1)); + multi_small_ghash_tests_one(ghash, rng, count); } TIMEIT_END(multi_small_ghash); TIMEIT_START(multi_small2_ghash); - unsigned int i = nbr; + unsigned int i = count; while (i--) { - const int nbr = 1 + (BLI_rng_get_int(rng) % TESTCASE_SIZE_SMALL) / 2 * - (!(i % 100) ? 100 : (!(i % 10) ? 10 : 1)); - multi_small_ghash_tests_one(ghash, rng, nbr); + const int count = 1 + (BLI_rng_get_int(rng) % TESTCASE_SIZE_SMALL) / 2 * + (!(i % 100) ? 100 : (!(i % 10) ? 10 : 1)); + multi_small_ghash_tests_one(ghash, rng, count); } TIMEIT_END(multi_small2_ghash); diff --git a/source/blender/blenlib/tests/performance/BLI_task_performance_test.cc b/source/blender/blenlib/tests/performance/BLI_task_performance_test.cc index 33a196569e9..98fafe55d69 100644 --- a/source/blender/blenlib/tests/performance/BLI_task_performance_test.cc +++ b/source/blender/blenlib/tests/performance/BLI_task_performance_test.cc @@ -135,17 +135,17 @@ static void task_listbase_test_do(ListBase *list, NUM_RUN_AVERAGED); } -static void task_listbase_test(const char *id, const int nbr, const bool use_threads) +static void task_listbase_test(const char *id, const int count, const bool use_threads) { printf("\n========== STARTING %s ==========\n", id); ListBase list = {nullptr, nullptr}; - LinkData *items_buffer = (LinkData *)MEM_calloc_arrayN(nbr, sizeof(*items_buffer), __func__); + LinkData *items_buffer = (LinkData *)MEM_calloc_arrayN(count, sizeof(*items_buffer), __func__); BLI_threadapi_init(); int num_items = 0; - for (int i = 0; i < nbr; i++) { + for (int i = 0; i < count; i++) { BLI_addtail(&list, &items_buffer[i]); num_items++; } diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c index d71bfd27a7f..2f6bec4061a 100644 --- a/source/blender/blenloader/intern/versioning_300.c +++ b/source/blender/blenloader/intern/versioning_300.c @@ -1571,10 +1571,10 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain) LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { if (md->type == eModifierType_SurfaceDeform) { SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md; - if (smd->num_bind_verts && smd->verts) { - smd->num_mesh_verts = smd->num_bind_verts; + if (smd->bind_verts_num && smd->verts) { + smd->mesh_verts_num = smd->bind_verts_num; - for (unsigned int i = 0; i < smd->num_bind_verts; i++) { + for (unsigned int i = 0; i < smd->bind_verts_num; i++) { smd->verts[i].vertex_idx = i; } } @@ -2417,6 +2417,24 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain) } } } + + /* Change grease pencil smooth iterations to match old results with new algorithm. */ + LISTBASE_FOREACH (Object *, ob, &bmain->objects) { + LISTBASE_FOREACH (GpencilModifierData *, md, &ob->greasepencil_modifiers) { + if (md->type == eGpencilModifierType_Smooth) { + SmoothGpencilModifierData *gpmd = (SmoothGpencilModifierData *)md; + if (gpmd->step == 1 && gpmd->factor <= 0.5f) { + gpmd->factor *= 2.0f; + } + else { + gpmd->step = 1 + (int)(gpmd->factor * max_ff(0.0f, + min_ff(5.1f * sqrtf(gpmd->step) - 3.0f, + gpmd->step + 2.0f))); + gpmd->factor = 1.0f; + } + } + } + } } /* rebuild active/render color attribute references*/ @@ -2496,5 +2514,16 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain) scene->toolsettings->curves_sculpt->curve_length = 0.3f; } } + + for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { + if (sl->spacetype == SPACE_OUTLINER) { + SpaceOutliner *space_outliner = (SpaceOutliner *)sl; + space_outliner->filter &= ~SO_FILTER_CLEARED_1; + } + } + } + } } } diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c index 5b026c1cca0..16297149cc3 100644 --- a/source/blender/blenloader/intern/versioning_legacy.c +++ b/source/blender/blenloader/intern/versioning_legacy.c @@ -2064,8 +2064,8 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) } for (part = bmain->particles.first; part; part = part->id.next) { - if (part->ren_child_nbr == 0) { - part->ren_child_nbr = part->child_nbr; + if (part->child_render_percent == 0) { + part->child_render_percent = part->child_percent; } } diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index 118e7751cbc..40f1d7c496d 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -1096,7 +1096,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh vertMap = bm_to_mesh_vertex_map(bm, ototvert); } - for (i = j = 0; i < hmd->totindex; i++) { + for (i = j = 0; i < hmd->indexar_num; i++) { if (hmd->indexar[i] < ototvert) { eve = vertMap[hmd->indexar[i]]; @@ -1109,7 +1109,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh } } - hmd->totindex = j; + hmd->indexar_num = j; } } } diff --git a/source/blender/bmesh/intern/bmesh_mesh_normals.c b/source/blender/bmesh/intern/bmesh_mesh_normals.c index d61b2c5bb43..cd89a550279 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_normals.c +++ b/source/blender/bmesh/intern/bmesh_mesh_normals.c @@ -580,7 +580,7 @@ static int bm_mesh_loops_calc_normals_for_loop(BMesh *bm, /* We validate clnors data on the fly - cheapest way to do! */ int clnors_avg[2] = {0, 0}; const short(*clnor_ref)[2] = NULL; - int clnors_nbr = 0; + int clnors_count = 0; bool clnors_invalid = false; const float *co_pivot = vcos ? vcos[BM_elem_index_get(v_pivot)] : v_pivot->co; @@ -649,7 +649,7 @@ static int bm_mesh_loops_calc_normals_for_loop(BMesh *bm, const short(*clnor)[2] = clnors_data ? &clnors_data[lfan_pivot_index] : (const void *)BM_ELEM_CD_GET_VOID_P( lfan_pivot, cd_loop_clnors_offset); - if (clnors_nbr) { + if (clnors_count) { clnors_invalid |= ((*clnor_ref)[0] != (*clnor)[0] || (*clnor_ref)[1] != (*clnor)[1]); } else { @@ -657,7 +657,7 @@ static int bm_mesh_loops_calc_normals_for_loop(BMesh *bm, } clnors_avg[0] += (*clnor)[0]; clnors_avg[1] += (*clnor)[1]; - clnors_nbr++; + clnors_count++; /* We store here a pointer to all custom lnors processed. */ BLI_SMALLSTACK_PUSH(clnors, (short *)*clnor); } @@ -706,8 +706,8 @@ static int bm_mesh_loops_calc_normals_for_loop(BMesh *bm, if (clnors_invalid) { short *clnor; - clnors_avg[0] /= clnors_nbr; - clnors_avg[1] /= clnors_nbr; + clnors_avg[0] /= clnors_count; + clnors_avg[1] /= clnors_count; /* Fix/update all clnors of this fan with computed average value. */ /* Prints continuously when merge custom normals, so commenting. */ @@ -1517,7 +1517,7 @@ static void bm_mesh_loops_assign_normal_data(BMesh *bm, BLI_BITMAP_ENABLE(done_loops, i); } else { - int nbr_nors = 0; + int avg_nor_count = 0; float avg_nor[3]; short clnor_data_tmp[2], *clnor_data; @@ -1530,7 +1530,7 @@ static void bm_mesh_loops_assign_normal_data(BMesh *bm, short *clnor = r_clnors_data ? &r_clnors_data[lidx] : BM_ELEM_CD_GET_VOID_P(ml, cd_loop_clnors_offset); - nbr_nors++; + avg_nor_count++; add_v3_v3(avg_nor, nor); BLI_SMALLSTACK_PUSH(clnors_data, clnor); @@ -1538,7 +1538,7 @@ static void bm_mesh_loops_assign_normal_data(BMesh *bm, BLI_BITMAP_ENABLE(done_loops, lidx); } - mul_v3_fl(avg_nor, 1.0f / (float)nbr_nors); + mul_v3_fl(avg_nor, 1.0f / (float)avg_nor_count); BKE_lnor_space_custom_normal_to_data( lnors_spacearr->lspacearr[i], avg_nor, clnor_data_tmp); diff --git a/source/blender/compositor/intern/COM_Debug.cc b/source/blender/compositor/intern/COM_Debug.cc index 0d9d3b111b0..66dbabe71b5 100644 --- a/source/blender/compositor/intern/COM_Debug.cc +++ b/source/blender/compositor/intern/COM_Debug.cc @@ -468,8 +468,8 @@ void DebugInfo::delete_operation_exports() const std::string dir = get_operations_export_dir(); if (BLI_exists(dir.c_str())) { struct direntry *file_list; - int num_files = BLI_filelist_dir_contents(dir.c_str(), &file_list); - for (int i = 0; i < num_files; i++) { + int file_list_num = BLI_filelist_dir_contents(dir.c_str(), &file_list); + for (int i = 0; i < file_list_num; i++) { direntry *file = &file_list[i]; const eFileAttributes file_attrs = BLI_file_attributes(file->path); if (file_attrs & FILE_ATTR_ANY_LINK) { @@ -480,7 +480,7 @@ void DebugInfo::delete_operation_exports() BLI_delete(file->path, false, false); } } - BLI_filelist_free(file_list, num_files); + BLI_filelist_free(file_list, file_list_num); } } diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc index 5788e8efa07..bcde1839a0f 100644 --- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc +++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc @@ -54,7 +54,7 @@ void deg_invalidate_iterator_work_data(DEGObjectIterData *data) { #ifdef INVALIDATE_WORK_DATA BLI_assert(data != nullptr); - memset(&data->temp_dupli_object, 0xff, sizeof(data->temp_dupli_object)); + memset((void *)&data->temp_dupli_object, 0xff, sizeof(data->temp_dupli_object)); #else (void)data; #endif @@ -167,7 +167,7 @@ bool deg_iterator_duplis_step(DEGObjectIterData *data) /* Temporary object to evaluate. */ Object *dupli_parent = data->dupli_parent; Object *temp_dupli_object = &data->temp_dupli_object; - *temp_dupli_object = *dob->ob; + *temp_dupli_object = blender::dna::shallow_copy(*dob->ob); temp_dupli_object->base_flag = dupli_parent->base_flag | BASE_FROM_DUPLI; temp_dupli_object->base_local_view_bits = dupli_parent->base_local_view_bits; temp_dupli_object->runtime.local_collections_bits = diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 5dd26d19e02..2a2335aa44c 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -25,10 +25,10 @@ set(INC ../windowmanager ../../../intern/atomic + ../../../intern/clog ../../../intern/glew-mx ../../../intern/guardedalloc ../../../intern/opensubdiv - ../../../intern/clog # dna_type_offsets.h ${CMAKE_CURRENT_BINARY_DIR}/../makesdna/intern @@ -190,6 +190,7 @@ set(SRC intern/draw_cache_inline.h intern/draw_color_management.h intern/draw_common.h + intern/draw_common_shader_shared.h intern/draw_debug.h intern/draw_hair_private.h intern/draw_instance_data.h @@ -221,9 +222,9 @@ set(SRC engines/image/image_partial_updater.hh engines/image/image_private.hh engines/image/image_shader_params.hh + engines/image/image_space.hh engines/image/image_space_image.hh engines/image/image_space_node.hh - engines/image/image_space.hh engines/image/image_texture_info.hh engines/image/image_usage.hh engines/image/image_wrappers.hh diff --git a/source/blender/draw/engines/eevee/eevee_shadows_cascade.c b/source/blender/draw/engines/eevee/eevee_shadows_cascade.c index 96b0df5b7db..25939926cfa 100644 --- a/source/blender/draw/engines/eevee/eevee_shadows_cascade.c +++ b/source/blender/draw/engines/eevee/eevee_shadows_cascade.c @@ -116,7 +116,7 @@ static void eevee_shadow_cascade_setup(EEVEE_LightsInfo *linfo, EEVEE_ShadowCascade *csm_data = linfo->shadow_cascade_data + (int)shdw_data->type_data_id; EEVEE_ShadowCascadeRender *csm_render = linfo->shadow_cascade_render + (int)shdw_data->type_data_id; - int cascade_nbr = csm_render->cascade_count; + int cascade_count = csm_render->cascade_count; float cascade_fade = csm_render->cascade_fade; float cascade_max_dist = csm_render->cascade_max_dist; float cascade_exponent = csm_render->cascade_exponent; @@ -223,19 +223,19 @@ static void eevee_shadow_cascade_setup(EEVEE_LightsInfo *linfo, float p[4] = {1.0f, 1.0f, csm_end, 1.0f}; /* TODO: we don't need full m4 multiply here */ mul_m4_v4(vp_projmat, p); - splits_end_ndc[cascade_nbr - 1] = p[2]; + splits_end_ndc[cascade_count - 1] = p[2]; if (is_persp) { - splits_end_ndc[cascade_nbr - 1] /= p[3]; + splits_end_ndc[cascade_count - 1] /= p[3]; } } csm_data->split_start[0] = csm_start; - csm_data->split_end[cascade_nbr - 1] = csm_end; + csm_data->split_end[cascade_count - 1] = csm_end; - for (int c = 1; c < cascade_nbr; c++) { + for (int c = 1; c < cascade_count; c++) { /* View Space */ - float linear_split = interpf(csm_end, csm_start, c / (float)cascade_nbr); - float exp_split = csm_start * powf(csm_end / csm_start, c / (float)cascade_nbr); + float linear_split = interpf(csm_end, csm_start, c / (float)cascade_count); + float exp_split = csm_start * powf(csm_end / csm_start, c / (float)cascade_count); if (is_persp) { csm_data->split_start[c] = interpf(exp_split, linear_split, cascade_exponent); @@ -276,13 +276,13 @@ static void eevee_shadow_cascade_setup(EEVEE_LightsInfo *linfo, } /* Set last cascade split fade distance into the first split_start. */ - float prev_split = (cascade_nbr > 1) ? csm_data->split_end[cascade_nbr - 2] : - csm_data->split_start[0]; + float prev_split = (cascade_count > 1) ? csm_data->split_end[cascade_count - 2] : + csm_data->split_start[0]; csm_data->split_start[0] = interpf( - prev_split, csm_data->split_end[cascade_nbr - 1], cascade_fade); + prev_split, csm_data->split_end[cascade_count - 1], cascade_fade); /* For each cascade */ - for (int c = 0; c < cascade_nbr; c++) { + for (int c = 0; c < cascade_count; c++) { float(*projmat)[4] = csm_render->projmat[c]; /* Given 8 frustum corners */ float corners[8][3] = { diff --git a/source/blender/draw/engines/image/image_drawing_mode.hh b/source/blender/draw/engines/image/image_drawing_mode.hh index 46482ab6668..f43bbadfa91 100644 --- a/source/blender/draw/engines/image/image_drawing_mode.hh +++ b/source/blender/draw/engines/image/image_drawing_mode.hh @@ -154,16 +154,15 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD * bug or a feature. For now we just acquire to determine if there is a texture. */ void *lock; ImBuf *tile_buffer = BKE_image_acquire_ibuf(image, &tile_user, &lock); - if (tile_buffer == nullptr) { - continue; + if (tile_buffer != nullptr) { + instance_data.float_buffers.mark_used(tile_buffer); + + DRWShadingGroup *shsub = DRW_shgroup_create_sub(shgrp); + float4 min_max_uv(tile_x, tile_y, tile_x + 1, tile_y + 1); + DRW_shgroup_uniform_vec4_copy(shsub, "min_max_uv", min_max_uv); + DRW_shgroup_call_obmat(shsub, info.batch, image_mat); } - instance_data.float_buffers.mark_used(tile_buffer); BKE_image_release_ibuf(image, tile_buffer, lock); - - DRWShadingGroup *shsub = DRW_shgroup_create_sub(shgrp); - float4 min_max_uv(tile_x, tile_y, tile_x + 1, tile_y + 1); - DRW_shgroup_uniform_vec4_copy(shsub, "min_max_uv", min_max_uv); - DRW_shgroup_call_obmat(shsub, info.batch, image_mat); } } } @@ -387,11 +386,9 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD tile_user.tile = image_tile.get_tile_number(); ImBuf *tile_buffer = BKE_image_acquire_ibuf(image, &tile_user, &lock); - if (tile_buffer == nullptr) { - /* Couldn't load the image buffer of the tile. */ - continue; + if (tile_buffer != nullptr) { + do_full_update_texture_slot(instance_data, info, texture_buffer, *tile_buffer, image_tile); } - do_full_update_texture_slot(instance_data, info, texture_buffer, *tile_buffer, image_tile); BKE_image_release_ibuf(image, tile_buffer, lock); } GPU_texture_update(info.texture, GPU_DATA_FLOAT, texture_buffer.rect_float); diff --git a/source/blender/draw/intern/draw_cache_impl_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc index f772f132b13..a21a6409ca5 100644 --- a/source/blender/draw/intern/draw_cache_impl_curves.cc +++ b/source/blender/draw/intern/draw_cache_impl_curves.cc @@ -138,7 +138,7 @@ static void curves_batch_cache_fill_segments_proc_pos(Curves *curves, Span<float3> positions = geometry.positions(); for (const int i : IndexRange(curve_size)) { - const IndexRange curve_range = geometry.range_for_curve(i); + const IndexRange curve_range = geometry.points_for_curve(i); Span<float3> curve_positions = positions.slice(curve_range); float total_len = 0.0f; @@ -218,8 +218,8 @@ static void curves_batch_cache_fill_strands_data(Curves *curves, const blender::bke::CurvesGeometry &geometry = blender::bke::CurvesGeometry::wrap( curves->geometry); - for (const int i : IndexRange(geometry.curves_size())) { - const IndexRange curve_range = geometry.range_for_curve(i); + for (const int i : IndexRange(geometry.curves_num())) { + const IndexRange curve_range = geometry.points_for_curve(i); *(uint *)GPU_vertbuf_raw_step(data_step) = curve_range.start(); *(ushort *)GPU_vertbuf_raw_step(seg_step) = curve_range.size() - 1; diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c index c7edf003346..462ae6f7cf1 100644 --- a/source/blender/draw/intern/draw_common.c +++ b/source/blender/draw/intern/draw_common.c @@ -184,9 +184,10 @@ void DRW_globals_update(void) gb->pixelFac = *DRW_viewport_pixelsize_get(); - copy_v2_v2(gb->sizeViewport, DRW_viewport_size_get()); - copy_v2_v2(gb->sizeViewportInv, gb->sizeViewport); - invert_v2(gb->sizeViewportInv); + /* Deprecated, use drw_view.viewport_size instead */ + copy_v2_v2(&gb->sizeViewport[0], DRW_viewport_size_get()); + copy_v2_v2(&gb->sizeViewport[2], &gb->sizeViewport[0]); + invert_v2(&gb->sizeViewport[2]); /* Color management. */ { diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h index 53946c0cec5..e2dc91f64be 100644 --- a/source/blender/draw/intern/draw_common.h +++ b/source/blender/draw/intern/draw_common.h @@ -7,6 +7,8 @@ #pragma once +#include "draw_common_shader_shared.h" + struct DRWShadingGroup; struct FluidModifierData; struct GPUMaterial; @@ -16,126 +18,6 @@ struct ParticleSystem; struct RegionView3D; struct ViewLayer; -#define UBO_FIRST_COLOR colorWire -#define UBO_LAST_COLOR colorUVShadow - -/* Used as ubo but colors can be directly referenced as well */ -/* Keep in sync with: common_globals_lib.glsl (globalsBlock) */ -/* NOTE: Also keep all color as vec4 and between #UBO_FIRST_COLOR and #UBO_LAST_COLOR. */ -typedef struct GlobalsUboStorage { - /* UBOs data needs to be 16 byte aligned (size of vec4) */ - float colorWire[4]; - float colorWireEdit[4]; - float colorActive[4]; - float colorSelect[4]; - float colorLibrarySelect[4]; - float colorLibrary[4]; - float colorTransform[4]; - float colorLight[4]; - float colorSpeaker[4]; - float colorCamera[4]; - float colorCameraPath[4]; - float colorEmpty[4]; - float colorVertex[4]; - float colorVertexSelect[4]; - float colorVertexUnreferenced[4]; - float colorVertexMissingData[4]; - float colorEditMeshActive[4]; - float colorEdgeSelect[4]; - float colorEdgeSeam[4]; - float colorEdgeSharp[4]; - float colorEdgeCrease[4]; - float colorEdgeBWeight[4]; - float colorEdgeFaceSelect[4]; - float colorEdgeFreestyle[4]; - float colorFace[4]; - float colorFaceSelect[4]; - float colorFaceFreestyle[4]; - float colorGpencilVertex[4]; - float colorGpencilVertexSelect[4]; - float colorNormal[4]; - float colorVNormal[4]; - float colorLNormal[4]; - float colorFaceDot[4]; - float colorSkinRoot[4]; - - float colorDeselect[4]; - float colorOutline[4]; - float colorLightNoAlpha[4]; - - float colorBackground[4]; - float colorBackgroundGradient[4]; - float colorCheckerPrimary[4]; - float colorCheckerSecondary[4]; - float colorClippingBorder[4]; - float colorEditMeshMiddle[4]; - - float colorHandleFree[4]; - float colorHandleAuto[4]; - float colorHandleVect[4]; - float colorHandleAlign[4]; - float colorHandleAutoclamp[4]; - float colorHandleSelFree[4]; - float colorHandleSelAuto[4]; - float colorHandleSelVect[4]; - float colorHandleSelAlign[4]; - float colorHandleSelAutoclamp[4]; - float colorNurbUline[4]; - float colorNurbVline[4]; - float colorNurbSelUline[4]; - float colorNurbSelVline[4]; - float colorActiveSpline[4]; - - float colorBonePose[4]; - float colorBonePoseActive[4]; - float colorBonePoseActiveUnsel[4]; - float colorBonePoseConstraint[4]; - float colorBonePoseIK[4]; - float colorBonePoseSplineIK[4]; - float colorBonePoseTarget[4]; - float colorBoneSolid[4]; - float colorBoneLocked[4]; - float colorBoneActive[4]; - float colorBoneActiveUnsel[4]; - float colorBoneSelect[4]; - float colorBoneIKLine[4]; - float colorBoneIKLineNoTarget[4]; - float colorBoneIKLineSpline[4]; - - float colorText[4]; - float colorTextHi[4]; - - float colorBundleSolid[4]; - - float colorMballRadius[4]; - float colorMballRadiusSelect[4]; - float colorMballStiffness[4]; - float colorMballStiffnessSelect[4]; - - float colorCurrentFrame[4]; - - float colorGrid[4]; - float colorGridEmphasis[4]; - float colorGridAxisX[4]; - float colorGridAxisY[4]; - float colorGridAxisZ[4]; - - float colorFaceBack[4]; - float colorFaceFront[4]; - - float colorUVShadow[4]; - - /* NOTE: Put all color before #UBO_LAST_COLOR. */ - float screenVecs[2][4]; /* Padded as vec4. */ - float sizeViewport[2], sizeViewportInv[2]; /* Packed as vec4 in GLSL. */ - - /* Pack individual float at the end of the buffer to avoid alignment errors */ - float sizePixel, pixelFac; - float sizeObjectCenter, sizeLightCenter, sizeLightCircle, sizeLightCircleShadow; - float sizeVertex, sizeEdge, sizeEdgeFix, sizeFaceDot; - float sizeChecker; - float sizeVertexGpencil; -} GlobalsUboStorage; /* Keep in sync with globalsBlock in shaders */ BLI_STATIC_ASSERT_ALIGN(GlobalsUboStorage, 16) diff --git a/source/blender/draw/intern/draw_common_shader_shared.h b/source/blender/draw/intern/draw_common_shader_shared.h new file mode 100644 index 00000000000..c83af2eef84 --- /dev/null +++ b/source/blender/draw/intern/draw_common_shader_shared.h @@ -0,0 +1,245 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2022 Blender Foundation. */ + +/** \file + * \ingroup draw + */ + +#ifndef GPU_SHADER +# include "GPU_shader_shared_utils.h" + +typedef struct GlobalsUboStorage GlobalsUboStorage; +#endif + +/* Future Plan: These globals were once shared between multiple overlay engines. But now that they + * have been merged into one engine, there is no reasons to keep these globals out of the overlay + * engine. */ + +#define UBO_FIRST_COLOR colorWire +#define UBO_LAST_COLOR colorUVShadow + +/* Used as ubo but colors can be directly referenced as well */ +/* NOTE: Also keep all color as vec4 and between #UBO_FIRST_COLOR and #UBO_LAST_COLOR. */ +struct GlobalsUboStorage { + /* UBOs data needs to be 16 byte aligned (size of vec4) */ + float4 colorWire; + float4 colorWireEdit; + float4 colorActive; + float4 colorSelect; + float4 colorLibrarySelect; + float4 colorLibrary; + float4 colorTransform; + float4 colorLight; + float4 colorSpeaker; + float4 colorCamera; + float4 colorCameraPath; + float4 colorEmpty; + float4 colorVertex; + float4 colorVertexSelect; + float4 colorVertexUnreferenced; + float4 colorVertexMissingData; + float4 colorEditMeshActive; + float4 colorEdgeSelect; + float4 colorEdgeSeam; + float4 colorEdgeSharp; + float4 colorEdgeCrease; + float4 colorEdgeBWeight; + float4 colorEdgeFaceSelect; + float4 colorEdgeFreestyle; + float4 colorFace; + float4 colorFaceSelect; + float4 colorFaceFreestyle; + float4 colorGpencilVertex; + float4 colorGpencilVertexSelect; + float4 colorNormal; + float4 colorVNormal; + float4 colorLNormal; + float4 colorFaceDot; + float4 colorSkinRoot; + + float4 colorDeselect; + float4 colorOutline; + float4 colorLightNoAlpha; + + float4 colorBackground; + float4 colorBackgroundGradient; + float4 colorCheckerPrimary; + float4 colorCheckerSecondary; + float4 colorClippingBorder; + float4 colorEditMeshMiddle; + + float4 colorHandleFree; + float4 colorHandleAuto; + float4 colorHandleVect; + float4 colorHandleAlign; + float4 colorHandleAutoclamp; + float4 colorHandleSelFree; + float4 colorHandleSelAuto; + float4 colorHandleSelVect; + float4 colorHandleSelAlign; + float4 colorHandleSelAutoclamp; + float4 colorNurbUline; + float4 colorNurbVline; + float4 colorNurbSelUline; + float4 colorNurbSelVline; + float4 colorActiveSpline; + + float4 colorBonePose; + float4 colorBonePoseActive; + float4 colorBonePoseActiveUnsel; + float4 colorBonePoseConstraint; + float4 colorBonePoseIK; + float4 colorBonePoseSplineIK; + float4 colorBonePoseTarget; + float4 colorBoneSolid; + float4 colorBoneLocked; + float4 colorBoneActive; + float4 colorBoneActiveUnsel; + float4 colorBoneSelect; + float4 colorBoneIKLine; + float4 colorBoneIKLineNoTarget; + float4 colorBoneIKLineSpline; + + float4 colorText; + float4 colorTextHi; + + float4 colorBundleSolid; + + float4 colorMballRadius; + float4 colorMballRadiusSelect; + float4 colorMballStiffness; + float4 colorMballStiffnessSelect; + + float4 colorCurrentFrame; + + float4 colorGrid; + float4 colorGridEmphasis; + float4 colorGridAxisX; + float4 colorGridAxisY; + float4 colorGridAxisZ; + + float4 colorFaceBack; + float4 colorFaceFront; + + float4 colorUVShadow; + + /* NOTE: Put all color before #UBO_LAST_COLOR. */ + float4 screenVecs[2]; /* Padded as vec4. */ + float4 sizeViewport; /* Packed as vec4. */ + + /* Pack individual float at the end of the buffer to avoid alignment errors */ + float sizePixel, pixelFac; + float sizeObjectCenter, sizeLightCenter, sizeLightCircle, sizeLightCircleShadow; + float sizeVertex, sizeEdge, sizeEdgeFix, sizeFaceDot; + float sizeChecker; + float sizeVertexGpencil; +}; +BLI_STATIC_ASSERT_ALIGN(GlobalsUboStorage, 16) + +#ifdef GPU_SHADER +/* Keep compatibility_with old global scope syntax. */ +/* TODO(@fclem) Mass rename and remove the camel case. */ +# define colorWire drw_globals.colorWire +# define colorWireEdit drw_globals.colorWireEdit +# define colorActive drw_globals.colorActive +# define colorSelect drw_globals.colorSelect +# define colorLibrarySelect drw_globals.colorLibrarySelect +# define colorLibrary drw_globals.colorLibrary +# define colorTransform drw_globals.colorTransform +# define colorLight drw_globals.colorLight +# define colorSpeaker drw_globals.colorSpeaker +# define colorCamera drw_globals.colorCamera +# define colorCameraPath drw_globals.colorCameraPath +# define colorEmpty drw_globals.colorEmpty +# define colorVertex drw_globals.colorVertex +# define colorVertexSelect drw_globals.colorVertexSelect +# define colorVertexUnreferenced drw_globals.colorVertexUnreferenced +# define colorVertexMissingData drw_globals.colorVertexMissingData +# define colorEditMeshActive drw_globals.colorEditMeshActive +# define colorEdgeSelect drw_globals.colorEdgeSelect +# define colorEdgeSeam drw_globals.colorEdgeSeam +# define colorEdgeSharp drw_globals.colorEdgeSharp +# define colorEdgeCrease drw_globals.colorEdgeCrease +# define colorEdgeBWeight drw_globals.colorEdgeBWeight +# define colorEdgeFaceSelect drw_globals.colorEdgeFaceSelect +# define colorEdgeFreestyle drw_globals.colorEdgeFreestyle +# define colorFace drw_globals.colorFace +# define colorFaceSelect drw_globals.colorFaceSelect +# define colorFaceFreestyle drw_globals.colorFaceFreestyle +# define colorGpencilVertex drw_globals.colorGpencilVertex +# define colorGpencilVertexSelect drw_globals.colorGpencilVertexSelect +# define colorNormal drw_globals.colorNormal +# define colorVNormal drw_globals.colorVNormal +# define colorLNormal drw_globals.colorLNormal +# define colorFaceDot drw_globals.colorFaceDot +# define colorSkinRoot drw_globals.colorSkinRoot +# define colorDeselect drw_globals.colorDeselect +# define colorOutline drw_globals.colorOutline +# define colorLightNoAlpha drw_globals.colorLightNoAlpha +# define colorBackground drw_globals.colorBackground +# define colorBackgroundGradient drw_globals.colorBackgroundGradient +# define colorCheckerPrimary drw_globals.colorCheckerPrimary +# define colorCheckerSecondary drw_globals.colorCheckerSecondary +# define colorClippingBorder drw_globals.colorClippingBorder +# define colorEditMeshMiddle drw_globals.colorEditMeshMiddle +# define colorHandleFree drw_globals.colorHandleFree +# define colorHandleAuto drw_globals.colorHandleAuto +# define colorHandleVect drw_globals.colorHandleVect +# define colorHandleAlign drw_globals.colorHandleAlign +# define colorHandleAutoclamp drw_globals.colorHandleAutoclamp +# define colorHandleSelFree drw_globals.colorHandleSelFree +# define colorHandleSelAuto drw_globals.colorHandleSelAuto +# define colorHandleSelVect drw_globals.colorHandleSelVect +# define colorHandleSelAlign drw_globals.colorHandleSelAlign +# define colorHandleSelAutoclamp drw_globals.colorHandleSelAutoclamp +# define colorNurbUline drw_globals.colorNurbUline +# define colorNurbVline drw_globals.colorNurbVline +# define colorNurbSelUline drw_globals.colorNurbSelUline +# define colorNurbSelVline drw_globals.colorNurbSelVline +# define colorActiveSpline drw_globals.colorActiveSpline +# define colorBonePose drw_globals.colorBonePose +# define colorBonePoseActive drw_globals.colorBonePoseActive +# define colorBonePoseActiveUnsel drw_globals.colorBonePoseActiveUnsel +# define colorBonePoseConstraint drw_globals.colorBonePoseConstraint +# define colorBonePoseIK drw_globals.colorBonePoseIK +# define colorBonePoseSplineIK drw_globals.colorBonePoseSplineIK +# define colorBonePoseTarget drw_globals.colorBonePoseTarget +# define colorBoneSolid drw_globals.colorBoneSolid +# define colorBoneLocked drw_globals.colorBoneLocked +# define colorBoneActive drw_globals.colorBoneActive +# define colorBoneActiveUnsel drw_globals.colorBoneActiveUnsel +# define colorBoneSelect drw_globals.colorBoneSelect +# define colorBoneIKLine drw_globals.colorBoneIKLine +# define colorBoneIKLineNoTarget drw_globals.colorBoneIKLineNoTarget +# define colorBoneIKLineSpline drw_globals.colorBoneIKLineSpline +# define colorText drw_globals.colorText +# define colorTextHi drw_globals.colorTextHi +# define colorBundleSolid drw_globals.colorBundleSolid +# define colorMballRadius drw_globals.colorMballRadius +# define colorMballRadiusSelect drw_globals.colorMballRadiusSelect +# define colorMballStiffness drw_globals.colorMballStiffness +# define colorMballStiffnessSelect drw_globals.colorMballStiffnessSelect +# define colorCurrentFrame drw_globals.colorCurrentFrame +# define colorGrid drw_globals.colorGrid +# define colorGridEmphasis drw_globals.colorGridEmphasis +# define colorGridAxisX drw_globals.colorGridAxisX +# define colorGridAxisY drw_globals.colorGridAxisY +# define colorGridAxisZ drw_globals.colorGridAxisZ +# define colorFaceBack drw_globals.colorFaceBack +# define colorFaceFront drw_globals.colorFaceFront +# define colorUVShadow drw_globals.colorUVShadow +# define screenVecs drw_globals.screenVecs +# define sizeViewport drw_globals.sizeViewport +# define sizePixel drw_globals.sizePixel +# define pixelFac drw_globals.pixelFac +# define sizeObjectCenter drw_globals.sizeObjectCenter +# define sizeLightCenter drw_globals.sizeLightCenter +# define sizeLightCircle drw_globals.sizeLightCircle +# define sizeLightCircleShadow drw_globals.sizeLightCircleShadow +# define sizeVertex drw_globals.sizeVertex +# define sizeEdge drw_globals.sizeEdge +# define sizeEdgeFix drw_globals.sizeEdgeFix +# define sizeFaceDot drw_globals.sizeFaceDot +# define sizeChecker drw_globals.sizeChecker +# define sizeVertexGpencil drw_globals.sizeVertexGpencil +#endif diff --git a/source/blender/draw/intern/draw_shader_shared.h b/source/blender/draw/intern/draw_shader_shared.h index 7c71ae9e21f..5fc76bc25e6 100644 --- a/source/blender/draw/intern/draw_shader_shared.h +++ b/source/blender/draw/intern/draw_shader_shared.h @@ -30,7 +30,7 @@ struct ViewInfos { float2 viewport_size_inverse; /** Frustum culling data. */ - /** NOTE: vec3 arrays are paded to vec4. */ + /** NOTE: vec3 arrays are padded to vec4. */ float4 frustum_corners[8]; float4 frustum_planes[6]; }; diff --git a/source/blender/draw/intern/draw_view_data.cc b/source/blender/draw/intern/draw_view_data.cc index 682728eb22b..0e55d28f6df 100644 --- a/source/blender/draw/intern/draw_view_data.cc +++ b/source/blender/draw/intern/draw_view_data.cc @@ -37,7 +37,10 @@ struct DRWViewData { DRWViewData *DRW_view_data_create(ListBase *engine_types) { + const int engine_types_len = BLI_listbase_count(engine_types); + DRWViewData *view_data = new DRWViewData(); + view_data->engines.reserve(engine_types_len); LISTBASE_FOREACH (DRWRegisteredDrawEngine *, type, engine_types) { ViewportEngineData engine = {}; engine.engine_type = type; diff --git a/source/blender/draw/intern/shaders/draw_view_info.hh b/source/blender/draw/intern/shaders/draw_view_info.hh index a699b9013ef..ba43938cbc0 100644 --- a/source/blender/draw/intern/shaders/draw_view_info.hh +++ b/source/blender/draw/intern/shaders/draw_view_info.hh @@ -75,6 +75,16 @@ GPU_SHADER_CREATE_INFO(drw_clipped).define("USE_WORLD_CLIP_PLANES"); /** \} */ /* -------------------------------------------------------------------- */ +/** \name Draw Globals + * \{ */ + +GPU_SHADER_CREATE_INFO(draw_globals) + .typedef_source("draw_common_shader_shared.h") + .uniform_buf(1, "ObjectMatrices", "drw_globals", Frequency::PASS); + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Geometry Type * \{ */ diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c index f18873cc22b..ed40845a47c 100644 --- a/source/blender/editors/animation/keyframes_edit.c +++ b/source/blender/editors/animation/keyframes_edit.c @@ -1292,8 +1292,8 @@ void ANIM_fcurve_equalize_keyframes_loop(FCurve *fcu, { uint i; BezTriple *bezt; - const float flat_direction_left[2] = {-handle_length, 0.f}; - const float flat_direction_right[2] = {handle_length, 0.f}; + const float flat_direction_left[2] = {-handle_length, 0.0f}; + const float flat_direction_right[2] = {handle_length, 0.0f}; /* Loop through an F-Curves keyframes. */ for (bezt = fcu->bezt, i = 0; i < fcu->totvert; bezt++, i++) { diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 31caa29a02a..7016511111e 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -59,7 +59,7 @@ static void error(const char *str) struct LaplacianSystem { LinearSolver *context; /* linear solver */ - int totvert, totface; + int verts_num, faces_num; float **verts; /* vertex coordinates */ float *varea; /* vertex weights for laplacian computation */ @@ -76,8 +76,8 @@ struct LaplacianSystem { struct HeatWeighting { const MLoopTri *mlooptri; const MLoop *mloop; /* needed to find vertices by index */ - int totvert; - int tottri; + int verts_num; + int tris_num; float (*verts)[3]; /* vertex coordinates */ float (*vnors)[3]; /* vertex normals */ @@ -202,28 +202,28 @@ static void laplacian_triangle_weights(LaplacianSystem *sys, int f, int i1, int } } -static LaplacianSystem *laplacian_system_construct_begin(int totvert, int totface, int lsq) +static LaplacianSystem *laplacian_system_construct_begin(int verts_num, int faces_num, int lsq) { LaplacianSystem *sys; sys = MEM_callocN(sizeof(LaplacianSystem), "LaplacianSystem"); - sys->verts = MEM_callocN(sizeof(float *) * totvert, "LaplacianSystemVerts"); - sys->vpinned = MEM_callocN(sizeof(char) * totvert, "LaplacianSystemVpinned"); - sys->faces = MEM_callocN(sizeof(int[3]) * totface, "LaplacianSystemFaces"); + sys->verts = MEM_callocN(sizeof(float *) * verts_num, "LaplacianSystemVerts"); + sys->vpinned = MEM_callocN(sizeof(char) * verts_num, "LaplacianSystemVpinned"); + sys->faces = MEM_callocN(sizeof(int[3]) * faces_num, "LaplacianSystemFaces"); - sys->totvert = 0; - sys->totface = 0; + sys->verts_num = 0; + sys->faces_num = 0; sys->areaweights = 1; sys->storeweights = 0; /* create linear solver */ if (lsq) { - sys->context = EIG_linear_least_squares_solver_new(0, totvert, 1); + sys->context = EIG_linear_least_squares_solver_new(0, verts_num, 1); } else { - sys->context = EIG_linear_solver_new(0, totvert, 1); + sys->context = EIG_linear_solver_new(0, verts_num, 1); } return sys; @@ -231,42 +231,43 @@ static LaplacianSystem *laplacian_system_construct_begin(int totvert, int totfac void laplacian_add_vertex(LaplacianSystem *sys, float *co, int pinned) { - sys->verts[sys->totvert] = co; - sys->vpinned[sys->totvert] = pinned; - sys->totvert++; + sys->verts[sys->verts_num] = co; + sys->vpinned[sys->verts_num] = pinned; + sys->verts_num++; } void laplacian_add_triangle(LaplacianSystem *sys, int v1, int v2, int v3) { - sys->faces[sys->totface][0] = v1; - sys->faces[sys->totface][1] = v2; - sys->faces[sys->totface][2] = v3; - sys->totface++; + sys->faces[sys->faces_num][0] = v1; + sys->faces[sys->faces_num][1] = v2; + sys->faces[sys->faces_num][2] = v3; + sys->faces_num++; } static void laplacian_system_construct_end(LaplacianSystem *sys) { int(*face)[3]; - int a, totvert = sys->totvert, totface = sys->totface; + int a, verts_num = sys->verts_num, faces_num = sys->faces_num; laplacian_begin_solve(sys, 0); - sys->varea = MEM_callocN(sizeof(float) * totvert, "LaplacianSystemVarea"); + sys->varea = MEM_callocN(sizeof(float) * verts_num, "LaplacianSystemVarea"); - sys->edgehash = BLI_edgehash_new_ex(__func__, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(sys->totface)); - for (a = 0, face = sys->faces; a < sys->totface; a++, face++) { + sys->edgehash = BLI_edgehash_new_ex(__func__, + BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(sys->faces_num)); + for (a = 0, face = sys->faces; a < sys->faces_num; a++, face++) { laplacian_increase_edge_count(sys->edgehash, (*face)[0], (*face)[1]); laplacian_increase_edge_count(sys->edgehash, (*face)[1], (*face)[2]); laplacian_increase_edge_count(sys->edgehash, (*face)[2], (*face)[0]); } if (sys->areaweights) { - for (a = 0, face = sys->faces; a < sys->totface; a++, face++) { + for (a = 0, face = sys->faces; a < sys->faces_num; a++, face++) { laplacian_triangle_area(sys, (*face)[0], (*face)[1], (*face)[2]); } } - for (a = 0; a < totvert; a++) { + for (a = 0; a < verts_num; a++) { if (sys->areaweights) { if (sys->varea[a] != 0.0f) { sys->varea[a] = 0.5f / sys->varea[a]; @@ -283,10 +284,10 @@ static void laplacian_system_construct_end(LaplacianSystem *sys) } if (sys->storeweights) { - sys->fweights = MEM_callocN(sizeof(float[3]) * totface, "LaplacianFWeight"); + sys->fweights = MEM_callocN(sizeof(float[3]) * faces_num, "LaplacianFWeight"); } - for (a = 0, face = sys->faces; a < totface; a++, face++) { + for (a = 0, face = sys->faces; a < faces_num; a++, face++) { laplacian_triangle_weights(sys, a, (*face)[0], (*face)[1], (*face)[2]); } @@ -327,7 +328,7 @@ void laplacian_begin_solve(LaplacianSystem *sys, int index) if (!sys->variablesdone) { if (index >= 0) { - for (a = 0; a < sys->totvert; a++) { + for (a = 0; a < sys->verts_num; a++) { if (sys->vpinned[a]) { EIG_linear_solver_variable_set(sys->context, 0, a, sys->verts[a][index]); EIG_linear_solver_variable_lock(sys->context, a); @@ -411,14 +412,14 @@ static void heat_ray_tree_create(LaplacianSystem *sys) const MLoopTri *looptri = sys->heat.mlooptri; const MLoop *mloop = sys->heat.mloop; float(*verts)[3] = sys->heat.verts; - int tottri = sys->heat.tottri; - int totvert = sys->heat.totvert; + int tris_num = sys->heat.tris_num; + int verts_num = sys->heat.verts_num; int a; - sys->heat.bvhtree = BLI_bvhtree_new(tottri, 0.0f, 4, 6); - sys->heat.vltree = MEM_callocN(sizeof(MLoopTri *) * totvert, "HeatVFaces"); + sys->heat.bvhtree = BLI_bvhtree_new(tris_num, 0.0f, 4, 6); + sys->heat.vltree = MEM_callocN(sizeof(MLoopTri *) * verts_num, "HeatVFaces"); - for (a = 0; a < tottri; a++) { + for (a = 0; a < tris_num; a++) { const MLoopTri *lt = &looptri[a]; float bb[6]; int vtri[3]; @@ -552,9 +553,9 @@ static void heat_calc_vnormals(LaplacianSystem *sys) float fnor[3]; int a, v1, v2, v3, (*face)[3]; - sys->heat.vnors = MEM_callocN(sizeof(float[3]) * sys->totvert, "HeatVNors"); + sys->heat.vnors = MEM_callocN(sizeof(float[3]) * sys->verts_num, "HeatVNors"); - for (a = 0, face = sys->faces; a < sys->totface; a++, face++) { + for (a = 0, face = sys->faces; a < sys->faces_num; a++, face++) { v1 = (*face)[0]; v2 = (*face)[1]; v3 = (*face)[2]; @@ -566,7 +567,7 @@ static void heat_calc_vnormals(LaplacianSystem *sys) add_v3_v3(sys->heat.vnors[v3], fnor); } - for (a = 0; a < sys->totvert; a++) { + for (a = 0; a < sys->verts_num; a++) { normalize_v3(sys->heat.vnors[a]); } } @@ -575,21 +576,21 @@ static void heat_laplacian_create(LaplacianSystem *sys) { const MLoopTri *mlooptri = sys->heat.mlooptri, *lt; const MLoop *mloop = sys->heat.mloop; - int tottri = sys->heat.tottri; - int totvert = sys->heat.totvert; + int tris_num = sys->heat.tris_num; + int verts_num = sys->heat.verts_num; int a; /* heat specific definitions */ - sys->heat.mindist = MEM_callocN(sizeof(float) * totvert, "HeatMinDist"); - sys->heat.H = MEM_callocN(sizeof(float) * totvert, "HeatH"); - sys->heat.p = MEM_callocN(sizeof(float) * totvert, "HeatP"); + sys->heat.mindist = MEM_callocN(sizeof(float) * verts_num, "HeatMinDist"); + sys->heat.H = MEM_callocN(sizeof(float) * verts_num, "HeatH"); + sys->heat.p = MEM_callocN(sizeof(float) * verts_num, "HeatP"); /* add verts and faces to laplacian */ - for (a = 0; a < totvert; a++) { + for (a = 0; a < verts_num; a++) { laplacian_add_vertex(sys, sys->heat.verts[a], 0); } - for (a = 0, lt = mlooptri; a < tottri; a++, lt++) { + for (a = 0, lt = mlooptri; a < tris_num; a++, lt++) { int vtri[3]; vtri[0] = mloop[lt->tri[0]].v; vtri[1] = mloop[lt->tri[1]].v; @@ -600,7 +601,7 @@ static void heat_laplacian_create(LaplacianSystem *sys) /* for distance computation in set_H */ heat_calc_vnormals(sys); - for (a = 0; a < totvert; a++) { + for (a = 0; a < verts_num; a++) { heat_set_H(sys, a); } } @@ -648,7 +649,7 @@ void heat_bone_weighting(Object *ob, MLoop *ml; float solution, weight; int *vertsflipped = NULL, *mask = NULL; - int a, tottri, j, bbone, firstsegment, lastsegment; + int a, tris_num, j, bbone, firstsegment, lastsegment; bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0; MVert *mvert = me->mvert; @@ -658,7 +659,7 @@ void heat_bone_weighting(Object *ob, *error_str = NULL; /* bone heat needs triangulated faces */ - tottri = poly_to_tri_count(me->totpoly, me->totloop); + tris_num = poly_to_tri_count(me->totpoly, me->totloop); /* count triangles and create mask */ if (ob->mode & OB_MODE_WEIGHT_PAINT && (use_face_sel || use_vert_sel)) { @@ -684,16 +685,16 @@ void heat_bone_weighting(Object *ob, } /* create laplacian */ - sys = laplacian_system_construct_begin(me->totvert, tottri, 1); + sys = laplacian_system_construct_begin(me->totvert, tris_num, 1); - sys->heat.tottri = poly_to_tri_count(me->totpoly, me->totloop); - mlooptri = MEM_mallocN(sizeof(*sys->heat.mlooptri) * sys->heat.tottri, __func__); + sys->heat.tris_num = poly_to_tri_count(me->totpoly, me->totloop); + mlooptri = MEM_mallocN(sizeof(*sys->heat.mlooptri) * sys->heat.tris_num, __func__); BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, mlooptri); sys->heat.mlooptri = mlooptri; sys->heat.mloop = me->mloop; - sys->heat.totvert = me->totvert; + sys->heat.verts_num = me->totvert; sys->heat.verts = verts; sys->heat.root = root; sys->heat.tip = tip; @@ -886,7 +887,7 @@ typedef struct MeshDeformBind { Mesh *cagemesh; float (*cagecos)[3]; float (*vertexcos)[3]; - int totvert, totcagevert; + int verts_num, cage_verts_num; /* grids */ MemArena *memarena; @@ -1467,7 +1468,7 @@ static void meshdeform_matrix_solve(MeshDeformModifierData *mmd, MeshDeformBind } /* solve for each cage vert */ - for (a = 0; a < mdb->totcagevert; a++) { + for (a = 0; a < mdb->cage_verts_num; a++) { /* fill in right hand side and solve */ for (z = 0; z < mdb->size; z++) { for (y = 0; y < mdb->size; y++) { @@ -1503,14 +1504,14 @@ static void meshdeform_matrix_solve(MeshDeformModifierData *mmd, MeshDeformBind if (mdb->weights) { /* static bind : compute weights for each vertex */ - for (b = 0; b < mdb->totvert; b++) { + for (b = 0; b < mdb->verts_num; b++) { if (mdb->inside[b]) { copy_v3_v3(vec, mdb->vertexcos[b]); gridvec[0] = (vec[0] - mdb->min[0] - mdb->halfwidth[0]) / mdb->width[0]; gridvec[1] = (vec[1] - mdb->min[1] - mdb->halfwidth[1]) / mdb->width[1]; gridvec[2] = (vec[2] - mdb->min[2] - mdb->halfwidth[2]) / mdb->width[2]; - mdb->weights[b * mdb->totcagevert + a] = meshdeform_interp_w(mdb, gridvec, vec, a); + mdb->weights[b * mdb->cage_verts_num + a] = meshdeform_interp_w(mdb, gridvec, vec, a); } } } @@ -1536,9 +1537,12 @@ static void meshdeform_matrix_solve(MeshDeformModifierData *mmd, MeshDeformBind break; } - BLI_snprintf( - message, sizeof(message), "Mesh deform solve %d / %d |||", a + 1, mdb->totcagevert); - progress_bar((float)(a + 1) / (float)(mdb->totcagevert), message); + BLI_snprintf(message, + sizeof(message), + "Mesh deform solve %d / %d |||", + a + 1, + mdb->cage_verts_num); + progress_bar((float)(a + 1) / (float)(mdb->cage_verts_num), message); } #if 0 @@ -1573,7 +1577,7 @@ static void harmonic_coordinates_bind(MeshDeformModifierData *mmd, MeshDeformBin /* compute bounding box of the cage mesh */ INIT_MINMAX(mdb->min, mdb->max); - for (a = 0; a < mdb->totcagevert; a++) { + for (a = 0; a < mdb->cage_verts_num; a++) { minmax_v3v3_v3(mdb->min, mdb->max, mdb->cagecos[a]); } @@ -1586,13 +1590,14 @@ static void harmonic_coordinates_bind(MeshDeformModifierData *mmd, MeshDeformBin mdb->boundisect = MEM_callocN(sizeof(*mdb->boundisect) * mdb->size3, "MDefBoundIsect"); mdb->semibound = MEM_callocN(sizeof(int) * mdb->size3, "MDefSemiBound"); mdb->bvhtree = BKE_bvhtree_from_mesh_get(&mdb->bvhdata, mdb->cagemesh, BVHTREE_FROM_LOOPTRI, 4); - mdb->inside = MEM_callocN(sizeof(int) * mdb->totvert, "MDefInside"); + mdb->inside = MEM_callocN(sizeof(int) * mdb->verts_num, "MDefInside"); if (mmd->flag & MOD_MDEF_DYNAMIC_BIND) { mdb->dyngrid = MEM_callocN(sizeof(MDefBindInfluence *) * mdb->size3, "MDefDynGrid"); } else { - mdb->weights = MEM_callocN(sizeof(float) * mdb->totvert * mdb->totcagevert, "MDefWeights"); + mdb->weights = MEM_callocN(sizeof(float) * mdb->verts_num * mdb->cage_verts_num, + "MDefWeights"); } mdb->memarena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "harmonic coords arena"); @@ -1632,7 +1637,7 @@ static void harmonic_coordinates_bind(MeshDeformModifierData *mmd, MeshDeformBin progress_bar(0, "Setting up mesh deform system"); totinside = 0; - for (a = 0; a < mdb->totvert; a++) { + for (a = 0; a < mdb->verts_num; a++) { copy_v3_v3(vec, mdb->vertexcos[a]); mdb->inside[a] = meshdeform_inside_cage(mdb, vec); if (mdb->inside[a]) { @@ -1674,16 +1679,16 @@ static void harmonic_coordinates_bind(MeshDeformModifierData *mmd, MeshDeformBin /* assign results */ if (mmd->flag & MOD_MDEF_DYNAMIC_BIND) { - mmd->totinfluence = 0; + mmd->influences_num = 0; for (a = 0; a < mdb->size3; a++) { for (inf = mdb->dyngrid[a]; inf; inf = inf->next) { - mmd->totinfluence++; + mmd->influences_num++; } } /* convert MDefBindInfluences to smaller MDefInfluences */ mmd->dyngrid = MEM_callocN(sizeof(MDefCell) * mdb->size3, "MDefDynGrid"); - mmd->dyninfluences = MEM_callocN(sizeof(MDefInfluence) * mmd->totinfluence, "MDefInfluence"); + mmd->dyninfluences = MEM_callocN(sizeof(MDefInfluence) * mmd->influences_num, "MDefInfluence"); offset = 0; for (a = 0; a < mdb->size3; a++) { cell = &mmd->dyngrid[a]; @@ -1695,17 +1700,17 @@ static void harmonic_coordinates_bind(MeshDeformModifierData *mmd, MeshDeformBin mdinf->weight = inf->weight; mdinf->vertex = inf->vertex; totweight += mdinf->weight; - cell->totinfluence++; + cell->influences_num++; } if (totweight > 0.0f) { mdinf = mmd->dyninfluences + cell->offset; - for (b = 0; b < cell->totinfluence; b++, mdinf++) { + for (b = 0; b < cell->influences_num; b++, mdinf++) { mdinf->weight /= totweight; } } - offset += cell->totinfluence; + offset += cell->influences_num; } mmd->dynverts = mdb->inside; @@ -1732,7 +1737,7 @@ void ED_mesh_deform_bind_callback(Object *object, MeshDeformModifierData *mmd, Mesh *cagemesh, float *vertexcos, - int totvert, + int verts_num, float cagemat[4][4]) { MeshDeformModifierData *mmd_orig = (MeshDeformModifierData *)BKE_modifier_get_original( @@ -1750,19 +1755,19 @@ void ED_mesh_deform_bind_callback(Object *object, BKE_mesh_wrapper_ensure_mdata(cagemesh); /* get mesh and cage mesh */ - mdb.vertexcos = MEM_callocN(sizeof(float[3]) * totvert, "MeshDeformCos"); - mdb.totvert = totvert; + mdb.vertexcos = MEM_callocN(sizeof(float[3]) * verts_num, "MeshDeformCos"); + mdb.verts_num = verts_num; mdb.cagemesh = cagemesh; - mdb.totcagevert = mdb.cagemesh->totvert; - mdb.cagecos = MEM_callocN(sizeof(*mdb.cagecos) * mdb.totcagevert, "MeshDeformBindCos"); + mdb.cage_verts_num = mdb.cagemesh->totvert; + mdb.cagecos = MEM_callocN(sizeof(*mdb.cagecos) * mdb.cage_verts_num, "MeshDeformBindCos"); copy_m4_m4(mdb.cagemat, cagemat); mvert = mdb.cagemesh->mvert; - for (a = 0; a < mdb.totcagevert; a++) { + for (a = 0; a < mdb.cage_verts_num; a++) { copy_v3_v3(mdb.cagecos[a], mvert[a].co); } - for (a = 0; a < mdb.totvert; a++) { + for (a = 0; a < mdb.verts_num; a++) { mul_v3_m4v3(mdb.vertexcos[a], mdb.cagemat, vertexcos + a * 3); } @@ -1771,12 +1776,12 @@ void ED_mesh_deform_bind_callback(Object *object, /* assign bind variables */ mmd_orig->bindcagecos = (float *)mdb.cagecos; - mmd_orig->totvert = mdb.totvert; - mmd_orig->totcagevert = mdb.totcagevert; + mmd_orig->verts_num = mdb.verts_num; + mmd_orig->cage_verts_num = mdb.cage_verts_num; copy_m4_m4(mmd_orig->bindmat, mmd_orig->object->obmat); /* transform bindcagecos to world space */ - for (a = 0; a < mdb.totcagevert; a++) { + for (a = 0; a < mdb.cage_verts_num; a++) { mul_m4_v3(mmd_orig->object->obmat, mmd_orig->bindcagecos + a * 3); } diff --git a/source/blender/editors/asset/intern/asset_indexer.cc b/source/blender/editors/asset/intern/asset_indexer.cc index 49c4002eee8..3cc3638c299 100644 --- a/source/blender/editors/asset/intern/asset_indexer.cc +++ b/source/blender/editors/asset/intern/asset_indexer.cc @@ -39,7 +39,6 @@ using namespace blender::bke; using namespace blender::bke::idprop; /** - * \file asset_indexer.cc * \brief Indexer for asset libraries. * * Indexes are stored per input file. Each index can contain zero to multiple asset entries. @@ -494,15 +493,15 @@ struct AssetLibraryIndex { return; } struct direntry *dir_entries = nullptr; - int num_entries = BLI_filelist_dir_contents(index_path, &dir_entries); - for (int i = 0; i < num_entries; i++) { + const int dir_entries_num = BLI_filelist_dir_contents(index_path, &dir_entries); + for (int i = 0; i < dir_entries_num; i++) { struct direntry *entry = &dir_entries[i]; if (BLI_str_endswith(entry->relname, ".index.json")) { unused_file_indices.add_as(std::string(entry->path)); } } - BLI_filelist_free(dir_entries, num_entries); + BLI_filelist_free(dir_entries, dir_entries_num); } void mark_as_used(const std::string &filename) diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 5ff63e767f6..38c14391273 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -1209,7 +1209,7 @@ static void remap_hooks_and_vertex_parents(Main *bmain, Object *obedit) old_to_new_map = init_index_map(obedit, &old_totvert); } - for (i = j = 0; i < hmd->totindex; i++) { + for (i = j = 0; i < hmd->indexar_num; i++) { if (hmd->indexar[i] < old_totvert) { index = old_to_new_map[hmd->indexar[i]]; if (index != -1) { @@ -1221,7 +1221,7 @@ static void remap_hooks_and_vertex_parents(Main *bmain, Object *obedit) } } - hmd->totindex = j; + hmd->indexar_num = j; } } } diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index 0afb1c2f4af..611dbb2e80c 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -526,16 +526,16 @@ static bool font_paste_utf8(bContext *C, const char *str, const size_t str_len) /** \name Paste From File Operator * \{ */ -static int paste_from_file(bContext *C, ReportList *reports, const char *filename) +static int paste_from_file(bContext *C, ReportList *reports, const char *filepath) { Object *obedit = CTX_data_edit_object(C); char *strp; size_t filelen; int retval; - strp = BLI_file_read_text_as_mem(filename, 1, &filelen); + strp = BLI_file_read_text_as_mem(filepath, 1, &filelen); if (strp == NULL) { - BKE_reportf(reports, RPT_ERROR, "Failed to open file '%s'", filename); + BKE_reportf(reports, RPT_ERROR, "Failed to open file '%s'", filepath); return OPERATOR_CANCELLED; } strp[filelen] = 0; @@ -545,7 +545,7 @@ static int paste_from_file(bContext *C, ReportList *reports, const char *filenam retval = OPERATOR_FINISHED; } else { - BKE_reportf(reports, RPT_ERROR, "File too long %s", filename); + BKE_reportf(reports, RPT_ERROR, "File too long %s", filepath); retval = OPERATOR_CANCELLED; } @@ -556,12 +556,12 @@ static int paste_from_file(bContext *C, ReportList *reports, const char *filenam static int paste_from_file_exec(bContext *C, wmOperator *op) { - char *path; + char *filepath; int retval; - path = RNA_string_get_alloc(op->ptr, "filepath", NULL, 0, NULL); - retval = paste_from_file(C, op->reports, path); - MEM_freeN(path); + filepath = RNA_string_get_alloc(op->ptr, "filepath", NULL, 0, NULL); + retval = paste_from_file(C, op->reports, filepath); + MEM_freeN(filepath); return retval; } @@ -2091,7 +2091,7 @@ static int font_open_exec(bContext *C, wmOperator *op) static int open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { VFont *vfont = NULL; - const char *path; + const char *filepath; PointerRNA idptr; PropertyPointerRNA *pprop; @@ -2106,13 +2106,13 @@ static int open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event) vfont = (VFont *)idptr.owner_id; } - path = (vfont && !BKE_vfont_is_builtin(vfont)) ? vfont->filepath : U.fontdir; + filepath = (vfont && !BKE_vfont_is_builtin(vfont)) ? vfont->filepath : U.fontdir; if (RNA_struct_property_is_set(op->ptr, "filepath")) { return font_open_exec(C, op); } - RNA_string_set(op->ptr, "filepath", path); + RNA_string_set(op->ptr, "filepath", filepath); WM_event_add_fileselect(C, op); return OPERATOR_RUNNING_MODAL; diff --git a/source/blender/editors/curves/intern/curves_add.cc b/source/blender/editors/curves/intern/curves_add.cc index 9cde23451dc..17108619a4d 100644 --- a/source/blender/editors/curves/intern/curves_add.cc +++ b/source/blender/editors/curves/intern/curves_add.cc @@ -21,7 +21,7 @@ bke::CurvesGeometry primitive_random_sphere(const int curves_size, const int poi float *radius_data = (float *)CustomData_add_layer_named( &curves.point_data, CD_PROP_FLOAT, CD_DEFAULT, nullptr, curves.point_size, "radius"); - MutableSpan<float> radii{radius_data, curves.points_size()}; + MutableSpan<float> radii{radius_data, curves.points_num()}; for (const int i : offsets.index_range()) { offsets[i] = points_per_curve * i; @@ -30,7 +30,7 @@ bke::CurvesGeometry primitive_random_sphere(const int curves_size, const int poi RandomNumberGenerator rng; for (const int i : curves.curves_range()) { - const IndexRange curve_range = curves.range_for_curve(i); + const IndexRange curve_range = curves.points_for_curve(i); MutableSpan<float3> curve_positions = positions.slice(curve_range); MutableSpan<float> curve_radii = radii.slice(curve_range); diff --git a/source/blender/editors/gpencil/CMakeLists.txt b/source/blender/editors/gpencil/CMakeLists.txt index f8fa23a54d1..09a3cac0d48 100644 --- a/source/blender/editors/gpencil/CMakeLists.txt +++ b/source/blender/editors/gpencil/CMakeLists.txt @@ -28,7 +28,7 @@ set(SRC gpencil_add_monkey.c gpencil_add_stroke.c gpencil_armature.c - gpencil_bake_animation.c + gpencil_bake_animation.cc gpencil_convert.c gpencil_data.c gpencil_edit.c @@ -36,7 +36,7 @@ set(SRC gpencil_fill.c gpencil_interpolate.c gpencil_merge.c - gpencil_mesh.c + gpencil_mesh.cc gpencil_ops.c gpencil_ops_versioning.c gpencil_paint.c diff --git a/source/blender/editors/gpencil/gpencil_bake_animation.c b/source/blender/editors/gpencil/gpencil_bake_animation.cc index 5d33377900f..0667da46e25 100644 --- a/source/blender/editors/gpencil/gpencil_bake_animation.c +++ b/source/blender/editors/gpencil/gpencil_bake_animation.cc @@ -61,7 +61,7 @@ const EnumPropertyItem rna_gpencil_reproject_type_items[] = { 0, "Cursor", "Reproject the strokes using the orientation of 3D cursor"}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; /* Check frame_end is always > start frame! */ @@ -86,7 +86,7 @@ static bool gpencil_bake_grease_pencil_animation_poll(bContext *C) } /* Check if grease pencil or empty for dupli groups. */ - if ((obact == NULL) || (!ELEM(obact->type, OB_GPENCIL, OB_EMPTY))) { + if ((obact == nullptr) || (!ELEM(obact->type, OB_GPENCIL, OB_EMPTY))) { return false; } @@ -95,10 +95,10 @@ static bool gpencil_bake_grease_pencil_animation_poll(bContext *C) return (area && area->spacetype); } -typedef struct GpBakeOb { +struct GpBakeOb { struct GpBakeOb *next, *prev; Object *ob; -} GpBakeOb; +}; /* Get list of keyframes used by selected objects. */ static void animdata_keyframe_list_get(ListBase *ob_list, @@ -109,7 +109,7 @@ static void animdata_keyframe_list_get(ListBase *ob_list, LISTBASE_FOREACH (GpBakeOb *, elem, ob_list) { Object *ob = elem->ob; AnimData *adt = BKE_animdata_from_id(&ob->id); - if ((adt == NULL) || (adt->action == NULL)) { + if ((adt == nullptr) || (adt->action == nullptr)) { continue; } LISTBASE_FOREACH (FCurve *, fcurve, &adt->action->curves) { @@ -131,16 +131,15 @@ static void animdata_keyframe_list_get(ListBase *ob_list, static void gpencil_bake_duplilist(Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *list) { - GpBakeOb *elem = NULL; + GpBakeOb *elem = nullptr; ListBase *lb; - DupliObject *dob; lb = object_duplilist(depsgraph, scene, ob); - for (dob = lb->first; dob; dob = dob->next) { + LISTBASE_FOREACH (DupliObject *, dob, lb) { if (dob->ob->type != OB_GPENCIL) { continue; } - elem = MEM_callocN(sizeof(GpBakeOb), __func__); + elem = MEM_cnew<GpBakeOb>(__func__); elem->ob = dob->ob; BLI_addtail(list, elem); } @@ -150,13 +149,13 @@ static void gpencil_bake_duplilist(Depsgraph *depsgraph, Scene *scene, Object *o static void gpencil_bake_ob_list(bContext *C, Depsgraph *depsgraph, Scene *scene, ListBase *list) { - GpBakeOb *elem = NULL; + GpBakeOb *elem = nullptr; /* Add active object. In some files this could not be in selected array. */ Object *obact = CTX_data_active_object(C); if (obact->type == OB_GPENCIL) { - elem = MEM_callocN(sizeof(GpBakeOb), __func__); + elem = MEM_cnew<GpBakeOb>(__func__); elem->ob = obact; BLI_addtail(list, elem); } @@ -172,7 +171,7 @@ static void gpencil_bake_ob_list(bContext *C, Depsgraph *depsgraph, Scene *scene } /* Add selected objects. */ if (ob->type == OB_GPENCIL) { - elem = MEM_callocN(sizeof(GpBakeOb), __func__); + elem = MEM_cnew<GpBakeOb>(__func__); elem->ob = ob; BLI_addtail(list, elem); } @@ -199,7 +198,7 @@ static int gpencil_bake_grease_pencil_animation_exec(bContext *C, wmOperator *op Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); - ListBase ob_selected_list = {NULL, NULL}; + ListBase ob_selected_list = {nullptr, nullptr}; gpencil_bake_ob_list(C, depsgraph, scene, &ob_selected_list); /* Grab all relevant settings. */ @@ -215,10 +214,11 @@ static int gpencil_bake_grease_pencil_animation_exec(bContext *C, wmOperator *op const bool only_selected = RNA_boolean_get(op->ptr, "only_selected"); const int frame_offset = RNA_int_get(op->ptr, "frame_target") - frame_start; - const int project_type = RNA_enum_get(op->ptr, "project_type"); + const eGP_ReprojectModes project_type = (eGP_ReprojectModes)RNA_enum_get(op->ptr, + "project_type"); /* Create a new grease pencil object. */ - Object *ob_gpencil = NULL; + Object *ob_gpencil = nullptr; ushort local_view_bits = (v3d && v3d->localvd) ? v3d->local_view_uuid : 0; ob_gpencil = ED_gpencil_add_object(C, scene->cursor.location, local_view_bits); float invmat[4][4]; @@ -230,8 +230,8 @@ static int gpencil_bake_grease_pencil_animation_exec(bContext *C, wmOperator *op /* Set cursor to indicate working. */ WM_cursor_wait(true); - GP_SpaceConversion gsc = {NULL}; - SnapObjectContext *sctx = NULL; + GP_SpaceConversion gsc = {nullptr}; + SnapObjectContext *sctx = nullptr; if (project_type != GP_REPROJECT_KEEP) { /* Init space conversion stuff. */ gpencil_point_conversion_init(C, &gsc); @@ -271,14 +271,14 @@ static int gpencil_bake_grease_pencil_animation_exec(bContext *C, wmOperator *op /* Loop all objects in the list. */ LISTBASE_FOREACH (GpBakeOb *, elem, &ob_selected_list) { Object *ob_eval = (Object *)DEG_get_evaluated_object(depsgraph, elem->ob); - bGPdata *gpd_src = ob_eval->data; + bGPdata *gpd_src = static_cast<bGPdata *>(ob_eval->data); LISTBASE_FOREACH (bGPDlayer *, gpl_src, &gpd_src->layers) { /* Create destination layer. */ char *layer_name; layer_name = BLI_sprintfN("%s_%s", elem->ob->id.name + 2, gpl_src->info); bGPDlayer *gpl_dst = BKE_gpencil_layer_named_get(gpd_dst, layer_name); - if (gpl_dst == NULL) { + if (gpl_dst == nullptr) { gpl_dst = BKE_gpencil_layer_addnew(gpd_dst, layer_name, true, false); } MEM_freeN(layer_name); @@ -293,7 +293,7 @@ static int gpencil_bake_grease_pencil_animation_exec(bContext *C, wmOperator *op /* Duplicate frame. */ bGPDframe *gpf_src = BKE_gpencil_layer_frame_get( gpl_src, remap_cfra, GP_GETFRAME_USE_PREV); - if (gpf_src == NULL) { + if (gpf_src == nullptr) { continue; } bGPDframe *gpf_dst = BKE_gpencil_frame_duplicate(gpf_src, true); @@ -346,19 +346,19 @@ static int gpencil_bake_grease_pencil_animation_exec(bContext *C, wmOperator *op /* Free memory. */ gpencil_bake_free_ob_list(&ob_selected_list); - if (sctx != NULL) { + if (sctx != nullptr) { ED_transform_snap_object_context_destroy(sctx); } /* Free temp hash table. */ - if (keyframe_list != NULL) { - BLI_ghash_free(keyframe_list, NULL, NULL); + if (keyframe_list != nullptr) { + BLI_ghash_free(keyframe_list, nullptr, nullptr); } /* Notifiers. */ DEG_relations_tag_update(bmain); DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); DEG_id_tag_update(&gpd_dst->id, ID_RECALC_COPY_ON_WRITE); - WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, NULL); + WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, nullptr); WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); /* Reset cursor. */ @@ -418,12 +418,15 @@ void GPENCIL_OT_bake_grease_pencil_animation(wmOperatorType *ot) prop = RNA_def_int( ot->srna, "frame_end", 250, 1, 100000, "End Frame", "The end frame of animation", 1, 100000); - RNA_def_property_update_runtime(prop, gpencil_bake_set_frame_end); + RNA_def_property_update_runtime(prop, (void *)gpencil_bake_set_frame_end); prop = RNA_def_int(ot->srna, "step", 1, 1, 100, "Step", "Step between generated frames", 1, 100); - RNA_def_boolean( - ot->srna, "only_selected", 0, "Only Selected Keyframes", "Convert only selected keyframes"); + RNA_def_boolean(ot->srna, + "only_selected", + false, + "Only Selected Keyframes", + "Convert only selected keyframes"); RNA_def_int( ot->srna, "frame_target", 1, 1, 100000, "Target Frame", "Destination frame", 1, 100000); diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c index d4518f21586..4f9468cc9c4 100644 --- a/source/blender/editors/gpencil/gpencil_convert.c +++ b/source/blender/editors/gpencil/gpencil_convert.c @@ -207,7 +207,7 @@ typedef struct tGpTimingData { int seed; /* Data set from points, used to compute final timing FCurve */ - int num_points, cur_point; + int points_num, cur_point; /* Distances */ float *dists; @@ -229,29 +229,29 @@ typedef struct tGpTimingData { /* Init point buffers for timing data. * Note this assumes we only grow those arrays! */ -static void gpencil_timing_data_set_nbr(tGpTimingData *gtd, const int nbr) +static void gpencil_timing_data_set_num(tGpTimingData *gtd, const int num) { float *tmp; - BLI_assert(nbr > gtd->num_points); + BLI_assert(num > gtd->points_num); /* distances */ tmp = gtd->dists; - gtd->dists = MEM_callocN(sizeof(float) * nbr, __func__); + gtd->dists = MEM_callocN(sizeof(float) * num, __func__); if (tmp) { - memcpy(gtd->dists, tmp, sizeof(float) * gtd->num_points); + memcpy(gtd->dists, tmp, sizeof(float) * gtd->points_num); MEM_freeN(tmp); } /* times */ tmp = gtd->times; - gtd->times = MEM_callocN(sizeof(float) * nbr, __func__); + gtd->times = MEM_callocN(sizeof(float) * num, __func__); if (tmp) { - memcpy(gtd->times, tmp, sizeof(float) * gtd->num_points); + memcpy(gtd->times, tmp, sizeof(float) * gtd->points_num); MEM_freeN(tmp); } - gtd->num_points = nbr; + gtd->points_num = num; } /* add stroke point to timing buffers */ @@ -297,15 +297,15 @@ static void gpencil_timing_data_add_point(tGpTimingData *gtd, static int gpencil_find_end_of_stroke_idx(tGpTimingData *gtd, RNG *rng, const int idx, - const int nbr_gaps, - int *nbr_done_gaps, + const int gaps_count, + int *gaps_done_count, const float tot_gaps_time, const float delta_time, float *next_delta_time) { int j; - for (j = idx + 1; j < gtd->num_points; j++) { + for (j = idx + 1; j < gtd->points_num; j++) { if (gtd->times[j] < 0) { gtd->times[j] = -gtd->times[j]; if (gtd->mode == GP_STROKECONVERT_TIMING_CUSTOMGAP) { @@ -316,7 +316,7 @@ static int gpencil_find_end_of_stroke_idx(tGpTimingData *gtd, /* We want gaps that are in gtd->gap_duration +/- gtd->gap_randomness range, * and which sum to exactly tot_gaps_time... */ - int rem_gaps = nbr_gaps - (*nbr_done_gaps); + int rem_gaps = gaps_count - (*gaps_done_count); if (rem_gaps < 2) { /* Last gap, just give remaining time! */ *next_delta_time = tot_gaps_time; @@ -327,7 +327,7 @@ static int gpencil_find_end_of_stroke_idx(tGpTimingData *gtd, /* This code ensures that if the first gaps * have been shorter than average gap_duration, next gaps * will tend to be longer (i.e. try to recover the lateness), and vice-versa! */ - delta = delta_time - (gtd->gap_duration * (*nbr_done_gaps)); + delta = delta_time - (gtd->gap_duration * (*gaps_done_count)); /* Clamp min between [-gap_randomness, 0.0], with lower delta giving higher min */ min = -gtd->gap_randomness - delta; @@ -343,7 +343,7 @@ static int gpencil_find_end_of_stroke_idx(tGpTimingData *gtd, *next_delta_time += gtd->gap_duration; } } - (*nbr_done_gaps)++; + (*gaps_done_count)++; break; } } @@ -353,14 +353,14 @@ static int gpencil_find_end_of_stroke_idx(tGpTimingData *gtd, static void gpencil_stroke_path_animation_preprocess_gaps(tGpTimingData *gtd, RNG *rng, - int *nbr_gaps, + int *gaps_count, float *r_tot_gaps_time) { float delta_time = 0.0f; - for (int i = 0; i < gtd->num_points; i++) { + for (int i = 0; i < gtd->points_num; i++) { if (gtd->times[i] < 0 && i) { - (*nbr_gaps)++; + (*gaps_count)++; gtd->times[i] = -gtd->times[i] - delta_time; delta_time += gtd->times[i] - gtd->times[i - 1]; gtd->times[i] = -gtd->times[i - 1]; /* Temp marker, values *have* to be different! */ @@ -371,7 +371,7 @@ static void gpencil_stroke_path_animation_preprocess_gaps(tGpTimingData *gtd, } gtd->tot_time -= delta_time; - *r_tot_gaps_time = (float)(*nbr_gaps) * gtd->gap_duration; + *r_tot_gaps_time = (float)(*gaps_count) * gtd->gap_duration; gtd->tot_time += *r_tot_gaps_time; if (gtd->gap_randomness > 0.0f) { BLI_rng_srandom(rng, gtd->seed); @@ -387,7 +387,7 @@ static void gpencil_stroke_path_animation_add_keyframes(ReportList *reports, tGpTimingData *gtd, RNG *rng, const float time_range, - const int nbr_gaps, + const int gaps_count, const float tot_gaps_time) { /* Use actual recorded timing! */ @@ -399,20 +399,20 @@ static void gpencil_stroke_path_animation_add_keyframes(ReportList *reports, /* CustomGaps specific */ float delta_time = 0.0f, next_delta_time = 0.0f; - int nbr_done_gaps = 0; + int gaps_done_count = 0; /* This is a bit tricky, as: * - We can't add arbitrarily close points on FCurve (in time). * - We *must* have all "caps" points of all strokes in FCurve, as much as possible! */ - for (int i = 0; i < gtd->num_points; i++) { + for (int i = 0; i < gtd->points_num; i++) { /* If new stroke... */ if (i > end_stroke_idx) { start_stroke_idx = i; delta_time = next_delta_time; /* find end of that new stroke */ end_stroke_idx = gpencil_find_end_of_stroke_idx( - gtd, rng, i, nbr_gaps, &nbr_done_gaps, tot_gaps_time, delta_time, &next_delta_time); + gtd, rng, i, gaps_count, &gaps_done_count, tot_gaps_time, delta_time, &next_delta_time); /* This one should *never* be negative! */ end_stroke_time = time_start + ((gtd->times[end_stroke_idx] + delta_time) / gtd->tot_time * time_range); @@ -502,7 +502,7 @@ static void gpencil_stroke_path_animation(bContext *C, FCurve *fcu; PointerRNA ptr; PropertyRNA *prop = NULL; - int nbr_gaps = 0; + int gaps_count = 0; if (gtd->mode == GP_STROKECONVERT_TIMING_NONE) { return; @@ -571,7 +571,7 @@ static void gpencil_stroke_path_animation(bContext *C, /* Pre-process gaps, in case we don't want to keep their original timing */ if (gtd->mode == GP_STROKECONVERT_TIMING_CUSTOMGAP) { - gpencil_stroke_path_animation_preprocess_gaps(gtd, rng, &nbr_gaps, &tot_gaps_time); + gpencil_stroke_path_animation_preprocess_gaps(gtd, rng, &gaps_count, &tot_gaps_time); } if (gtd->realtime) { @@ -582,7 +582,7 @@ static void gpencil_stroke_path_animation(bContext *C, } gpencil_stroke_path_animation_add_keyframes( - reports, ptr, prop, depsgraph, fcu, cu, gtd, rng, time_range, nbr_gaps, tot_gaps_time); + reports, ptr, prop, depsgraph, fcu, cu, gtd, rng, time_range, gaps_count, tot_gaps_time); BLI_rng_free(rng); } @@ -684,7 +684,7 @@ static void gpencil_stroke_to_path(bContext *C, } if (do_gtd) { - gpencil_timing_data_set_nbr(gtd, nu->pntsu); + gpencil_timing_data_set_num(gtd, nu->pntsu); } /* If needed, make the link between both strokes with two zero-radius additional points */ @@ -929,7 +929,7 @@ static void gpencil_stroke_to_bezier(bContext *C, } if (do_gtd) { - gpencil_timing_data_set_nbr(gtd, nu->pntsu); + gpencil_timing_data_set_num(gtd, nu->pntsu); } tot = gps->totpoints; @@ -1536,7 +1536,7 @@ static int gpencil_convert_layer_exec(bContext *C, wmOperator *op) gtd.gap_randomness = RNA_float_get(op->ptr, "gap_randomness"); gtd.gap_randomness = min_ff(gtd.gap_randomness, gtd.gap_duration); gtd.seed = RNA_int_get(op->ptr, "seed"); - gtd.num_points = gtd.cur_point = 0; + gtd.points_num = gtd.cur_point = 0; gtd.dists = gtd.times = NULL; gtd.tot_dist = gtd.tot_time = gtd.gap_tot_time = 0.0f; gtd.inittime = 0.0; diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 8506e90191f..a8fb344f366 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -3924,31 +3924,36 @@ static void gpencil_smooth_stroke(bContext *C, wmOperator *op) GP_EDITABLE_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) { if (gps->flag & GP_STROKE_SELECT) { - for (int r = 0; r < repeat; r++) { + /* TODO use `BKE_gpencil_stroke_smooth` when the weights are better used. */ + bGPDstroke gps_old = *gps; + gps_old.points = (bGPDspoint *)MEM_dupallocN(gps->points); + /* Here the iteration needs to be done outside the smooth functions, + * as there are points that don't get smoothed. */ + for (int n = 0; n < repeat; n++) { for (int i = 0; i < gps->totpoints; i++) { - bGPDspoint *pt = &gps->points[i]; - if ((only_selected) && ((pt->flag & GP_SPOINT_SELECT) == 0)) { + if (only_selected && (gps->points[i].flag & GP_SPOINT_SELECT) == 0) { continue; } - /* perform smoothing */ + /* Perform smoothing. */ if (smooth_position) { - BKE_gpencil_stroke_smooth_point(gps, i, factor, false); + BKE_gpencil_stroke_smooth_point(&gps_old, i, factor, 1, false, false, gps); } if (smooth_strength) { - BKE_gpencil_stroke_smooth_strength(gps, i, factor); + BKE_gpencil_stroke_smooth_strength(&gps_old, i, factor, 1, gps); } if (smooth_thickness) { - /* thickness need to repeat process several times */ - for (int r2 = 0; r2 < repeat * 2; r2++) { - BKE_gpencil_stroke_smooth_thickness(gps, i, 1.0f - factor); - } + BKE_gpencil_stroke_smooth_thickness(&gps_old, i, 1.0f - factor, 1, gps); } if (smooth_uv) { - BKE_gpencil_stroke_smooth_uv(gps, i, factor); + BKE_gpencil_stroke_smooth_uv(&gps_old, i, factor, 1, gps); } } + if (n < repeat - 1) { + memcpy(gps_old.points, gps->points, sizeof(bGPDspoint) * gps->totpoints); + } } + MEM_freeN(gps_old.points); } } GP_EDITABLE_STROKES_END(gpstroke_iter); @@ -4926,10 +4931,10 @@ void GPENCIL_OT_stroke_smooth(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - prop = RNA_def_int(ot->srna, "repeat", 1, 1, 50, "Repeat", "", 1, 20); + prop = RNA_def_int(ot->srna, "repeat", 2, 1, 1000, "Repeat", "", 1, 1000); RNA_def_property_flag(prop, PROP_SKIP_SAVE); - RNA_def_float(ot->srna, "factor", 0.5f, 0.0f, 2.0f, "Factor", "", 0.0f, 2.0f); + RNA_def_float(ot->srna, "factor", 1.0f, 0.0f, 2.0f, "Factor", "", 0.0f, 1.0f); RNA_def_boolean(ot->srna, "only_selected", true, diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c index 45a2247c65e..94acf464691 100644 --- a/source/blender/editors/gpencil/gpencil_fill.c +++ b/source/blender/editors/gpencil/gpencil_fill.c @@ -1638,14 +1638,9 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf) } } - /* smooth stroke */ - float reduce = 0.0f; - float smoothfac = 1.0f; - for (int r = 0; r < 1; r++) { - for (int i = 0; i < gps->totpoints; i++) { - BKE_gpencil_stroke_smooth_point(gps, i, smoothfac - reduce, false); - } - reduce += 0.25f; /* reduce the factor */ + /* Smooth stroke. No copy of the stroke since there only a minor improvement here. */ + for (int i = 0; i < gps->totpoints; i++) { + BKE_gpencil_stroke_smooth_point(gps, i, 1.0f, 2, false, true, gps); } /* if axis locked, reproject to plane locked */ @@ -2113,18 +2108,18 @@ static bool gpencil_do_frame_fill(tGPDfill *tgpf, const bool is_inverted) int totpoints_prv = 0; int loop_limit = 0; while (totpoints > 0) { - /* analyze outline */ + /* Analyze outline. */ gpencil_get_outline_points(tgpf, (totpoints == 1) ? true : false); - /* create array of points from stack */ + /* Create array of points from stack. */ totpoints = gpencil_points_from_stack(tgpf); + if (totpoints > 0) { + /* Create z-depth array for reproject. */ + gpencil_get_depth_array(tgpf); - /* create z-depth array for reproject */ - gpencil_get_depth_array(tgpf); - - /* create stroke and reproject */ - gpencil_stroke_from_buffer(tgpf); - + /* Create stroke and reproject. */ + gpencil_stroke_from_buffer(tgpf); + } if (is_inverted) { gpencil_erase_processed_area(tgpf); } diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h index 1bb98ce51c7..56c94e4494d 100644 --- a/source/blender/editors/gpencil/gpencil_intern.h +++ b/source/blender/editors/gpencil/gpencil_intern.h @@ -13,6 +13,10 @@ #define DEPTH_INVALID 1.0f +#ifdef __cplusplus +extern "C" { +#endif + /* internal exports only */ struct Material; struct bGPDspoint; @@ -826,3 +830,7 @@ struct GP_EditableStrokes_Iter { extern const EnumPropertyItem rna_gpencil_reproject_type_items[]; /* ****************************************************** */ + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c index 65060e1bab5..8630b7f23d4 100644 --- a/source/blender/editors/gpencil/gpencil_interpolate.c +++ b/source/blender/editors/gpencil/gpencil_interpolate.c @@ -310,23 +310,6 @@ static void gpencil_stroke_pair_table(bContext *C, } } -static void gpencil_interpolate_smooth_stroke(bGPDstroke *gps, - float smooth_factor, - int smooth_steps) -{ - if (smooth_factor == 0.0f) { - return; - } - - float reduce = 0.0f; - for (int r = 0; r < smooth_steps; r++) { - for (int i = 0; i < gps->totpoints - 1; i++) { - BKE_gpencil_stroke_smooth_point(gps, i, smooth_factor - reduce, false); - BKE_gpencil_stroke_smooth_strength(gps, i, smooth_factor); - } - reduce += 0.25f; /* reduce the factor */ - } -} /* Perform interpolation */ static void gpencil_interpolate_update_points(const bGPDstroke *gps_from, const bGPDstroke *gps_to, @@ -553,7 +536,15 @@ static void gpencil_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi) /* Update points position. */ gpencil_interpolate_update_points(gps_from, gps_to, new_stroke, tgpil->factor); - gpencil_interpolate_smooth_stroke(new_stroke, tgpi->smooth_factor, tgpi->smooth_steps); + BKE_gpencil_stroke_smooth(new_stroke, + tgpi->smooth_factor, + tgpi->smooth_steps, + true, + true, + false, + false, + true, + NULL); /* Calc geometry data. */ BKE_gpencil_stroke_geometry_update(gpd, new_stroke); @@ -1385,7 +1376,8 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op) /* Update points position. */ gpencil_interpolate_update_points(gps_from, gps_to, new_stroke, factor); - gpencil_interpolate_smooth_stroke(new_stroke, smooth_factor, smooth_steps); + BKE_gpencil_stroke_smooth( + new_stroke, smooth_factor, smooth_steps, true, true, false, false, true, NULL); /* Calc geometry data. */ BKE_gpencil_stroke_geometry_update(gpd, new_stroke); diff --git a/source/blender/editors/gpencil/gpencil_mesh.c b/source/blender/editors/gpencil/gpencil_mesh.cc index 7db55796053..aee00d4ede3 100644 --- a/source/blender/editors/gpencil/gpencil_mesh.c +++ b/source/blender/editors/gpencil/gpencil_mesh.cc @@ -67,10 +67,10 @@ static bool gpencil_bake_mesh_animation_poll(bContext *C) return (area && area->spacetype); } -typedef struct GpBakeOb { +struct GpBakeOb { struct GpBakeOb *next, *prev; Object *ob; -} GpBakeOb; +}; /* Get list of keyframes used by selected objects. */ static void animdata_keyframe_list_get(ListBase *ob_list, @@ -81,7 +81,7 @@ static void animdata_keyframe_list_get(ListBase *ob_list, LISTBASE_FOREACH (GpBakeOb *, elem, ob_list) { Object *ob = elem->ob; AnimData *adt = BKE_animdata_from_id(&ob->id); - if ((adt == NULL) || (adt->action == NULL)) { + if ((adt == nullptr) || (adt->action == nullptr)) { continue; } LISTBASE_FOREACH (FCurve *, fcurve, &adt->action->curves) { @@ -103,15 +103,14 @@ static void animdata_keyframe_list_get(ListBase *ob_list, static void gpencil_bake_duplilist(Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *list) { - GpBakeOb *elem = NULL; + GpBakeOb *elem = nullptr; ListBase *lb; - DupliObject *dob; lb = object_duplilist(depsgraph, scene, ob); - for (dob = lb->first; dob; dob = dob->next) { + LISTBASE_FOREACH (DupliObject *, dob, lb) { if (dob->ob->type != OB_MESH) { continue; } - elem = MEM_callocN(sizeof(GpBakeOb), __func__); + elem = MEM_cnew<GpBakeOb>(__func__); elem->ob = dob->ob; BLI_addtail(list, elem); } @@ -121,17 +120,17 @@ static void gpencil_bake_duplilist(Depsgraph *depsgraph, Scene *scene, Object *o static bool gpencil_bake_ob_list(bContext *C, Depsgraph *depsgraph, Scene *scene, ListBase *list) { - GpBakeOb *elem = NULL; + GpBakeOb *elem = nullptr; bool simple_material = false; /* Add active object. In some files this could not be in selected array. */ Object *obact = CTX_data_active_object(C); - if (obact == NULL) { + if (obact == nullptr) { return false; } if (obact->type == OB_MESH) { - elem = MEM_callocN(sizeof(GpBakeOb), __func__); + elem = MEM_cnew<GpBakeOb>(__func__); elem->ob = obact; BLI_addtail(list, elem); } @@ -148,7 +147,7 @@ static bool gpencil_bake_ob_list(bContext *C, Depsgraph *depsgraph, Scene *scene } /* Add selected meshes. */ if (ob->type == OB_MESH) { - elem = MEM_callocN(sizeof(GpBakeOb), __func__); + elem = MEM_cnew<GpBakeOb>(__func__); elem->ob = ob; BLI_addtail(list, elem); } @@ -177,11 +176,11 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); - ListBase ob_selected_list = {NULL, NULL}; + ListBase ob_selected_list = {nullptr, nullptr}; gpencil_bake_ob_list(C, depsgraph, scene, &ob_selected_list); /* Cannot check this in poll because the active object changes. */ - if (ob_selected_list.first == NULL) { + if (ob_selected_list.first == nullptr) { BKE_report(op->reports, RPT_INFO, "No valid object selected"); gpencil_bake_free_ob_list(&ob_selected_list); return OPERATOR_CANCELLED; @@ -205,28 +204,29 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op) const bool only_selected = RNA_boolean_get(op->ptr, "only_selected"); const float offset = RNA_float_get(op->ptr, "offset"); const int frame_offset = RNA_int_get(op->ptr, "frame_target") - frame_start; - const int project_type = RNA_enum_get(op->ptr, "project_type"); - eGP_TargetObjectMode target = RNA_enum_get(op->ptr, "target"); + const eGP_ReprojectModes project_type = (eGP_ReprojectModes)RNA_enum_get(op->ptr, + "project_type"); + const eGP_TargetObjectMode target = (eGP_TargetObjectMode)RNA_enum_get(op->ptr, "target"); /* Create a new grease pencil object in origin or reuse selected. */ - Object *ob_gpencil = NULL; + Object *ob_gpencil = nullptr; bool newob = false; if (target == GP_TARGET_OB_SELECTED) { ob_gpencil = BKE_view_layer_non_active_selected_object(CTX_data_view_layer(C), v3d); - if (ob_gpencil != NULL) { + if (ob_gpencil != nullptr) { if (ob_gpencil->type != OB_GPENCIL) { BKE_report(op->reports, RPT_WARNING, "Target object not a grease pencil, ignoring!"); - ob_gpencil = NULL; + ob_gpencil = nullptr; } else if (BKE_object_obdata_is_libdata(ob_gpencil)) { BKE_report(op->reports, RPT_WARNING, "Target object library-data, ignoring!"); - ob_gpencil = NULL; + ob_gpencil = nullptr; } } } - if (ob_gpencil == NULL) { + if (ob_gpencil == nullptr) { ushort local_view_bits = (v3d && v3d->localvd) ? v3d->local_view_uuid : 0; const float loc[3] = {0.0f, 0.0f, 0.0f}; ob_gpencil = ED_gpencil_add_object(C, loc, local_view_bits); @@ -239,8 +239,8 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op) /* Set cursor to indicate working. */ WM_cursor_wait(true); - GP_SpaceConversion gsc = {NULL}; - SnapObjectContext *sctx = NULL; + GP_SpaceConversion gsc = {nullptr}; + SnapObjectContext *sctx = nullptr; if (project_type != GP_REPROJECT_KEEP) { /* Init space conversion stuff. */ gpencil_point_conversion_init(C, &gsc); @@ -309,7 +309,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op) if (project_type != GP_REPROJECT_KEEP) { LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { bGPDframe *gpf = gpl->actframe; - if (gpf == NULL) { + if (gpf == nullptr) { continue; } LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { @@ -355,12 +355,12 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op) /* Free memory. */ gpencil_bake_free_ob_list(&ob_selected_list); - if (sctx != NULL) { + if (sctx != nullptr) { ED_transform_snap_object_context_destroy(sctx); } /* Free temp hash table. */ - if (keyframe_list != NULL) { - BLI_ghash_free(keyframe_list, NULL, NULL); + if (keyframe_list != nullptr) { + BLI_ghash_free(keyframe_list, nullptr, nullptr); } /* notifiers */ @@ -368,7 +368,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op) DEG_relations_tag_update(bmain); } DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); - WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, NULL); + WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, nullptr); WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); /* Reset cursor. */ @@ -392,7 +392,7 @@ void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot) static const EnumPropertyItem target_object_modes[] = { {GP_TARGET_OB_NEW, "NEW", 0, "New Object", ""}, {GP_TARGET_OB_SELECTED, "SELECTED", 0, "Selected Object", ""}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; PropertyRNA *prop; @@ -424,7 +424,7 @@ void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot) prop = RNA_def_int( ot->srna, "frame_end", 250, 1, 100000, "End Frame", "The end frame of animation", 1, 100000); - RNA_def_property_update_runtime(prop, gpencil_bake_set_frame_end); + RNA_def_property_update_runtime(prop, (void *)gpencil_bake_set_frame_end); prop = RNA_def_int(ot->srna, "step", 1, 1, 100, "Step", "Step between generated frames", 1, 100); @@ -433,7 +433,7 @@ void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot) prop = RNA_def_float_rotation(ot->srna, "angle", 0, - NULL, + nullptr, DEG2RADF(0.0f), DEG2RADF(180.0f), "Threshold Angle", @@ -452,10 +452,13 @@ void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot) 0.0, 100.00); - RNA_def_boolean(ot->srna, "seams", 0, "Only Seam Edges", "Convert only seam edges"); - RNA_def_boolean(ot->srna, "faces", 1, "Export Faces", "Export faces as filled strokes"); - RNA_def_boolean( - ot->srna, "only_selected", 0, "Only Selected Keyframes", "Convert only selected keyframes"); + RNA_def_boolean(ot->srna, "seams", false, "Only Seam Edges", "Convert only seam edges"); + RNA_def_boolean(ot->srna, "faces", true, "Export Faces", "Export faces as filled strokes"); + RNA_def_boolean(ot->srna, + "only_selected", + false, + "Only Selected Keyframes", + "Convert only selected keyframes"); RNA_def_int( ot->srna, "frame_target", 1, 1, 100000, "Target Frame", "Destination frame", 1, 100000); diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 18dc8d4bc72..93a4a784674 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1197,29 +1197,21 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p) gpencil_subdivide_stroke(gpd, gps, subdivide); } - /* Smooth stroke after subdiv - only if there's something to do for each iteration, - * the factor is reduced to get a better smoothing - * without changing too much the original stroke. */ - if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_SETTINGS) && - (brush->gpencil_settings->draw_smoothfac > 0.0f)) { - float reduce = 0.0f; - for (int r = 0; r < brush->gpencil_settings->draw_smoothlvl; r++) { - for (i = 0; i < gps->totpoints - 1; i++) { - BKE_gpencil_stroke_smooth_point( - gps, i, brush->gpencil_settings->draw_smoothfac - reduce, false); - BKE_gpencil_stroke_smooth_strength(gps, i, brush->gpencil_settings->draw_smoothfac); - } - reduce += 0.25f; /* reduce the factor */ - } + /* Smooth stroke after subdiv - only if there's something to do for each iteration. + * Keep the original stroke shape as much as possible. */ + const float smoothfac = brush->gpencil_settings->draw_smoothfac; + const int iterations = brush->gpencil_settings->draw_smoothlvl; + if (brush->gpencil_settings->flag & GP_BRUSH_GROUP_SETTINGS) { + BKE_gpencil_stroke_smooth(gps, smoothfac, iterations, true, true, false, false, true, NULL); } /* If reproject the stroke using Stroke mode, need to apply a smooth because * the reprojection creates small jitter. */ if (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) { float ifac = (float)brush->gpencil_settings->input_samples / 10.0f; float sfac = interpf(1.0f, 0.2f, ifac); - for (i = 0; i < gps->totpoints - 1; i++) { - BKE_gpencil_stroke_smooth_point(gps, i, sfac, false); - BKE_gpencil_stroke_smooth_strength(gps, i, sfac); + for (i = 0; i < gps->totpoints; i++) { + BKE_gpencil_stroke_smooth_point(gps, i, sfac, 2, false, true, gps); + BKE_gpencil_stroke_smooth_strength(gps, i, sfac, 2, gps); } } diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c index 57a184b0e8d..01d433b9b2a 100644 --- a/source/blender/editors/gpencil/gpencil_primitive.c +++ b/source/blender/editors/gpencil/gpencil_primitive.c @@ -1481,7 +1481,7 @@ static void gpencil_primitive_edit_event_handling( break; } case MOUSEMOVE: { - if ((event->val == KM_PRESS) && tgpi->sel_cp != SELECT_NONE) { + if (tgpi->sel_cp != SELECT_NONE) { if (tgpi->sel_cp == SELECT_START && tgpi->tot_stored_edges == 0) { copy_v2_v2(tgpi->start, tgpi->mval); } diff --git a/source/blender/editors/gpencil/gpencil_sculpt_paint.c b/source/blender/editors/gpencil/gpencil_sculpt_paint.c index 216971e514b..1e7159392e2 100644 --- a/source/blender/editors/gpencil/gpencil_sculpt_paint.c +++ b/source/blender/editors/gpencil/gpencil_sculpt_paint.c @@ -329,16 +329,16 @@ static bool gpencil_brush_smooth_apply(tGP_BrushEditData *gso, /* perform smoothing */ if (gso->brush->gpencil_settings->sculpt_mode_flag & GP_SCULPT_FLAGMODE_APPLY_POSITION) { - BKE_gpencil_stroke_smooth_point(gps, pt_index, inf, false); + BKE_gpencil_stroke_smooth_point(gps, pt_index, inf, 2, false, false, gps); } if (gso->brush->gpencil_settings->sculpt_mode_flag & GP_SCULPT_FLAGMODE_APPLY_STRENGTH) { - BKE_gpencil_stroke_smooth_strength(gps, pt_index, inf); + BKE_gpencil_stroke_smooth_strength(gps, pt_index, inf, 2, gps); } if (gso->brush->gpencil_settings->sculpt_mode_flag & GP_SCULPT_FLAGMODE_APPLY_THICKNESS) { - BKE_gpencil_stroke_smooth_thickness(gps, pt_index, inf); + BKE_gpencil_stroke_smooth_thickness(gps, pt_index, inf, 2, gps); } if (gso->brush->gpencil_settings->sculpt_mode_flag & GP_SCULPT_FLAGMODE_APPLY_UV) { - BKE_gpencil_stroke_smooth_uv(gps, pt_index, inf); + BKE_gpencil_stroke_smooth_uv(gps, pt_index, inf, 2, gps); } return true; diff --git a/source/blender/editors/include/ED_transform_snap_object_context.h b/source/blender/editors/include/ED_transform_snap_object_context.h index fa53e7a76e4..2919001c5ce 100644 --- a/source/blender/editors/include/ED_transform_snap_object_context.h +++ b/source/blender/editors/include/ED_transform_snap_object_context.h @@ -21,19 +21,19 @@ struct Object; struct Scene; struct View3D; -/* transform_snap_object.c */ +/* transform_snap_object.cc */ /* ED_transform_snap_object_*** API */ -typedef enum { +typedef enum eSnapSelect { SNAP_ALL = 0, SNAP_NOT_SELECTED = 1, SNAP_NOT_ACTIVE = 2, - SNAP_ONLY_ACTIVE = 3, + SNAP_NOT_EDITED = 3, SNAP_SELECTABLE = 4, } eSnapSelect; -typedef enum { +typedef enum eSnapEditType { SNAP_GEOM_FINAL = 0, SNAP_GEOM_CAGE = 1, SNAP_GEOM_EDIT = 2, /* Bmesh for mesh-type. */ @@ -59,13 +59,13 @@ struct SnapObjectHitDepth { /** parameters that define which objects will be used to snap. */ struct SnapObjectParams { /* Special context sensitive handling for the active or selected object. */ - char snap_select; + eSnapSelect snap_select; /* Geometry for snapping in edit mode. */ - char edit_mode_type; + eSnapEditType edit_mode_type; /* snap to the closest element, use when using more than one snap type */ - unsigned int use_occlusion_test : 1; + bool use_occlusion_test : true; /* exclude back facing geometry from snapping */ - unsigned int use_backface_culling : 1; + bool use_backface_culling : true; }; typedef struct SnapObjectContext SnapObjectContext; diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index d2ff5637a13..53591e02f71 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -273,9 +273,8 @@ typedef enum { V3D_SNAPCURSOR_TOGGLE_ALWAYS_TRUE = 1 << 0, V3D_SNAPCURSOR_OCCLUSION_ALWAYS_TRUE = 1 << 1, V3D_SNAPCURSOR_OCCLUSION_ALWAYS_FALSE = 1 << 2, /* TODO. */ - V3D_SNAPCURSOR_SNAP_ONLY_ACTIVE = 1 << 3, - V3D_SNAPCURSOR_SNAP_EDIT_GEOM_FINAL = 1 << 4, - V3D_SNAPCURSOR_SNAP_EDIT_GEOM_CAGE = 1 << 5, + V3D_SNAPCURSOR_SNAP_EDIT_GEOM_FINAL = 1 << 3, + V3D_SNAPCURSOR_SNAP_EDIT_GEOM_CAGE = 1 << 4, } eV3DSnapCursor; typedef enum { diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index a223eac3000..74797f91046 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -157,6 +157,8 @@ enum { UI_BLOCK_POPOVER_ONCE = 1 << 22, /** Always show key-maps, even for non-menus. */ UI_BLOCK_SHOW_SHORTCUT_ALWAYS = 1 << 23, + /** Don't show library override state for buttons in this block. */ + UI_BLOCK_NO_DRAW_OVERRIDDEN_STATE = 1 << 24, /** The block is only used during the search process and will not be drawn. * Currently just for the case of a closed panel's sub-panel (and its sub-panels). */ UI_BLOCK_SEARCH_ONLY = 1 << 25, diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 3619a7ce317..e83a8761e12 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -4238,28 +4238,28 @@ static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *bu int totitems = 0; int categories = 0; - int nbr_entries_nosepr = 0; + int entries_nosepr_count = 0; for (const EnumPropertyItem *item = item_array; item->identifier; item++, totitems++) { if (!item->identifier[0]) { /* inconsistent, but menus with categories do not look good flipped */ if (item->name) { block->flag |= UI_BLOCK_NO_FLIP; categories++; - nbr_entries_nosepr++; + entries_nosepr_count++; } - /* We do not want simple separators in nbr_entries_nosepr count */ + /* We do not want simple separators in `entries_nosepr_count`. */ continue; } - nbr_entries_nosepr++; + entries_nosepr_count++; } /* Columns and row estimation. Ignore simple separators here. */ - int columns = (nbr_entries_nosepr + 20) / 20; + int columns = (entries_nosepr_count + 20) / 20; if (columns < 1) { columns = 1; } if (columns > 8) { - columns = (nbr_entries_nosepr + 25) / 25; + columns = (entries_nosepr_count + 25) / 25; } int rows = totitems / columns; diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index decd8c03d70..c02024bc82d 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -546,13 +546,13 @@ void ui_draw_but_HISTOGRAM(ARegion *UNUSED(region), #undef HISTOGRAM_TOT_GRID_LINES -static void waveform_draw_one(float *waveform, int nbr, const float col[3]) +static void waveform_draw_one(float *waveform, int waveform_num, const float col[3]) { GPUVertFormat format = {0}; const uint pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); - GPU_vertbuf_data_alloc(vbo, nbr); + GPU_vertbuf_data_alloc(vbo, waveform_num); GPU_vertbuf_attr_fill(vbo, pos_id, waveform); diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 35cf952b5ce..b33cab3cbc6 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -4963,6 +4963,9 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu } } #endif + if (but->block->flag & UI_BLOCK_NO_DRAW_OVERRIDDEN_STATE) { + state &= ~UI_BUT_OVERRIDDEN; + } const float zoom = 1.0f / but->block->aspect; wt->state(wt, state, drawflag, but->emboss); diff --git a/source/blender/editors/io/io_usd.c b/source/blender/editors/io/io_usd.c index 98df418b5d4..51181f7caaa 100644 --- a/source/blender/editors/io/io_usd.c +++ b/source/blender/editors/io/io_usd.c @@ -201,6 +201,8 @@ void WM_OT_usd_export(struct wmOperatorType *ot) ot->poll = WM_operator_winactive; ot->ui = wm_usd_export_draw; + ot->flag = OPTYPE_REGISTER; /* No UNDO possible. */ + WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_USD, FILE_BLENDER, @@ -459,6 +461,8 @@ void WM_OT_usd_import(struct wmOperatorType *ot) ot->poll = WM_operator_winactive; ot->ui = wm_usd_import_draw; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_USD, FILE_BLENDER, diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index dbb6916dfce..d93edd2776b 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -515,7 +515,7 @@ static void multiresbake_freejob(void *bkv) /* delete here, since this delete will be called from main thread */ for (link = data->images.first; link; link = link->next) { Image *ima = (Image *)link->data; - BKE_image_free_gputextures(ima); + BKE_image_partial_update_mark_full_update(ima); } MEM_freeN(data->ob_image.array); diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index 3ca91c7e652..fec87fbfa95 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -180,7 +180,7 @@ static bool write_internal_bake_pixels(Image *image, void *lock; bool is_float; char *mask_buffer = NULL; - const size_t num_pixels = (size_t)width * (size_t)height; + const size_t pixels_num = (size_t)width * (size_t)height; ibuf = BKE_image_acquire_ibuf(image, NULL, &lock); @@ -189,8 +189,8 @@ static bool write_internal_bake_pixels(Image *image, } if (margin > 0 || !is_clear) { - mask_buffer = MEM_callocN(sizeof(char) * num_pixels, "Bake Mask"); - RE_bake_mask_fill(pixel_array, num_pixels, mask_buffer); + mask_buffer = MEM_callocN(sizeof(char) * pixels_num, "Bake Mask"); + RE_bake_mask_fill(pixel_array, pixels_num, mask_buffer); } is_float = (ibuf->rect_float != NULL); @@ -298,7 +298,7 @@ static bool write_internal_bake_pixels(Image *image, /* force OpenGL reload */ static void bake_targets_refresh(BakeTargets *targets) { - for (int i = 0; i < targets->num_images; i++) { + for (int i = 0; i < targets->images_num; i++) { Image *ima = targets->images[i].image; if (ima) { @@ -374,10 +374,10 @@ static bool write_external_bake_pixels(const char *filepath, /* margins */ if (margin > 0) { char *mask_buffer = NULL; - const size_t num_pixels = (size_t)width * (size_t)height; + const size_t pixels_num = (size_t)width * (size_t)height; - mask_buffer = MEM_callocN(sizeof(char) * num_pixels, "Bake Mask"); - RE_bake_mask_fill(pixel_array, num_pixels, mask_buffer); + mask_buffer = MEM_callocN(sizeof(char) * pixels_num, "Bake Mask"); + RE_bake_mask_fill(pixel_array, pixels_num, mask_buffer); RE_bake_margin(ibuf, mask_buffer, margin, margin_type, mesh_eval, uv_layer); if (mask_buffer) { @@ -670,9 +670,9 @@ static bool bake_targets_init_image_textures(const BakeAPIRender *bkr, Object *ob, ReportList *reports) { - int num_materials = ob->totcol; + int materials_num = ob->totcol; - if (num_materials == 0) { + if (materials_num == 0) { if (bkr->save_mode == R_BAKE_SAVE_INTERNAL) { BKE_report( reports, RPT_ERROR, "No active image found, add a material or bake to an external file"); @@ -688,15 +688,15 @@ static bool bake_targets_init_image_textures(const BakeAPIRender *bkr, } /* Over-allocate in case there is more materials than images. */ - targets->num_materials = num_materials; - targets->images = MEM_callocN(sizeof(BakeImage) * targets->num_materials, "BakeTargets.images"); - targets->material_to_image = MEM_callocN(sizeof(int) * targets->num_materials, + targets->materials_num = materials_num; + targets->images = MEM_callocN(sizeof(BakeImage) * targets->materials_num, "BakeTargets.images"); + targets->material_to_image = MEM_callocN(sizeof(int) * targets->materials_num, "BakeTargets.material_to_image"); /* Error handling and tag (in case multiple materials share the same image). */ BKE_main_id_tag_idcode(bkr->main, ID_IM, LIB_TAG_DOIT, false); - for (int i = 0; i < num_materials; i++) { + for (int i = 0; i < materials_num; i++) { Image *image; ED_object_get_active_image(ob, i + 1, &image, NULL, NULL, NULL); @@ -713,10 +713,10 @@ static bool bake_targets_init_image_textures(const BakeAPIRender *bkr, } } else { - targets->material_to_image[i] = targets->num_images; - targets->images[targets->num_images].image = image; + targets->material_to_image[i] = targets->images_num; + targets->images[targets->images_num].image = image; image->id.tag |= LIB_TAG_DOIT; - targets->num_images++; + targets->images_num++; } } @@ -733,7 +733,7 @@ static bool bake_targets_init_internal(const BakeAPIRender *bkr, } /* Saving to image datablocks. */ - for (int i = 0; i < targets->num_images; i++) { + for (int i = 0; i < targets->images_num; i++) { BakeImage *bk_image = &targets->images[i]; void *lock; ImBuf *ibuf = BKE_image_acquire_ibuf(bk_image->image, NULL, &lock); @@ -741,9 +741,9 @@ static bool bake_targets_init_internal(const BakeAPIRender *bkr, if (ibuf) { bk_image->width = ibuf->x; bk_image->height = ibuf->y; - bk_image->offset = targets->num_pixels; + bk_image->offset = targets->pixels_num; - targets->num_pixels += (size_t)ibuf->x * (size_t)ibuf->y; + targets->pixels_num += (size_t)ibuf->x * (size_t)ibuf->y; } else { BKE_image_release_ibuf(bk_image->image, ibuf, lock); @@ -765,12 +765,12 @@ static bool bake_targets_output_internal(const BakeAPIRender *bkr, { bool all_ok = true; - for (int i = 0; i < targets->num_images; i++) { + for (int i = 0; i < targets->images_num; i++) { BakeImage *bk_image = &targets->images[i]; const bool ok = write_internal_bake_pixels(bk_image->image, pixel_array + bk_image->offset, targets->result + - bk_image->offset * targets->num_channels, + bk_image->offset * targets->channels_num, bk_image->width, bk_image->height, bkr->margin, @@ -809,15 +809,15 @@ static bool bake_targets_init_external(const BakeAPIRender *bkr, } /* Saving to disk. */ - for (int i = 0; i < targets->num_images; i++) { + for (int i = 0; i < targets->images_num; i++) { BakeImage *bk_image = &targets->images[i]; bk_image->width = bkr->width; bk_image->height = bkr->height; - bk_image->offset = targets->num_pixels; + bk_image->offset = targets->pixels_num; bk_image->image = NULL; - targets->num_pixels += (size_t)bkr->width * (size_t)bkr->height; + targets->pixels_num += (size_t)bkr->width * (size_t)bkr->height; if (!bkr->is_split_materials) { break; @@ -826,7 +826,7 @@ static bool bake_targets_init_external(const BakeAPIRender *bkr, if (!bkr->is_split_materials) { /* saving a single image */ - for (int i = 0; i < targets->num_materials; i++) { + for (int i = 0; i < targets->materials_num; i++) { targets->material_to_image[i] = 0; } } @@ -844,7 +844,7 @@ static bool bake_targets_output_external(const BakeAPIRender *bkr, { bool all_ok = true; - for (int i = 0; i < targets->num_images; i++) { + for (int i = 0; i < targets->images_num; i++) { BakeImage *bk_image = &targets->images[i]; BakeData *bake = &bkr->scene->r.bake; @@ -888,7 +888,7 @@ static bool bake_targets_output_external(const BakeAPIRender *bkr, const bool ok = write_external_bake_pixels(name, pixel_array + bk_image->offset, targets->result + - bk_image->offset * targets->num_channels, + bk_image->offset * targets->channels_num, bk_image->width, bk_image->height, bkr->margin, @@ -934,11 +934,11 @@ static bool bake_targets_init_vertex_colors(BakeTargets *targets, Object *ob, Re } targets->images = MEM_callocN(sizeof(BakeImage), "BakeTargets.images"); - targets->num_images = 1; + targets->images_num = 1; targets->material_to_image = MEM_callocN(sizeof(int) * ob->totcol, "BakeTargets.material_to_image"); - targets->num_materials = ob->totcol; + targets->materials_num = ob->totcol; BakeImage *bk_image = &targets->images[0]; bk_image->width = me->totloop; @@ -946,7 +946,7 @@ static bool bake_targets_init_vertex_colors(BakeTargets *targets, Object *ob, Re bk_image->offset = 0; bk_image->image = NULL; - targets->num_pixels = bk_image->width * bk_image->height; + targets->pixels_num = bk_image->width * bk_image->height; return true; } @@ -984,10 +984,10 @@ static void bake_targets_populate_pixels_vertex_colors(BakeTargets *targets, BakePixel *pixel_array) { Mesh *me = ob->data; - const int num_pixels = targets->num_pixels; + const int pixels_num = targets->pixels_num; /* Initialize blank pixels. */ - for (int i = 0; i < num_pixels; i++) { + for (int i = 0; i < pixels_num; i++) { BakePixel *pixel = &pixel_array[i]; pixel->primitive_id = -1; @@ -1059,12 +1059,12 @@ static void bake_targets_populate_pixels_vertex_colors(BakeTargets *targets, MEM_freeN(looptri); } -static void bake_result_add_to_rgba(float rgba[4], const float *result, const int num_channels) +static void bake_result_add_to_rgba(float rgba[4], const float *result, const int channels_num) { - if (num_channels == 4) { + if (channels_num == 4) { add_v4_v4(rgba, result); } - else if (num_channels == 3) { + else if (channels_num == 3) { add_v3_v3(rgba, result); rgba[3] += 1.0f; } @@ -1082,7 +1082,7 @@ static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob) MPropCol *mcol = CustomData_get_layer(&me->vdata, CD_PROP_COLOR); const bool mcol_valid = (mcol != NULL); MLoopCol *mloopcol = CustomData_get_layer(&me->ldata, CD_MLOOPCOL); - const int num_channels = targets->num_channels; + const int channels_num = targets->channels_num; const float *result = targets->result; if (mcol_valid) { @@ -1096,7 +1096,7 @@ static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob) MLoop *mloop = me->mloop; for (int i = 0; i < totloop; i++, mloop++) { const int v = mloop->v; - bake_result_add_to_rgba(mcol[v].color, &result[i * num_channels], num_channels); + bake_result_add_to_rgba(mcol[v].color, &result[i * channels_num], channels_num); num_loops_for_vertex[v]++; } @@ -1118,7 +1118,7 @@ static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob) for (int i = 0; i < totloop; i++, mloop++, mloopcol++) { float rgba[4]; zero_v4(rgba); - bake_result_add_to_rgba(rgba, &result[i * num_channels], num_channels); + bake_result_add_to_rgba(rgba, &result[i * channels_num], channels_num); if (is_noncolor) { unit_float_to_uchar_clamp_v4(&mloopcol->r, rgba); @@ -1160,13 +1160,13 @@ static bool bake_targets_init(const BakeAPIRender *bkr, } } - if (targets->num_pixels == 0) { + if (targets->pixels_num == 0) { return false; } targets->is_noncolor = is_noncolor_pass(bkr->pass_type); - targets->num_channels = RE_pass_depth(bkr->pass_type); - targets->result = MEM_callocN(sizeof(float) * targets->num_channels * targets->num_pixels, + targets->channels_num = RE_pass_depth(bkr->pass_type); + targets->result = MEM_callocN(sizeof(float) * targets->channels_num * targets->pixels_num, "bake return pixels"); return true; @@ -1182,7 +1182,7 @@ static void bake_targets_populate_pixels(const BakeAPIRender *bkr, bake_targets_populate_pixels_vertex_colors(targets, ob, me_eval, pixel_array); } else { - RE_bake_pixels_populate(me_eval, pixel_array, targets->num_pixels, targets, bkr->uv_layer); + RE_bake_pixels_populate(me_eval, pixel_array, targets->pixels_num, targets, bkr->uv_layer); } } @@ -1329,7 +1329,7 @@ static int bake(const BakeAPIRender *bkr, /* Populate the pixel array with the face data. Except if we use a cage, then * it is populated later with the cage mesh (smoothed version of the mesh). */ - pixel_array_low = MEM_mallocN(sizeof(BakePixel) * targets.num_pixels, "bake pixels low poly"); + pixel_array_low = MEM_mallocN(sizeof(BakePixel) * targets.pixels_num, "bake pixels low poly"); if ((bkr->is_selected_to_active && (ob_cage == NULL) && bkr->is_cage) == false) { bake_targets_populate_pixels(bkr, &targets, ob_low, me_low_eval, pixel_array_low); } @@ -1422,7 +1422,7 @@ static int bake(const BakeAPIRender *bkr, ob_low_eval->base_flag &= ~(BASE_VISIBLE_DEPSGRAPH | BASE_ENABLED_RENDER); /* populate the pixel arrays with the corresponding face data for each high poly object */ - pixel_array_high = MEM_mallocN(sizeof(BakePixel) * targets.num_pixels, + pixel_array_high = MEM_mallocN(sizeof(BakePixel) * targets.pixels_num, "bake pixels high poly"); if (!RE_bake_pixels_populate_from_objects(me_low_eval, @@ -1430,7 +1430,7 @@ static int bake(const BakeAPIRender *bkr, pixel_array_high, highpoly, tot_highpoly, - targets.num_pixels, + targets.pixels_num, ob_cage != NULL, bkr->cage_extrusion, bkr->max_ray_distance, @@ -1491,16 +1491,16 @@ static int bake(const BakeAPIRender *bkr, break; } RE_bake_normal_world_to_world(pixel_array_low, - targets.num_pixels, - targets.num_channels, + targets.pixels_num, + targets.channels_num, targets.result, bkr->normal_swizzle); break; } case R_BAKE_SPACE_OBJECT: { RE_bake_normal_world_to_object(pixel_array_low, - targets.num_pixels, - targets.num_channels, + targets.pixels_num, + targets.channels_num, targets.result, ob_low_eval, bkr->normal_swizzle); @@ -1509,8 +1509,8 @@ static int bake(const BakeAPIRender *bkr, case R_BAKE_SPACE_TANGENT: { if (bkr->is_selected_to_active) { RE_bake_normal_world_to_tangent(pixel_array_low, - targets.num_pixels, - targets.num_channels, + targets.pixels_num, + targets.channels_num, targets.result, me_low_eval, bkr->normal_swizzle, @@ -1535,8 +1535,8 @@ static int bake(const BakeAPIRender *bkr, } RE_bake_normal_world_to_tangent(pixel_array_low, - targets.num_pixels, - targets.num_channels, + targets.pixels_num, + targets.channels_num, targets.result, (me_nores) ? me_nores : me_low_eval, bkr->normal_swizzle, diff --git a/source/blender/editors/object/object_gpencil_modifier.c b/source/blender/editors/object/object_gpencil_modifier.c index 9b62823ea8a..d0a6a5d44c0 100644 --- a/source/blender/editors/object/object_gpencil_modifier.c +++ b/source/blender/editors/object/object_gpencil_modifier.c @@ -403,7 +403,7 @@ void OBJECT_OT_gpencil_modifier_add(wmOperatorType *ot) /* properties */ prop = RNA_def_enum(ot->srna, "type", - rna_enum_object_modifier_type_items, + rna_enum_object_greasepencil_modifier_type_items, eGpencilModifierType_Thick, "Type", ""); diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c index e8637b57724..b3f62f3fc0f 100644 --- a/source/blender/editors/object/object_hook.c +++ b/source/blender/editors/object/object_hook.c @@ -54,23 +54,26 @@ #include "object_intern.h" -static int return_editmesh_indexar(BMEditMesh *em, int *r_tot, int **r_indexar, float r_cent[3]) +static int return_editmesh_indexar(BMEditMesh *em, + int *r_indexar_num, + int **r_indexar, + float r_cent[3]) { BMVert *eve; BMIter iter; - int *index, nr, totvert = 0; + int *index, nr, indexar_num = 0; BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - totvert++; + indexar_num++; } } - if (totvert == 0) { + if (indexar_num == 0) { return 0; } - *r_indexar = index = MEM_mallocN(4 * totvert, "hook indexar"); - *r_tot = totvert; + *r_indexar = index = MEM_mallocN(4 * indexar_num, "hook indexar"); + *r_indexar_num = indexar_num; nr = 0; zero_v3(r_cent); @@ -83,9 +86,9 @@ static int return_editmesh_indexar(BMEditMesh *em, int *r_tot, int **r_indexar, nr++; } - mul_v3_fl(r_cent, 1.0f / (float)totvert); + mul_v3_fl(r_cent, 1.0f / (float)indexar_num); - return totvert; + return indexar_num; } static bool return_editmesh_vgroup(Object *obedit, BMEditMesh *em, char *r_name, float r_cent[3]) @@ -97,7 +100,7 @@ static bool return_editmesh_vgroup(Object *obedit, BMEditMesh *em, char *r_name, if (cd_dvert_offset != -1) { const int defgrp_index = active_index - 1; - int totvert = 0; + int indexar_num = 0; MDeformVert *dvert; BMVert *eve; @@ -109,14 +112,14 @@ static bool return_editmesh_vgroup(Object *obedit, BMEditMesh *em, char *r_name, if (BKE_defvert_find_weight(dvert, defgrp_index) > 0.0f) { add_v3_v3(r_cent, eve->co); - totvert++; + indexar_num++; } } - if (totvert) { + if (indexar_num) { const ListBase *defbase = BKE_object_defgroup_list(obedit); bDeformGroup *dg = BLI_findlink(defbase, defgrp_index); BLI_strncpy(r_name, dg->name, sizeof(dg->name)); - mul_v3_fl(r_cent, 1.0f / (float)totvert); + mul_v3_fl(r_cent, 1.0f / (float)indexar_num); return true; } } @@ -139,7 +142,7 @@ static void select_editbmesh_hook(Object *ob, HookModifierData *hmd) BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { if (nr == hmd->indexar[index]) { BM_vert_select_set(em->bm, eve, true); - if (index < hmd->totindex - 1) { + if (index < hmd->indexar_num - 1) { index++; } } @@ -151,12 +154,12 @@ static void select_editbmesh_hook(Object *ob, HookModifierData *hmd) } static int return_editlattice_indexar(Lattice *editlatt, - int *r_tot, int **r_indexar, + int *r_indexar_num, float r_cent[3]) { BPoint *bp; - int *index, nr, totvert = 0, a; + int *index, nr, indexar_num = 0, a; /* count */ a = editlatt->pntsu * editlatt->pntsv * editlatt->pntsw; @@ -164,18 +167,18 @@ static int return_editlattice_indexar(Lattice *editlatt, while (a--) { if (bp->f1 & SELECT) { if (bp->hide == 0) { - totvert++; + indexar_num++; } } bp++; } - if (totvert == 0) { + if (indexar_num == 0) { return 0; } - *r_indexar = index = MEM_mallocN(4 * totvert, "hook indexar"); - *r_tot = totvert; + *r_indexar = index = MEM_mallocN(4 * indexar_num, "hook indexar"); + *r_indexar_num = indexar_num; nr = 0; zero_v3(r_cent); @@ -193,9 +196,9 @@ static int return_editlattice_indexar(Lattice *editlatt, nr++; } - mul_v3_fl(r_cent, 1.0f / (float)totvert); + mul_v3_fl(r_cent, 1.0f / (float)indexar_num); - return totvert; + return indexar_num; } static void select_editlattice_hook(Object *obedit, HookModifierData *hmd) @@ -211,7 +214,7 @@ static void select_editlattice_hook(Object *obedit, HookModifierData *hmd) while (a--) { if (hmd->indexar[index] == nr) { bp->f1 |= SELECT; - if (index < hmd->totindex - 1) { + if (index < hmd->indexar_num - 1) { index++; } } @@ -220,12 +223,15 @@ static void select_editlattice_hook(Object *obedit, HookModifierData *hmd) } } -static int return_editcurve_indexar(Object *obedit, int *r_tot, int **r_indexar, float r_cent[3]) +static int return_editcurve_indexar(Object *obedit, + int **r_indexar, + int *r_indexar_num, + float r_cent[3]) { ListBase *editnurb = object_editcurve_get(obedit); BPoint *bp; BezTriple *bezt; - int *index, a, nr, totvert = 0; + int *index, a, nr, indexar_num = 0; LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_BEZIER) { @@ -233,13 +239,13 @@ static int return_editcurve_indexar(Object *obedit, int *r_tot, int **r_indexar, a = nu->pntsu; while (a--) { if (bezt->f1 & SELECT) { - totvert++; + indexar_num++; } if (bezt->f2 & SELECT) { - totvert++; + indexar_num++; } if (bezt->f3 & SELECT) { - totvert++; + indexar_num++; } bezt++; } @@ -249,18 +255,18 @@ static int return_editcurve_indexar(Object *obedit, int *r_tot, int **r_indexar, a = nu->pntsu * nu->pntsv; while (a--) { if (bp->f1 & SELECT) { - totvert++; + indexar_num++; } bp++; } } } - if (totvert == 0) { + if (indexar_num == 0) { return 0; } - *r_indexar = index = MEM_mallocN(sizeof(*index) * totvert, "hook indexar"); - *r_tot = totvert; + *r_indexar = index = MEM_mallocN(sizeof(*index) * indexar_num, "hook indexar"); + *r_indexar_num = indexar_num; nr = 0; zero_v3(r_cent); @@ -305,21 +311,21 @@ static int return_editcurve_indexar(Object *obedit, int *r_tot, int **r_indexar, } } - mul_v3_fl(r_cent, 1.0f / (float)totvert); + mul_v3_fl(r_cent, 1.0f / (float)indexar_num); - return totvert; + return indexar_num; } static bool object_hook_index_array(Main *bmain, Scene *scene, Object *obedit, - int *r_tot, int **r_indexar, + int *r_indexar_num, char *r_name, float r_cent[3]) { *r_indexar = NULL; - *r_tot = 0; + *r_indexar_num = 0; r_name[0] = 0; switch (obedit->type) { @@ -338,7 +344,7 @@ static bool object_hook_index_array(Main *bmain, BKE_editmesh_looptri_and_normals_calc(em); /* check selected vertices first */ - if (return_editmesh_indexar(em, r_tot, r_indexar, r_cent) == 0) { + if (return_editmesh_indexar(em, r_indexar_num, r_indexar, r_cent) == 0) { return return_editmesh_vgroup(obedit, em, r_name, r_cent); } return true; @@ -347,10 +353,10 @@ static bool object_hook_index_array(Main *bmain, case OB_SURF: ED_curve_editnurb_load(bmain, obedit); ED_curve_editnurb_make(obedit); - return return_editcurve_indexar(obedit, r_tot, r_indexar, r_cent); + return return_editcurve_indexar(obedit, r_indexar, r_indexar_num, r_cent); case OB_LATTICE: { Lattice *lt = obedit->data; - return return_editlattice_indexar(lt->editlatt->latt, r_tot, r_indexar, r_cent); + return return_editlattice_indexar(lt->editlatt->latt, r_indexar, r_indexar_num, r_cent); } default: return false; @@ -371,21 +377,21 @@ static void select_editcurve_hook(Object *obedit, HookModifierData *hmd) while (a--) { if (nr == hmd->indexar[index]) { bezt->f1 |= SELECT; - if (index < hmd->totindex - 1) { + if (index < hmd->indexar_num - 1) { index++; } } nr++; if (nr == hmd->indexar[index]) { bezt->f2 |= SELECT; - if (index < hmd->totindex - 1) { + if (index < hmd->indexar_num - 1) { index++; } } nr++; if (nr == hmd->indexar[index]) { bezt->f3 |= SELECT; - if (index < hmd->totindex - 1) { + if (index < hmd->indexar_num - 1) { index++; } } @@ -400,7 +406,7 @@ static void select_editcurve_hook(Object *obedit, HookModifierData *hmd) while (a--) { if (nr == hmd->indexar[index]) { bp->f1 |= SELECT; - if (index < hmd->totindex - 1) { + if (index < hmd->indexar_num - 1) { index++; } } @@ -514,10 +520,10 @@ static int add_hook_object(const bContext *C, HookModifierData *hmd = NULL; float cent[3]; float pose_mat[4][4]; - int tot, ok, *indexar; + int indexar_num, ok, *indexar; char name[MAX_NAME]; - ok = object_hook_index_array(bmain, scene, obedit, &tot, &indexar, name, cent); + ok = object_hook_index_array(bmain, scene, obedit, &indexar, &indexar_num, name, cent); if (!ok) { BKE_report(reports, RPT_ERROR, "Requires selected vertices or active vertex group"); @@ -545,7 +551,7 @@ static int add_hook_object(const bContext *C, hmd->object = ob; hmd->indexar = indexar; copy_v3_v3(hmd->cent, cent); - hmd->totindex = tot; + hmd->indexar_num = indexar_num; BLI_strncpy(hmd->name, name, sizeof(hmd->name)); unit_m4(pose_mat); @@ -873,7 +879,7 @@ static int object_hook_assign_exec(bContext *C, wmOperator *op) HookModifierData *hmd = NULL; float cent[3]; char name[MAX_NAME]; - int *indexar, tot; + int *indexar, indexar_num; object_hook_from_context(C, &ptr, num, &ob, &hmd); if (hmd == NULL) { @@ -883,7 +889,7 @@ static int object_hook_assign_exec(bContext *C, wmOperator *op) /* assign functionality */ - if (!object_hook_index_array(bmain, scene, ob, &tot, &indexar, name, cent)) { + if (!object_hook_index_array(bmain, scene, ob, &indexar, &indexar_num, name, cent)) { BKE_report(op->reports, RPT_WARNING, "Requires selected vertices or active vertex group"); return OPERATOR_CANCELLED; } @@ -893,7 +899,7 @@ static int object_hook_assign_exec(bContext *C, wmOperator *op) copy_v3_v3(hmd->cent, cent); hmd->indexar = indexar; - hmd->totindex = tot; + hmd->indexar_num = indexar_num; DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 7fedc2c6265..7c3571d3b75 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -541,36 +541,36 @@ bool ED_object_modifier_convert(ReportList *UNUSED(reports), return false; } - int totpart = psys_eval->totcached; - int totchild = psys_eval->totchildcache; + int part_num = psys_eval->totcached; + int child_num = psys_eval->totchildcache; - if (totchild && (part->draw & PART_DRAW_PARENT) == 0) { - totpart = 0; + if (child_num && (part->draw & PART_DRAW_PARENT) == 0) { + part_num = 0; } /* count */ - int totvert = 0, totedge = 0; + int verts_num = 0, edges_num = 0; ParticleCacheKey **cache = psys_eval->pathcache; - for (int a = 0; a < totpart; a++) { + for (int a = 0; a < part_num; a++) { ParticleCacheKey *key = cache[a]; if (key->segments > 0) { - totvert += key->segments + 1; - totedge += key->segments; + verts_num += key->segments + 1; + edges_num += key->segments; } } cache = psys_eval->childcache; - for (int a = 0; a < totchild; a++) { + for (int a = 0; a < child_num; a++) { ParticleCacheKey *key = cache[a]; if (key->segments > 0) { - totvert += key->segments + 1; - totedge += key->segments; + verts_num += key->segments + 1; + edges_num += key->segments; } } - if (totvert == 0) { + if (verts_num == 0) { return false; } @@ -578,11 +578,11 @@ bool ED_object_modifier_convert(ReportList *UNUSED(reports), Object *obn = BKE_object_add(bmain, view_layer, OB_MESH, NULL); Mesh *me = obn->data; - me->totvert = totvert; - me->totedge = totedge; + me->totvert = verts_num; + me->totedge = edges_num; - me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert); - me->medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, totedge); + me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, verts_num); + me->medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, edges_num); me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0); MVert *mvert = me->mvert; @@ -590,7 +590,7 @@ bool ED_object_modifier_convert(ReportList *UNUSED(reports), /* copy coordinates */ cache = psys_eval->pathcache; - for (int a = 0; a < totpart; a++) { + for (int a = 0; a < part_num; a++) { ParticleCacheKey *key = cache[a]; int kmax = key->segments; for (int k = 0; k <= kmax; k++, key++, cvert++, mvert++) { @@ -609,7 +609,7 @@ bool ED_object_modifier_convert(ReportList *UNUSED(reports), } cache = psys_eval->childcache; - for (int a = 0; a < totchild; a++) { + for (int a = 0; a < child_num; a++) { ParticleCacheKey *key = cache[a]; int kmax = key->segments; for (int k = 0; k <= kmax; k++, key++, cvert++, mvert++) { @@ -774,9 +774,9 @@ static bool modifier_apply_obdata( RPT_INFO, "Applied modifier only changed CV points, not tessellated/bevel vertices"); - int numVerts; - float(*vertexCos)[3] = BKE_curve_nurbs_vert_coords_alloc(&curve_eval->nurb, &numVerts); - mti->deformVerts(md_eval, &mectx, NULL, vertexCos, numVerts); + int verts_num; + float(*vertexCos)[3] = BKE_curve_nurbs_vert_coords_alloc(&curve_eval->nurb, &verts_num); + mti->deformVerts(md_eval, &mectx, NULL, vertexCos, verts_num); BKE_curve_nurbs_vert_coords_apply(&curve->nurb, vertexCos, false); MEM_freeN(vertexCos); @@ -793,9 +793,9 @@ static bool modifier_apply_obdata( return false; } - int numVerts; - float(*vertexCos)[3] = BKE_lattice_vert_coords_alloc(lattice, &numVerts); - mti->deformVerts(md_eval, &mectx, NULL, vertexCos, numVerts); + int verts_num; + float(*vertexCos)[3] = BKE_lattice_vert_coords_alloc(lattice, &verts_num); + mti->deformVerts(md_eval, &mectx, NULL, vertexCos, verts_num); BKE_lattice_vert_coords_apply(lattice, vertexCos); MEM_freeN(vertexCos); @@ -2781,9 +2781,9 @@ static int meshdeform_bind_exec(bContext *C, wmOperator *op) MEM_SAFE_FREE(mmd->dynverts); MEM_SAFE_FREE(mmd->bindweights); /* Deprecated */ MEM_SAFE_FREE(mmd->bindcos); /* Deprecated */ - mmd->totvert = 0; - mmd->totcagevert = 0; - mmd->totinfluence = 0; + mmd->verts_num = 0; + mmd->cage_verts_num = 0; + mmd->influences_num = 0; } else { /* Force modifier to run, it will call binding routine @@ -3119,7 +3119,7 @@ static int laplaciandeform_bind_exec(bContext *C, wmOperator *op) /* This is hard to know from the modifier itself whether the evaluation is * happening for binding or not. So we copy all the required data here. */ - lmd->total_verts = lmd_eval->total_verts; + lmd->verts_num = lmd_eval->verts_num; if (lmd_eval->vertexco == NULL) { MEM_SAFE_FREE(lmd->vertexco); } diff --git a/source/blender/editors/object/object_transform.cc b/source/blender/editors/object/object_transform.cc index 24425b5a991..afd2c048379 100644 --- a/source/blender/editors/object/object_transform.cc +++ b/source/blender/editors/object/object_transform.cc @@ -1695,13 +1695,13 @@ static void object_apply_rotation(Object *ob, const float rmat[3][3]) static void object_apply_location(Object *ob, const float loc[3]) { /* quick but weak */ - Object ob_prev = *ob; + Object ob_prev = blender::dna::shallow_copy(*ob); float mat[4][4]; copy_m4_m4(mat, ob->obmat); copy_v3_v3(mat[3], loc); BKE_object_apply_mat4(ob, mat, true, true); copy_v3_v3(mat[3], ob->loc); - *ob = ob_prev; + *ob = blender::dna::shallow_copy(ob_prev); copy_v3_v3(ob->loc, mat[3]); } diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c index 5bc062eb177..e8ceb97ed7a 100644 --- a/source/blender/editors/physics/dynamicpaint_ops.c +++ b/source/blender/editors/physics/dynamicpaint_ops.c @@ -399,27 +399,27 @@ static void dynamicPaint_bakeImageSequence(DynamicPaintBakeJob *job) * Save output images */ { - char filename[FILE_MAX]; + char filepath[FILE_MAX]; /* primary output layer */ if (surface->flags & MOD_DPAINT_OUT1) { /* set filepath */ BLI_join_dirfile( - filename, sizeof(filename), surface->image_output_path, surface->output_name); - BLI_path_frame(filename, frame, 4); + filepath, sizeof(filepath), surface->image_output_path, surface->output_name); + BLI_path_frame(filepath, frame, 4); /* save image */ - dynamicPaint_outputSurfaceImage(surface, filename, 0); + dynamicPaint_outputSurfaceImage(surface, filepath, 0); } /* secondary output */ if (surface->flags & MOD_DPAINT_OUT2 && surface->type == MOD_DPAINT_SURFACE_T_PAINT) { /* set filepath */ BLI_join_dirfile( - filename, sizeof(filename), surface->image_output_path, surface->output_name2); - BLI_path_frame(filename, frame, 4); + filepath, sizeof(filepath), surface->image_output_path, surface->output_name2); + BLI_path_frame(filepath, frame, 4); /* save image */ - dynamicPaint_outputSurfaceImage(surface, filename, 1); + dynamicPaint_outputSurfaceImage(surface, filepath, 1); } } } diff --git a/source/blender/editors/physics/rigidbody_world.c b/source/blender/editors/physics/rigidbody_world.c index fa90d1e64d6..a77d70d5d9b 100644 --- a/source/blender/editors/physics/rigidbody_world.c +++ b/source/blender/editors/physics/rigidbody_world.c @@ -192,7 +192,7 @@ void RIGIDBODY_OT_world_export(wmOperatorType *ot) FILE_TYPE_FOLDER, FILE_SPECIAL, FILE_SAVE, - FILE_RELPATH, + WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY, FILE_SORT_DEFAULT); } diff --git a/source/blender/editors/render/render_preview.cc b/source/blender/editors/render/render_preview.cc index 16a3e799779..ef0f0b6225c 100644 --- a/source/blender/editors/render/render_preview.cc +++ b/source/blender/editors/render/render_preview.cc @@ -1679,19 +1679,19 @@ class PreviewLoadJob { PreviewLoadJob(); ~PreviewLoadJob(); - static PreviewLoadJob &ensure_job(wmWindowManager *, wmWindow *); - static void load_jobless(PreviewImage *, eIconSizes); + static PreviewLoadJob &ensure_job(wmWindowManager *wm, wmWindow *win); + static void load_jobless(PreviewImage *preview, eIconSizes icon_size); - void push_load_request(PreviewImage *, eIconSizes); + void push_load_request(PreviewImage *preview, eIconSizes icon_size); private: - static void run_fn(void *, short *, short *, float *); - static void update_fn(void *); - static void end_fn(void *); - static void free_fn(void *); + static void run_fn(void *customdata, short *stop, short *do_update, float *progress); + static void update_fn(void *customdata); + static void end_fn(void *customdata); + static void free_fn(void *customdata); /** Mark a single requested preview as being done, remove the request. */ - static void finish_request(RequestedPreview &); + static void finish_request(RequestedPreview &request); }; PreviewLoadJob::PreviewLoadJob() : todo_queue_(BLI_thread_queue_init()) diff --git a/source/blender/editors/scene/CMakeLists.txt b/source/blender/editors/scene/CMakeLists.txt index 7f687212066..12043ac2957 100644 --- a/source/blender/editors/scene/CMakeLists.txt +++ b/source/blender/editors/scene/CMakeLists.txt @@ -8,8 +8,8 @@ set(INC ../../depsgraph ../../makesdna ../../makesrna - ../../windowmanager ../../sequencer + ../../windowmanager ) set(INC_SYS diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index af84f6f99a9..30bf23e0987 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1972,6 +1972,7 @@ void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area) static void area_offscreen_init(ScrArea *area) { + area->flag |= AREA_FLAG_OFFSCREEN; area->type = BKE_spacetype_from_id(area->spacetype); if (area->type == NULL) { diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt index 7392f05aea4..d0ff1d09c39 100644 --- a/source/blender/editors/sculpt_paint/CMakeLists.txt +++ b/source/blender/editors/sculpt_paint/CMakeLists.txt @@ -13,8 +13,8 @@ set(INC ../../gpu ../../imbuf ../../makesdna - ../../nodes ../../makesrna + ../../nodes ../../render ../../windowmanager ../../../../intern/atomic @@ -38,9 +38,9 @@ set(SRC paint_curve_undo.c paint_hide.c paint_image.cc - paint_image_ops_paint.cc paint_image_2d.c paint_image_2d_curve_mask.cc + paint_image_ops_paint.cc paint_image_proj.c paint_mask.c paint_ops.c diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_3d_brush.cc b/source/blender/editors/sculpt_paint/curves_sculpt_3d_brush.cc index 94c0f5536b7..945bb09c0c6 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_3d_brush.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_3d_brush.cc @@ -65,7 +65,7 @@ static std::optional<float3> find_curves_brush_position(const CurvesGeometry &cu /* New candidate is in inner radius while old one is not. */ return true; } - else if (b.depth_sq_cu < a.depth_sq_cu) { + if (b.depth_sq_cu < a.depth_sq_cu) { /* Both candidates are in inner radius, but new one is closer to the camera. */ return true; } @@ -93,7 +93,7 @@ static std::optional<float3> find_curves_brush_position(const CurvesGeometry &cu BrushPositionCandidate best_candidate = init; for (const int curve_i : curves_range) { - const IndexRange points = curves.range_for_curve(curve_i); + const IndexRange points = curves.points_for_curve(curve_i); const int tot_segments = points.size() - 1; for (const int segment_i : IndexRange(tot_segments)) { diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc index e57a6e43983..809511d0106 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc @@ -55,7 +55,7 @@ class AddOperation : public CurvesSculptStrokeOperation { friend struct AddOperationExecutor; public: - ~AddOperation() + ~AddOperation() override { if (curve_roots_kdtree_ != nullptr) { BLI_kdtree_3d_free(curve_roots_kdtree_); @@ -174,8 +174,8 @@ struct AddOperationExecutor { use_interpolation_ = interpolate_length_ || interpolate_shape_; new_curve_length_ = curves_sculpt_->curve_length; - tot_old_curves_ = curves_->curves_size(); - tot_old_points_ = curves_->points_size(); + tot_old_curves_ = curves_->curves_num(); + tot_old_points_ = curves_->points_num(); if (add_amount_ == 0) { return; @@ -216,8 +216,8 @@ struct AddOperationExecutor { const int tot_added_curves = added_points.bary_coords.size(); const int tot_added_points = tot_added_curves * points_per_curve_; - curves_->resize(curves_->points_size() + tot_added_points, - curves_->curves_size() + tot_added_curves); + curves_->resize(curves_->points_num() + tot_added_points, + curves_->curves_num() + tot_added_curves); threading::parallel_invoke([&]() { this->initialize_curve_offsets(tot_added_curves); }, [&]() { this->initialize_attributes(added_points); }); @@ -515,7 +515,7 @@ struct AddOperationExecutor { void ensure_curve_roots_kdtree() { if (self_->curve_roots_kdtree_ == nullptr) { - self_->curve_roots_kdtree_ = BLI_kdtree_3d_new(curves_->curves_size()); + self_->curve_roots_kdtree_ = BLI_kdtree_3d_new(curves_->curves_num()); for (const int curve_i : curves_->curves_range()) { const int root_point_i = curves_->offsets()[curve_i]; const float3 &root_pos_cu = curves_->positions()[root_point_i]; @@ -609,7 +609,7 @@ struct AddOperationExecutor { const Span<NeighborInfo> neighbors = neighbors_per_curve[added_curve_i]; float length_sum = 0.0f; for (const NeighborInfo &neighbor : neighbors) { - const IndexRange neighbor_points = curves_->range_for_curve(neighbor.index); + const IndexRange neighbor_points = curves_->points_for_curve(neighbor.index); float neighbor_length = 0.0f; const int tot_segments = neighbor_points.size() - 1; for (const int segment_i : IndexRange(tot_segments)) { @@ -744,7 +744,7 @@ struct AddOperationExecutor { float normal_rotation_cu[3][3]; rotation_between_vecs_to_mat3(normal_rotation_cu, neighbor_normal_cu, normal_cu); - const IndexRange neighbor_points = curves_->range_for_curve(neighbor_curve_i); + const IndexRange neighbor_points = curves_->points_for_curve(neighbor_curve_i); const float3 &neighbor_root_cu = positions_cu[neighbor_points[0]]; /* Use a temporary #PolySpline, because that's the easiest way to resample an diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc b/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc index 35b2b2ce956..d062fe32cfe 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc @@ -202,7 +202,7 @@ struct CombOperationExecutor { Vector<int> &local_changed_curves = r_changed_curves.local(); for (const int curve_i : curves_range) { bool curve_changed = false; - const IndexRange points = curves_->range_for_curve(curve_i); + const IndexRange points = curves_->points_for_curve(curve_i); for (const int point_i : points.drop_front(1)) { const float3 old_pos_cu = positions_cu[point_i]; @@ -274,7 +274,7 @@ struct CombOperationExecutor { Vector<int> &local_changed_curves = r_changed_curves.local(); for (const int curve_i : curves_range) { bool curve_changed = false; - const IndexRange points = curves_->range_for_curve(curve_i); + const IndexRange points = curves_->points_for_curve(curve_i); for (const int point_i : points.drop_front(1)) { const float3 pos_old_cu = positions_cu[point_i]; @@ -324,10 +324,10 @@ struct CombOperationExecutor { void initialize_segment_lengths() { const Span<float3> positions_cu = curves_->positions(); - self_->segment_lengths_cu_.reinitialize(curves_->points_size()); + self_->segment_lengths_cu_.reinitialize(curves_->points_num()); threading::parallel_for(curves_->curves_range(), 128, [&](const IndexRange range) { for (const int curve_i : range) { - const IndexRange points = curves_->range_for_curve(curve_i); + const IndexRange points = curves_->points_for_curve(curve_i); for (const int point_i : points.drop_back(1)) { const float3 &p1_cu = positions_cu[point_i]; const float3 &p2_cu = positions_cu[point_i + 1]; @@ -349,7 +349,7 @@ struct CombOperationExecutor { threading::parallel_for_each(changed_curves, [&](const Vector<int> &changed_curves) { threading::parallel_for(changed_curves.index_range(), 256, [&](const IndexRange range) { for (const int curve_i : changed_curves.as_span().slice(range)) { - const IndexRange points = curves_->range_for_curve(curve_i); + const IndexRange points = curves_->points_for_curve(curve_i); for (const int segment_i : IndexRange(points.size() - 1)) { const float3 &p1_cu = positions_cu[points[segment_i]]; float3 &p2_cu = positions_cu[points[segment_i] + 1]; diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc b/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc index efe85dc132a..ae87f414dd5 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc @@ -70,7 +70,7 @@ class DeleteOperation : public CurvesSculptStrokeOperation { Vector<int64_t> indices; const IndexMask curves_to_remove = index_mask_ops::find_indices_based_on_predicate( curves.curves_range(), 512, indices, [&](const int curve_i) { - const IndexRange point_range = curves.range_for_curve(curve_i); + const IndexRange point_range = curves.points_for_curve(curve_i); for (const int segment_i : IndexRange(point_range.size() - 1)) { const float3 pos1 = positions[point_range[segment_i]]; const float3 pos2 = positions[point_range[segment_i + 1]]; diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc index b9a019a012c..382f0529daa 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc @@ -117,7 +117,7 @@ class ShrinkOperation : public CurvesSculptStrokeOperation { threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange curves_range) { for (const int curve_i : curves_range) { - const IndexRange curve_points = curves.range_for_curve(curve_i); + const IndexRange curve_points = curves.points_for_curve(curve_i); const int last_point_i = curve_points.last(); const float3 old_tip_position = positions[last_point_i]; @@ -304,7 +304,7 @@ class DensityAddOperation : public CurvesSculptStrokeOperation { if (old_kdtree_ == nullptr && minimum_distance > 0.0f) { old_kdtree_ = this->kdtree_from_curve_roots_and_positions(curves, curves.curves_range(), {}); - old_kdtree_size_ = curves.curves_size(); + old_kdtree_size_ = curves.curves_num(); } float density; @@ -525,7 +525,7 @@ class DensityAddOperation : public CurvesSculptStrokeOperation { { Array<bool> elimination_mask(points.positions.size(), false); - const int curves_added_previously = curves.curves_size() - old_kdtree_size_; + const int curves_added_previously = curves.curves_num() - old_kdtree_size_; KDTree_3d *new_points_kdtree = this->kdtree_from_curve_roots_and_positions( curves, IndexRange(old_kdtree_size_, curves_added_previously), points.positions); @@ -589,14 +589,14 @@ class DensityAddOperation : public CurvesSculptStrokeOperation { const int tot_new_curves = new_points.positions.size(); const int points_per_curve = 8; - curves.resize(curves.points_size() + tot_new_curves * points_per_curve, - curves.curves_size() + tot_new_curves); + curves.resize(curves.points_num() + tot_new_curves * points_per_curve, + curves.curves_num() + tot_new_curves); MutableSpan<int> offsets = curves.offsets(); MutableSpan<float3> positions = curves.positions(); for (const int i : IndexRange(tot_new_curves)) { - const int curve_i = curves.curves_size() - tot_new_curves + i; + const int curve_i = curves.curves_num() - tot_new_curves + i; const int first_point_i = offsets[curve_i]; offsets[curve_i + 1] = offsets[curve_i] + points_per_curve; diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc b/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc index bd6b238ea72..682cd3b47ca 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc @@ -83,7 +83,7 @@ class SnakeHookOperation : public CurvesSculptStrokeOperation { threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange curves_range) { for (const int curve_i : curves_range) { - const IndexRange curve_points = curves.range_for_curve(curve_i); + const IndexRange curve_points = curves.points_for_curve(curve_i); const int last_point_i = curve_points.last(); const float3 old_position = positions[last_point_i]; diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index 2b55eb379cc..36dac998303 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -1076,7 +1076,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex const int trim_totpolys = (2 * (tot_screen_points - 2)) + (2 * tot_screen_points); trim_operation->mesh = BKE_mesh_new_nomain( trim_totverts, 0, 0, trim_totpolys * 3, trim_totpolys); - trim_operation->true_mesh_co = MEM_malloc_arrayN(trim_totverts, 3 * sizeof(float), "mesh orco"); + trim_operation->true_mesh_co = MEM_malloc_arrayN(trim_totverts, sizeof(float[3]), "mesh orco"); float depth_front = trim_operation->depth_front; float depth_back = trim_operation->depth_back; @@ -1130,7 +1130,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex /* Get the triangulation for the front/back poly. */ const int tot_tris_face = tot_screen_points - 2; - uint(*r_tris)[3] = MEM_malloc_arrayN(tot_tris_face, 3 * sizeof(uint), "tris"); + uint(*r_tris)[3] = MEM_malloc_arrayN(tot_tris_face, sizeof(uint[3]), "tris"); BLI_polyfill_calc(screen_points, tot_screen_points, 0, r_tris); /* Write the front face triangle indices. */ diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.c b/source/blender/editors/sculpt_paint/sculpt_boundary.c index 70f8f2127b4..8bf09ce3d05 100644 --- a/source/blender/editors/sculpt_paint/sculpt_boundary.c +++ b/source/blender/editors/sculpt_paint/sculpt_boundary.c @@ -532,9 +532,8 @@ static void sculpt_boundary_bend_data_init(SculptSession *ss, SculptBoundary *bo { const int totvert = SCULPT_vertex_count_get(ss); boundary->bend.pivot_rotation_axis = MEM_calloc_arrayN( - totvert, 3 * sizeof(float), "pivot rotation axis"); - boundary->bend.pivot_positions = MEM_calloc_arrayN( - totvert, 3 * sizeof(float), "pivot positions"); + totvert, sizeof(float[3]), "pivot rotation axis"); + boundary->bend.pivot_positions = MEM_calloc_arrayN(totvert, sizeof(float[3]), "pivot positions"); for (int i = 0; i < totvert; i++) { if (boundary->edit_info[i].num_propagation_steps != boundary->max_propagation_steps) { @@ -567,7 +566,7 @@ static void sculpt_boundary_bend_data_init(SculptSession *ss, SculptBoundary *bo static void sculpt_boundary_slide_data_init(SculptSession *ss, SculptBoundary *boundary) { const int totvert = SCULPT_vertex_count_get(ss); - boundary->slide.directions = MEM_calloc_arrayN(totvert, 3 * sizeof(float), "slide directions"); + boundary->slide.directions = MEM_calloc_arrayN(totvert, sizeof(float[3]), "slide directions"); for (int i = 0; i < totvert; i++) { if (boundary->edit_info[i].num_propagation_steps != boundary->max_propagation_steps) { @@ -592,7 +591,7 @@ static void sculpt_boundary_twist_data_init(SculptSession *ss, SculptBoundary *b { zero_v3(boundary->twist.pivot_position); float(*poly_verts)[3] = MEM_malloc_arrayN( - boundary->num_vertices, sizeof(float) * 3, "poly verts"); + boundary->num_vertices, sizeof(float[3]), "poly verts"); for (int i = 0; i < boundary->num_vertices; i++) { add_v3_v3(boundary->twist.pivot_position, SCULPT_vertex_co_get(ss, boundary->vertices[i])); copy_v3_v3(poly_verts[i], SCULPT_vertex_co_get(ss, boundary->vertices[i])); diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.c b/source/blender/editors/sculpt_paint/sculpt_smooth.c index d12ae75464f..53babc3d36d 100644 --- a/source/blender/editors/sculpt_paint/sculpt_smooth.c +++ b/source/blender/editors/sculpt_paint/sculpt_smooth.c @@ -255,7 +255,7 @@ static void SCULPT_enhance_details_brush(Sculpt *sd, if (SCULPT_stroke_is_first_brush_step(ss->cache)) { const int totvert = SCULPT_vertex_count_get(ss); ss->cache->detail_directions = MEM_malloc_arrayN( - totvert, 3 * sizeof(float), "details directions"); + totvert, sizeof(float[3]), "details directions"); for (int i = 0; i < totvert; i++) { float avg[3]; diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index f0ada312d82..d33cf70e117 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -1706,8 +1706,8 @@ static const EnumPropertyItem prop_actkeys_snap_types[] = { "NEAREST_FRAME", 0, "Selection to Nearest Frame", - "Snap selected keyframes to the nearest (whole) frame (use to fix accidental subframe " - "offsets)"}, + "Snap selected keyframes to the nearest (whole) frame " + "(use to fix accidental sub-frame offsets)"}, {ACTKEYS_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index f91ed5eb4f3..10fb008049d 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -207,13 +207,13 @@ static int file_browse_exec(bContext *C, wmOperator *op) /* Do this first so '//' isn't converted to '//\' on windows. */ BLI_path_slash_ensure(path); if (is_relative) { - const int path_len = BLI_strncpy_rlen(path, str, FILE_MAX); BLI_path_rel(path, BKE_main_blendfile_path(bmain)); - str = MEM_reallocN(str, path_len + 2); - BLI_strncpy(str, path, FILE_MAX); + str_len = strlen(path); + str = MEM_reallocN(str, str_len + 1); + memcpy(str, path, str_len + 1); } else { - str = MEM_reallocN(str, str_len + 2); + str = MEM_reallocN(str, str_len + 1); } } else { diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 6660ff3b78b..e7bdbfe7c68 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -876,24 +876,24 @@ static int slide_marker_modal(bContext *C, wmOperator *op, const wmEvent *event) BKE_tracking_marker_clamp(data->marker, CLAMP_PAT_DIM); } else if (data->action == SLIDE_ACTION_TILT_SIZE) { - float start[2], end[2]; - float scale = 1.0f, angle = 0.0f; - float mval[2]; - - if (data->accurate) { - mval[0] = data->mval[0] + (event->mval[0] - data->mval[0]) / 5.0f; - mval[1] = data->mval[1] + (event->mval[1] - data->mval[1]) / 5.0f; - } - else { - mval[0] = event->mval[0]; - mval[1] = event->mval[1]; - } + const float mouse_delta[2] = {dx, dy}; + /* Vector which connects marker position with tilt/scale sliding area before sliding + * began. */ + float start[2]; sub_v2_v2v2(start, data->spos, data->old_pos); + start[0] *= data->width; + start[1] *= data->height; - ED_clip_point_stable_pos(sc, region, mval[0], mval[1], &end[0], &end[1]); + /* Vector which connects marker position with tilt/scale sliding area with the sliding + * delta applied. */ + float end[2]; + add_v2_v2v2(end, data->spos, mouse_delta); sub_v2_v2(end, data->old_pos); + end[0] *= data->width; + end[1] *= data->height; + float scale = 1.0f; if (len_squared_v2(start) != 0.0f) { scale = len_v2(end) / len_v2(start); @@ -902,7 +902,7 @@ static int slide_marker_modal(bContext *C, wmOperator *op, const wmEvent *event) } } - angle = -angle_signed_v2v2(start, end); + const float angle = -angle_signed_v2v2(start, end); for (int a = 0; a < 4; a++) { float vec[2]; diff --git a/source/blender/editors/space_file/CMakeLists.txt b/source/blender/editors/space_file/CMakeLists.txt index c4c6fa01025..b8c28e354da 100644 --- a/source/blender/editors/space_file/CMakeLists.txt +++ b/source/blender/editors/space_file/CMakeLists.txt @@ -79,6 +79,9 @@ if(WITH_IMAGE_HDR) add_definitions(-DWITH_HDR) endif() +if(WITH_IMAGE_WEBP) + add_definitions(-DWITH_WEBP) +endif() if(WITH_FREESTYLE) add_definitions(-DWITH_FREESTYLE) diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 180e30a11d4..ceac53bde6b 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -1056,10 +1056,10 @@ void filelist_tag_needs_filtering(FileList *filelist) void filelist_filter(FileList *filelist) { int num_filtered = 0; - const int num_files = filelist->filelist.nbr_entries; + const int num_files = filelist->filelist.entries_num; FileListInternEntry **filtered_tmp, *file; - if (ELEM(filelist->filelist.nbr_entries, FILEDIR_NBR_ENTRIES_UNSET, 0)) { + if (ELEM(filelist->filelist.entries_num, FILEDIR_NBR_ENTRIES_UNSET, 0)) { return; } @@ -1099,8 +1099,8 @@ void filelist_filter(FileList *filelist) memcpy(filelist->filelist_intern.filtered, filtered_tmp, sizeof(*filelist->filelist_intern.filtered) * (size_t)num_filtered); - filelist->filelist.nbr_entries_filtered = num_filtered; - // printf("Filetered: %d over %d entries\n", num_filtered, filelist->filelist.nbr_entries); + filelist->filelist.entries_filtered_num = num_filtered; + // printf("Filetered: %d over %d entries\n", num_filtered, filelist->filelist.entries_num); filelist_cache_clear(&filelist->filelist_cache, filelist->filelist_cache.size); filelist->flags &= ~FL_NEED_FILTERING; @@ -1552,8 +1552,8 @@ static void filelist_direntryarr_free(FileDirEntryArr *array) #else BLI_assert(BLI_listbase_is_empty(&array->entries)); #endif - array->nbr_entries = FILEDIR_NBR_ENTRIES_UNSET; - array->nbr_entries_filtered = FILEDIR_NBR_ENTRIES_UNSET; + array->entries_num = FILEDIR_NBR_ENTRIES_UNSET; + array->entries_filtered_num = FILEDIR_NBR_ENTRIES_UNSET; } static void filelist_intern_entry_free(FileListInternEntry *entry) @@ -1874,7 +1874,7 @@ FileList *filelist_new(short type) filelist_cache_init(&p->filelist_cache, FILELIST_ENTRYCACHESIZE_DEFAULT); p->selection_state = BLI_ghash_new(BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, __func__); - p->filelist.nbr_entries = FILEDIR_NBR_ENTRIES_UNSET; + p->filelist.entries_num = FILEDIR_NBR_ENTRIES_UNSET; filelist_settype(p, type); return p; @@ -1979,9 +1979,9 @@ static void filelist_clear_main_files(FileList *filelist, const int removed_files = filelist_intern_free_main_files(&filelist->filelist_intern); - filelist->filelist.nbr_entries -= removed_files; - filelist->filelist.nbr_entries_filtered = FILEDIR_NBR_ENTRIES_UNSET; - BLI_assert(filelist->filelist.nbr_entries > FILEDIR_NBR_ENTRIES_UNSET); + filelist->filelist.entries_num -= removed_files; + filelist->filelist.entries_filtered_num = FILEDIR_NBR_ENTRIES_UNSET; + BLI_assert(filelist->filelist.entries_num > FILEDIR_NBR_ENTRIES_UNSET); if (do_selection && filelist->selection_state) { BLI_ghash_clear(filelist->selection_state, NULL, NULL); @@ -2167,7 +2167,7 @@ int filelist_files_ensure(FileList *filelist) filelist_filter(filelist); } - return filelist->filelist.nbr_entries_filtered; + return filelist->filelist.entries_filtered_num; } static FileDirEntry *filelist_file_create_entry(FileList *filelist, const int index) @@ -2226,7 +2226,7 @@ FileDirEntry *filelist_file_ex(struct FileList *filelist, const int index, const const size_t cache_size = cache->size; int old_index; - if ((index < 0) || (index >= filelist->filelist.nbr_entries_filtered)) { + if ((index < 0) || (index >= filelist->filelist.entries_filtered_num)) { return ret; } @@ -2274,7 +2274,7 @@ FileDirEntry *filelist_file(struct FileList *filelist, int index) int filelist_file_find_path(struct FileList *filelist, const char *filename) { - if (filelist->filelist.nbr_entries_filtered == FILEDIR_NBR_ENTRIES_UNSET) { + if (filelist->filelist.entries_filtered_num == FILEDIR_NBR_ENTRIES_UNSET) { return -1; } @@ -2282,7 +2282,7 @@ int filelist_file_find_path(struct FileList *filelist, const char *filename) * This is only used to find again renamed entry, * annoying but looks hairy to get rid of it currently. */ - for (int fidx = 0; fidx < filelist->filelist.nbr_entries_filtered; fidx++) { + for (int fidx = 0; fidx < filelist->filelist.entries_filtered_num; fidx++) { FileListInternEntry *entry = filelist->filelist_intern.filtered[fidx]; if (STREQ(entry->relpath, filename)) { return fidx; @@ -2294,11 +2294,11 @@ int filelist_file_find_path(struct FileList *filelist, const char *filename) int filelist_file_find_id(const FileList *filelist, const ID *id) { - if (filelist->filelist.nbr_entries_filtered == FILEDIR_NBR_ENTRIES_UNSET) { + if (filelist->filelist.entries_filtered_num == FILEDIR_NBR_ENTRIES_UNSET) { return -1; } - for (int fidx = 0; fidx < filelist->filelist.nbr_entries_filtered; fidx++) { + for (int fidx = 0; fidx < filelist->filelist.entries_filtered_num; fidx++) { FileListInternEntry *entry = filelist->filelist_intern.filtered[fidx]; if (entry->local_data.id == id) { return fidx; @@ -2408,23 +2408,23 @@ bool filelist_file_cache_block(struct FileList *filelist, const int index) FileListEntryCache *cache = &filelist->filelist_cache; const size_t cache_size = cache->size; - const int nbr_entries = filelist->filelist.nbr_entries_filtered; + const int entries_num = filelist->filelist.entries_filtered_num; int start_index = max_ii(0, index - (cache_size / 2)); - int end_index = min_ii(nbr_entries, index + (cache_size / 2)); + int end_index = min_ii(entries_num, index + (cache_size / 2)); int i; const bool full_refresh = (filelist->flags & FL_IS_READY) == 0; - if ((index < 0) || (index >= nbr_entries)) { - // printf("Wrong index %d ([%d:%d])", index, 0, nbr_entries); + if ((index < 0) || (index >= entries_num)) { + // printf("Wrong index %d ([%d:%d])", index, 0, entries_num); return false; } /* Maximize cached range! */ if ((end_index - start_index) < cache_size) { if (start_index == 0) { - end_index = min_ii(nbr_entries, start_index + cache_size); + end_index = min_ii(entries_num, start_index + cache_size); } - else if (end_index == nbr_entries) { + else if (end_index == entries_num) { start_index = max_ii(0, end_index - cache_size); } } @@ -2861,7 +2861,7 @@ int ED_file_extension_icon(const char *path) int filelist_needs_reading(FileList *filelist) { - return (filelist->filelist.nbr_entries == FILEDIR_NBR_ENTRIES_UNSET) || + return (filelist->filelist.entries_num == FILEDIR_NBR_ENTRIES_UNSET) || filelist_needs_force_reset(filelist); } @@ -2926,8 +2926,8 @@ void filelist_entries_select_index_range_set( FileList *filelist, FileSelection *sel, FileSelType select, uint flag, FileCheckType check) { /* select all valid files between first and last indicated */ - if ((sel->first >= 0) && (sel->first < filelist->filelist.nbr_entries_filtered) && - (sel->last >= 0) && (sel->last < filelist->filelist.nbr_entries_filtered)) { + if ((sel->first >= 0) && (sel->first < filelist->filelist.entries_filtered_num) && + (sel->last >= 0) && (sel->last < filelist->filelist.entries_filtered_num)) { int current_file; for (current_file = sel->first; current_file <= sel->last; current_file++) { filelist_entry_select_index_set(filelist, current_file, select, flag, check); @@ -2963,7 +2963,7 @@ uint filelist_entry_select_index_get(FileList *filelist, const int index, FileCh bool filelist_entry_is_selected(FileList *filelist, const int index) { - BLI_assert(index >= 0 && index < filelist->filelist.nbr_entries_filtered); + BLI_assert(index >= 0 && index < filelist->filelist.entries_filtered_num); FileListInternEntry *intern_entry = filelist->filelist_intern.filtered[index]; /* BLI_ghash_lookup returns NULL if not found, which gets mapped to 0, which gets mapped to @@ -3030,13 +3030,13 @@ static int filelist_readjob_list_dir(const char *root, const bool skip_currpar) { struct direntry *files; - int nbr_files, nbr_entries = 0; + int entries_num = 0; /* Full path of the item. */ char full_path[FILE_MAX]; - nbr_files = BLI_filelist_dir_contents(root, &files); + const int files_num = BLI_filelist_dir_contents(root, &files); if (files) { - int i = nbr_files; + int i = files_num; while (i--) { FileListInternEntry *entry; @@ -3110,11 +3110,11 @@ static int filelist_readjob_list_dir(const char *root, #endif BLI_addtail(entries, entry); - nbr_entries++; + entries_num++; } - BLI_filelist_free(files, nbr_files); + BLI_filelist_free(files, files_num); } - return nbr_entries; + return entries_num; } typedef enum ListLibOptions { @@ -3370,13 +3370,13 @@ static void filelist_readjob_main_recursive(Main *bmain, FileList *filelist) if (filelist->dir[0] == 0) { /* make directories */ # ifdef WITH_FREESTYLE - filelist->filelist.nbr_entries = 27; + filelist->filelist.entries_num = 27; # else - filelist->filelist.nbr_entries = 26; + filelist->filelist.entries_num = 26; # endif - filelist_resize(filelist, filelist->filelist.nbr_entries); + filelist_resize(filelist, filelist->filelist.entries_num); - for (a = 0; a < filelist->filelist.nbr_entries; a++) { + for (a = 0; a < filelist->filelist.entries_num; a++) { filelist->filelist.entries[a].typeflag |= FILE_TYPE_DIR; } @@ -3419,20 +3419,20 @@ static void filelist_readjob_main_recursive(Main *bmain, FileList *filelist) return; } - filelist->filelist.nbr_entries = 0; + filelist->filelist.entries_num = 0; for (id = lb->first; id; id = id->next) { if (!(filelist->filter_data.flags & FLF_HIDE_DOT) || id->name[2] != '.') { - filelist->filelist.nbr_entries++; + filelist->filelist.entries_num++; } } /* XXX TODO: if data-browse or append/link #FLF_HIDE_PARENT has to be set. */ if (!(filelist->filter_data.flags & FLF_HIDE_PARENT)) { - filelist->filelist.nbr_entries++; + filelist->filelist.entries_num++; } - if (filelist->filelist.nbr_entries > 0) { - filelist_resize(filelist, filelist->filelist.nbr_entries); + if (filelist->filelist.entries_num > 0) { + filelist_resize(filelist, filelist->filelist.entries_num); } files = filelist->filelist.entries; @@ -3538,11 +3538,11 @@ typedef struct FileListReadJob { static void filelist_readjob_append_entries(FileListReadJob *job_params, ListBase *from_entries, - int nbr_from_entries, + int from_entries_num, short *do_update) { - BLI_assert(BLI_listbase_count(from_entries) == nbr_from_entries); - if (nbr_from_entries <= 0) { + BLI_assert(BLI_listbase_count(from_entries) == from_entries_num); + if (from_entries_num <= 0) { *do_update = false; return; } @@ -3550,7 +3550,7 @@ static void filelist_readjob_append_entries(FileListReadJob *job_params, FileList *filelist = job_params->tmp_filelist; /* Use the thread-safe filelist queue. */ BLI_mutex_lock(&job_params->lock); BLI_movelisttolist(&filelist->filelist.entries, from_entries); - filelist->filelist.nbr_entries += nbr_from_entries; + filelist->filelist.entries_num += from_entries_num; BLI_mutex_unlock(&job_params->lock); *do_update = true; @@ -3606,7 +3606,7 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib, char filter_glob[FILE_MAXFILE]; const char *root = filelist->filelist.root; const int max_recursion = filelist->max_recursion; - int nbr_done_dirs = 0, nbr_todo_dirs = 1; + int dirs_done_count = 0, dirs_todo_count = 1; todo_dirs = BLI_stack_new(sizeof(*td_dir), __func__); td_dir = BLI_stack_push_r(todo_dirs); @@ -3626,7 +3626,7 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib, while (!BLI_stack_is_empty(todo_dirs) && !(*stop)) { FileListInternEntry *entry; - int nbr_entries = 0; + int entries_num = 0; char *subdir; char rel_subdir[FILE_MAX_LIBEXTRA]; @@ -3666,15 +3666,15 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib, if (filelist->asset_library_ref) { list_lib_options |= LIST_LIB_ASSETS_ONLY; } - nbr_entries = filelist_readjob_list_lib( + entries_num = filelist_readjob_list_lib( subdir, &entries, list_lib_options, &indexer_runtime); - if (nbr_entries > 0) { + if (entries_num > 0) { is_lib = true; } } if (!is_lib) { - nbr_entries = filelist_readjob_list_dir( + entries_num = filelist_readjob_list_dir( subdir, &entries, filter_glob, do_lib, job_params->main_name, skip_currpar); } @@ -3698,14 +3698,14 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib, td_dir = BLI_stack_push_r(todo_dirs); td_dir->level = recursion_level + 1; td_dir->dir = BLI_strdup(dir); - nbr_todo_dirs++; + dirs_todo_count++; } } - filelist_readjob_append_entries(job_params, &entries, nbr_entries, do_update); + filelist_readjob_append_entries(job_params, &entries, entries_num, do_update); - nbr_done_dirs++; - *progress = (float)nbr_done_dirs / (float)nbr_todo_dirs; + dirs_done_count++; + *progress = (float)dirs_done_count / (float)dirs_todo_count; MEM_freeN(subdir); } @@ -3738,10 +3738,10 @@ static void filelist_readjob_do(const bool do_lib, // BLI_assert(filelist->filtered == NULL); BLI_assert(BLI_listbase_is_empty(&filelist->filelist.entries) && - (filelist->filelist.nbr_entries == FILEDIR_NBR_ENTRIES_UNSET)); + (filelist->filelist.entries_num == FILEDIR_NBR_ENTRIES_UNSET)); /* A valid, but empty directory from now. */ - filelist->filelist.nbr_entries = 0; + filelist->filelist.entries_num = 0; filelist_readjob_recursive_dir_add_items(do_lib, job_params, stop, do_update, progress); } @@ -3812,7 +3812,7 @@ static void filelist_readjob_main_assets_add_items(FileListReadJob *job_params, FileListInternEntry *entry; ListBase tmp_entries = {0}; ID *id_iter; - int nbr_entries = 0; + int entries_num = 0; /* Make sure no IDs are added/removed/reallocated in the main thread while this is running in * parallel. */ @@ -3835,19 +3835,19 @@ static void filelist_readjob_main_assets_add_items(FileListReadJob *job_params, entry->local_data.preview_image = BKE_asset_metadata_preview_get_from_id(id_iter->asset_data, id_iter); entry->local_data.id = id_iter; - nbr_entries++; + entries_num++; BLI_addtail(&tmp_entries, entry); } FOREACH_MAIN_ID_END; BKE_main_unlock(job_params->current_main); - if (nbr_entries) { + if (entries_num) { *do_update = true; BLI_movelisttolist(&filelist->filelist.entries, &tmp_entries); - filelist->filelist.nbr_entries += nbr_entries; - filelist->filelist.nbr_entries_filtered = -1; + filelist->filelist.entries_num += entries_num; + filelist->filelist.entries_filtered_num = -1; } } @@ -3872,10 +3872,10 @@ static void filelist_readjob_asset_library(FileListReadJob *job_params, FileList *filelist = job_params->tmp_filelist; /* Use the thread-safe filelist queue. */ BLI_assert(BLI_listbase_is_empty(&filelist->filelist.entries) && - (filelist->filelist.nbr_entries == FILEDIR_NBR_ENTRIES_UNSET)); + (filelist->filelist.entries_num == FILEDIR_NBR_ENTRIES_UNSET)); /* A valid, but empty file-list from now. */ - filelist->filelist.nbr_entries = 0; + filelist->filelist.entries_num = 0; /* NOP if already read. */ filelist_readjob_load_asset_library_data(job_params, do_update); @@ -3904,12 +3904,12 @@ static void filelist_readjob_main_assets(FileListReadJob *job_params, { FileList *filelist = job_params->tmp_filelist; /* Use the thread-safe filelist queue. */ BLI_assert(BLI_listbase_is_empty(&filelist->filelist.entries) && - (filelist->filelist.nbr_entries == FILEDIR_NBR_ENTRIES_UNSET)); + (filelist->filelist.entries_num == FILEDIR_NBR_ENTRIES_UNSET)); filelist_readjob_load_asset_library_data(job_params, do_update); /* A valid, but empty file-list from now. */ - filelist->filelist.nbr_entries = 0; + filelist->filelist.entries_num = 0; filelist_readjob_main_assets_add_items(job_params, stop, do_update, progress); } @@ -3932,7 +3932,7 @@ static void filelist_readjob_startjob(void *flrjv, short *stop, short *do_update FileListReadJob *flrj = flrjv; // printf("START filelist reading (%d files, main thread: %d)\n", - // flrj->filelist->filelist.nbr_entries, BLI_thread_is_main()); + // flrj->filelist->filelist.entries_num, BLI_thread_is_main()); BLI_mutex_lock(&flrj->lock); @@ -3941,7 +3941,7 @@ static void filelist_readjob_startjob(void *flrjv, short *stop, short *do_update flrj->tmp_filelist = MEM_dupallocN(flrj->filelist); BLI_listbase_clear(&flrj->tmp_filelist->filelist.entries); - flrj->tmp_filelist->filelist.nbr_entries = FILEDIR_NBR_ENTRIES_UNSET; + flrj->tmp_filelist->filelist.entries_num = FILEDIR_NBR_ENTRIES_UNSET; flrj->tmp_filelist->filelist_intern.filtered = NULL; BLI_listbase_clear(&flrj->tmp_filelist->filelist_intern.entries); @@ -3973,18 +3973,18 @@ static void filelist_readjob_update(void *flrjv) FileListReadJob *flrj = flrjv; FileListIntern *fl_intern = &flrj->filelist->filelist_intern; ListBase new_entries = {NULL}; - int nbr_entries, new_nbr_entries = 0; + int entries_num, new_entries_num = 0; BLI_movelisttolist(&new_entries, &fl_intern->entries); - nbr_entries = flrj->filelist->filelist.nbr_entries; + entries_num = flrj->filelist->filelist.entries_num; BLI_mutex_lock(&flrj->lock); - if (flrj->tmp_filelist->filelist.nbr_entries > 0) { + if (flrj->tmp_filelist->filelist.entries_num > 0) { /* We just move everything out of 'thread context' into final list. */ - new_nbr_entries = flrj->tmp_filelist->filelist.nbr_entries; + new_entries_num = flrj->tmp_filelist->filelist.entries_num; BLI_movelisttolist(&new_entries, &flrj->tmp_filelist->filelist.entries); - flrj->tmp_filelist->filelist.nbr_entries = 0; + flrj->tmp_filelist->filelist.entries_num = 0; } if (flrj->tmp_filelist->asset_library) { @@ -3998,7 +3998,7 @@ static void filelist_readjob_update(void *flrjv) BLI_mutex_unlock(&flrj->lock); - if (new_nbr_entries) { + if (new_entries_num) { /* Do not clear selection cache, we can assume already 'selected' UIDs are still valid! Keep * the asset library data we just read. */ filelist_clear_ex(flrj->filelist, false, true, false); @@ -4006,9 +4006,9 @@ static void filelist_readjob_update(void *flrjv) flrj->filelist->flags |= (FL_NEED_SORTING | FL_NEED_FILTERING); } - /* if no new_nbr_entries, this is NOP */ + /* if no new_entries_num, this is NOP */ BLI_movelisttolist(&fl_intern->entries, &new_entries); - flrj->filelist->filelist.nbr_entries = MAX2(nbr_entries, 0) + new_nbr_entries; + flrj->filelist->filelist.entries_num = MAX2(entries_num, 0) + new_entries_num; } static void filelist_readjob_endjob(void *flrjv) @@ -4026,11 +4026,11 @@ static void filelist_readjob_free(void *flrjv) { FileListReadJob *flrj = flrjv; - // printf("END filelist reading (%d files)\n", flrj->filelist->filelist.nbr_entries); + // printf("END filelist reading (%d files)\n", flrj->filelist->filelist.entries_num); if (flrj->tmp_filelist) { /* tmp_filelist shall never ever be filtered! */ - BLI_assert(flrj->tmp_filelist->filelist.nbr_entries == 0); + BLI_assert(flrj->tmp_filelist->filelist.entries_num == 0); BLI_assert(BLI_listbase_is_empty(&flrj->tmp_filelist->filelist.entries)); filelist_freelib(flrj->tmp_filelist); diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c index 847bf89bba8..ae0e5b23d55 100644 --- a/source/blender/editors/space_file/fsmenu.c +++ b/source/blender/editors/space_file/fsmenu.c @@ -968,13 +968,13 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) /* Check gvfs shares. */ const char *const xdg_runtime_dir = BLI_getenv("XDG_RUNTIME_DIR"); if (xdg_runtime_dir != NULL) { - struct direntry *dir; + struct direntry *dirs; char name[FILE_MAX]; BLI_join_dirfile(name, sizeof(name), xdg_runtime_dir, "gvfs/"); - const uint dir_len = BLI_filelist_dir_contents(name, &dir); - for (uint i = 0; i < dir_len; i++) { - if (dir[i].type & S_IFDIR) { - const char *dirname = dir[i].relname; + const uint dirs_num = BLI_filelist_dir_contents(name, &dirs); + for (uint i = 0; i < dirs_num; i++) { + if (dirs[i].type & S_IFDIR) { + const char *dirname = dirs[i].relname; if (dirname[0] != '.') { /* Dir names contain a lot of unwanted text. * Assuming every entry ends with the share name */ @@ -992,7 +992,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) } } } - BLI_filelist_free(dir, dir_len); + BLI_filelist_free(dirs, dirs_num); } # endif diff --git a/source/blender/editors/space_image/CMakeLists.txt b/source/blender/editors/space_image/CMakeLists.txt index f5cc6083b25..c385420b18e 100644 --- a/source/blender/editors/space_image/CMakeLists.txt +++ b/source/blender/editors/space_image/CMakeLists.txt @@ -60,6 +60,9 @@ if(WITH_IMAGE_CINEON) add_definitions(-DWITH_CINEON) endif() +if(WITH_IMAGE_WEBP) + add_definitions(-DWITH_WEBP) +endif() blender_add_lib(bf_editor_space_image "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 1c4a1d7e8c9..aa77aab2283 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -2790,8 +2790,7 @@ static int image_flip_exec(bContext *C, wmOperator *op) ED_image_undo_push_end(); - /* force GPU re-upload, all image is invalid. */ - BKE_image_free_gputextures(ima); + BKE_image_partial_update_mark_full_update(ima); WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima); @@ -2910,8 +2909,7 @@ static int image_invert_exec(bContext *C, wmOperator *op) ED_image_undo_push_end(); - /* Force GPU re-upload, all image is invalid. */ - BKE_image_free_gputextures(ima); + BKE_image_partial_update_mark_full_update(ima); WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima); @@ -3001,8 +2999,7 @@ static int image_scale_exec(bContext *C, wmOperator *op) ED_image_undo_push_end(); - /* Force GPU re-upload, all image is invalid. */ - BKE_image_free_gputextures(ima); + BKE_image_partial_update_mark_full_update(ima); DEG_id_tag_update(&ima->id, 0); WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima); diff --git a/source/blender/editors/space_outliner/outliner_collections.cc b/source/blender/editors/space_outliner/outliner_collections.cc index 716d5b67fe3..a4ff44512ef 100644 --- a/source/blender/editors/space_outliner/outliner_collections.cc +++ b/source/blender/editors/space_outliner/outliner_collections.cc @@ -301,7 +301,7 @@ static TreeTraversalAction collection_find_data_to_edit(TreeElement *te, void *c if (ID_IS_OVERRIDE_LIBRARY_REAL(collection)) { if (ID_IS_OVERRIDE_LIBRARY_HIERARCHY_ROOT(collection)) { - if (!data->is_liboverride_hierarchy_root_allowed) { + if (!(data->is_liboverride_hierarchy_root_allowed || data->is_liboverride_allowed)) { return TRAVERSE_SKIP_CHILDS; } } diff --git a/source/blender/editors/space_outliner/outliner_draw.cc b/source/blender/editors/space_outliner/outliner_draw.cc index 8b03047b1dd..9857abb3da7 100644 --- a/source/blender/editors/space_outliner/outliner_draw.cc +++ b/source/blender/editors/space_outliner/outliner_draw.cc @@ -3917,6 +3917,7 @@ void draw_outliner(const bContext *C) block, region, space_outliner, &space_outliner->tree, true); UI_block_emboss_set(block, UI_EMBOSS); + UI_block_flag_enable(block, UI_BLOCK_NO_DRAW_OVERRIDDEN_STATE); const int x = region->v2d.cur.xmax - right_column_width; outliner_draw_separator(region, x); outliner_draw_overrides_rna_buts(block, region, space_outliner, &space_outliner->tree, x); diff --git a/source/blender/editors/space_outliner/outliner_edit.cc b/source/blender/editors/space_outliner/outliner_edit.cc index a60e082f6a5..ae67e7108bf 100644 --- a/source/blender/editors/space_outliner/outliner_edit.cc +++ b/source/blender/editors/space_outliner/outliner_edit.cc @@ -447,6 +447,17 @@ static void id_delete(bContext *C, ReportList *reports, TreeElement *te, TreeSto (tselem->type == TSE_LAYER_COLLECTION)); UNUSED_VARS_NDEBUG(te); + if (ID_IS_OVERRIDE_LIBRARY(id)) { + if (!ID_IS_OVERRIDE_LIBRARY_REAL(id) || + (id->override_library->flag & IDOVERRIDE_LIBRARY_FLAG_NO_HIERARCHY) == 0) { + BKE_reportf(reports, + RPT_WARNING, + "Cannot delete library override id '%s', it is part of an override hierarchy", + id->name); + return; + } + } + if (te->idcode == ID_LI && ((Library *)id)->parent != nullptr) { BKE_reportf(reports, RPT_WARNING, "Cannot delete indirectly linked library '%s'", id->name); return; diff --git a/source/blender/editors/space_outliner/outliner_tools.cc b/source/blender/editors/space_outliner/outliner_tools.cc index 612baaa0752..0aea4521204 100644 --- a/source/blender/editors/space_outliner/outliner_tools.cc +++ b/source/blender/editors/space_outliner/outliner_tools.cc @@ -1677,6 +1677,12 @@ void OUTLINER_OT_object_operation(wmOperatorType *ot) using OutlinerDeleteFn = void (*)(bContext *C, ReportList *reports, Scene *scene, Object *ob); +typedef struct ObjectEditData { + GSet *objects_set; + bool is_liboverride_allowed; + bool is_liboverride_hierarchy_root_allowed; +} ObjectEditData; + static void outliner_do_object_delete(bContext *C, ReportList *reports, Scene *scene, @@ -1693,7 +1699,8 @@ static void outliner_do_object_delete(bContext *C, static TreeTraversalAction outliner_find_objects_to_delete(TreeElement *te, void *customdata) { - GSet *objects_to_delete = (GSet *)customdata; + ObjectEditData *data = reinterpret_cast<ObjectEditData *>(customdata); + GSet *objects_to_delete = data->objects_set; TreeStoreElem *tselem = TREESTORE(te); if (outliner_is_collection_tree_element(te)) { @@ -1708,9 +1715,15 @@ static TreeTraversalAction outliner_find_objects_to_delete(TreeElement *te, void ID *id = tselem->id; if (ID_IS_OVERRIDE_LIBRARY_REAL(id)) { - if (!ID_IS_OVERRIDE_LIBRARY_HIERARCHY_ROOT(id)) { - /* Only allow deletion of liboverride objects if they are root overrides. */ - return TRAVERSE_SKIP_CHILDS; + if (ID_IS_OVERRIDE_LIBRARY_HIERARCHY_ROOT(id)) { + if (!(data->is_liboverride_hierarchy_root_allowed || data->is_liboverride_allowed)) { + return TRAVERSE_SKIP_CHILDS; + } + } + else { + if (!data->is_liboverride_allowed) { + return TRAVERSE_SKIP_CHILDS; + } } } @@ -1732,27 +1745,31 @@ static int outliner_delete_exec(bContext *C, wmOperator *op) /* Get selected objects skipping duplicates to prevent deleting objects linked to multiple * collections twice */ - GSet *objects_to_delete = BLI_gset_ptr_new(__func__); + ObjectEditData object_delete_data = {}; + object_delete_data.objects_set = BLI_gset_ptr_new(__func__); + object_delete_data.is_liboverride_allowed = false; + object_delete_data.is_liboverride_hierarchy_root_allowed = delete_hierarchy; outliner_tree_traverse(space_outliner, &space_outliner->tree, 0, TSE_SELECTED, outliner_find_objects_to_delete, - objects_to_delete); + &object_delete_data); if (delete_hierarchy) { BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false); outliner_do_object_delete( - C, op->reports, scene, objects_to_delete, object_batch_delete_hierarchy_fn); + C, op->reports, scene, object_delete_data.objects_set, object_batch_delete_hierarchy_fn); BKE_id_multi_tagged_delete(bmain); } else { - outliner_do_object_delete(C, op->reports, scene, objects_to_delete, outliner_object_delete_fn); + outliner_do_object_delete( + C, op->reports, scene, object_delete_data.objects_set, outliner_object_delete_fn); } - BLI_gset_free(objects_to_delete, nullptr); + BLI_gset_free(object_delete_data.objects_set, nullptr); outliner_collection_delete(C, bmain, scene, op->reports, delete_hierarchy); diff --git a/source/blender/editors/space_outliner/outliner_tree.cc b/source/blender/editors/space_outliner/outliner_tree.cc index 1a772287dfa..19fe40b612e 100644 --- a/source/blender/editors/space_outliner/outliner_tree.cc +++ b/source/blender/editors/space_outliner/outliner_tree.cc @@ -900,7 +900,6 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner, /* ID types not (fully) ported to new design yet. */ if (te->abstract_element->expandPoll(*space_outliner)) { outliner_add_id_contents(space_outliner, te, tselem, id); - te->abstract_element->postExpand(*space_outliner); } } else if (ELEM(type, diff --git a/source/blender/editors/space_outliner/tree/tree_display.hh b/source/blender/editors/space_outliner/tree/tree_display.hh index bdca1954a9c..a60d3339042 100644 --- a/source/blender/editors/space_outliner/tree/tree_display.hh +++ b/source/blender/editors/space_outliner/tree/tree_display.hh @@ -136,8 +136,7 @@ class TreeDisplayOverrideLibrary final : public AbstractTreeDisplay { ListBase buildTree(const TreeSourceData &source_data) override; private: - TreeElement *add_library_contents(Main &, ListBase &, Library *); - bool override_library_id_filter_poll(const Library *lib, ID *id) const; + ListBase add_library_contents(Main &); short id_filter_get() const; }; diff --git a/source/blender/editors/space_outliner/tree/tree_display_libraries.cc b/source/blender/editors/space_outliner/tree/tree_display_libraries.cc index 0023b7c7b62..476bbdb63ae 100644 --- a/source/blender/editors/space_outliner/tree/tree_display_libraries.cc +++ b/source/blender/editors/space_outliner/tree/tree_display_libraries.cc @@ -150,7 +150,7 @@ TreeElement *TreeDisplayLibraries::add_library_contents(Main &mainvar, ListBase } else { ten = outliner_add_element( - &space_outliner_, &tenlib->subtree, lbarray[a], nullptr, TSE_ID_BASE, 0); + &space_outliner_, &tenlib->subtree, lib, nullptr, TSE_ID_BASE, a); ten->directdata = lbarray[a]; ten->name = outliner_idcode_to_plural(GS(id->name)); } diff --git a/source/blender/editors/space_outliner/tree/tree_display_override_library.cc b/source/blender/editors/space_outliner/tree/tree_display_override_library.cc index f94727ba356..2162c303da1 100644 --- a/source/blender/editors/space_outliner/tree/tree_display_override_library.cc +++ b/source/blender/editors/space_outliner/tree/tree_display_override_library.cc @@ -32,72 +32,22 @@ TreeDisplayOverrideLibrary::TreeDisplayOverrideLibrary(SpaceOutliner &space_outl ListBase TreeDisplayOverrideLibrary::buildTree(const TreeSourceData &source_data) { - ListBase tree = {nullptr}; - - { - /* current file first - mainvar provides tselem with unique pointer - not used */ - TreeElement *ten = add_library_contents(*source_data.bmain, tree, nullptr); - TreeStoreElem *tselem; - - if (ten) { - tselem = TREESTORE(ten); - if (!tselem->used) { - tselem->flag &= ~TSE_CLOSED; - } - } - } + ListBase tree = add_library_contents(*source_data.bmain); - for (ID *id : List<ID>(source_data.bmain->libraries)) { - Library *lib = reinterpret_cast<Library *>(id); - TreeElement *ten = add_library_contents(*source_data.bmain, tree, lib); - /* NULL-check matters, due to filtering there may not be a new element. */ - if (ten) { - lib->id.newid = (ID *)ten; + for (TreeElement *top_level_te : List<TreeElement>(tree)) { + TreeStoreElem *tselem = TREESTORE(top_level_te); + if (!tselem->used) { + tselem->flag &= ~TSE_CLOSED; } } - /* make hierarchy */ - for (TreeElement *ten : List<TreeElement>(tree)) { - if (ten == tree.first) { - /* First item is main, skip. */ - continue; - } - - TreeStoreElem *tselem = TREESTORE(ten); - Library *lib = (Library *)tselem->id; - BLI_assert(!lib || (GS(lib->id.name) == ID_LI)); - if (!lib || !lib->parent) { - continue; - } - - TreeElement *parent = (TreeElement *)lib->parent->id.newid; - - if (tselem->id->tag & LIB_TAG_INDIRECT) { - /* Only remove from 'first level' if lib is not also directly used. */ - BLI_remlink(&tree, ten); - BLI_addtail(&parent->subtree, ten); - ten->parent = parent; - } - else { - /* Else, make a new copy of the libtree for our parent. */ - TreeElement *dupten = add_library_contents(*source_data.bmain, parent->subtree, lib); - if (dupten) { - dupten->parent = parent; - } - } - } - /* restore newid pointers */ - for (ID *library_id : List<ID>(source_data.bmain->libraries)) { - library_id->newid = nullptr; - } - return tree; } -TreeElement *TreeDisplayOverrideLibrary::add_library_contents(Main &mainvar, - ListBase &lb, - Library *lib) +ListBase TreeDisplayOverrideLibrary::add_library_contents(Main &mainvar) { + ListBase tree = {nullptr}; + const short filter_id_type = id_filter_get(); ListBase *lbarray[INDEX_ID_MAX]; @@ -110,7 +60,6 @@ TreeElement *TreeDisplayOverrideLibrary::add_library_contents(Main &mainvar, tot = set_listbasepointers(&mainvar, lbarray); } - TreeElement *tenlib = nullptr; for (int a = 0; a < tot; a++) { if (!lbarray[a] || !lbarray[a]->first) { continue; @@ -118,56 +67,51 @@ TreeElement *TreeDisplayOverrideLibrary::add_library_contents(Main &mainvar, ID *id = nullptr; - /* check if there's data in current lib */ + /* check if there's data in current id list */ for (ID *id_iter : List<ID>(lbarray[a])) { - if (id_iter->lib == lib && ID_IS_OVERRIDE_LIBRARY_REAL(id_iter)) { + if (ID_IS_OVERRIDE_LIBRARY_REAL(id_iter) && !ID_IS_LINKED(id_iter)) { id = id_iter; break; } } - if (id != nullptr) { - if (!tenlib) { - /* Create library tree element on demand, depending if there are any data-blocks. */ - if (lib) { - tenlib = outliner_add_element(&space_outliner_, &lb, lib, nullptr, TSE_SOME_ID, 0); - } - else { - tenlib = outliner_add_element(&space_outliner_, &lb, &mainvar, nullptr, TSE_ID_BASE, 0); - tenlib->name = IFACE_("Current File"); - } - if (tenlib->flag & TE_HAS_WARNING) { - has_warnings = true; - } - } + if (id == nullptr) { + continue; + } - /* Create data-block list parent element on demand. */ - TreeElement *ten; + /* Create data-block list parent element on demand. */ + TreeElement *id_base_te = nullptr; + ListBase *lb_to_expand = &tree; - if (filter_id_type) { - ten = tenlib; - } - else { - ten = outliner_add_element( - &space_outliner_, &tenlib->subtree, lbarray[a], nullptr, TSE_ID_BASE, 0); - ten->directdata = lbarray[a]; - ten->name = outliner_idcode_to_plural(GS(id->name)); - } + if (!filter_id_type) { + id_base_te = outliner_add_element( + &space_outliner_, &tree, lbarray[a], nullptr, TSE_ID_BASE, 0); + id_base_te->directdata = lbarray[a]; + id_base_te->name = outliner_idcode_to_plural(GS(id->name)); - for (ID *id : List<ID>(lbarray[a])) { - if (override_library_id_filter_poll(lib, id)) { - TreeElement *override_tree_element = outliner_add_element( - &space_outliner_, &ten->subtree, id, ten, TSE_LIBRARY_OVERRIDE_BASE, 0); + lb_to_expand = &id_base_te->subtree; + } - if (BLI_listbase_is_empty(&override_tree_element->subtree)) { - outliner_free_tree_element(override_tree_element, &ten->subtree); - } + for (ID *id : List<ID>(lbarray[a])) { + if (ID_IS_OVERRIDE_LIBRARY_REAL(id) && !ID_IS_LINKED(id)) { + TreeElement *override_tree_element = outliner_add_element( + &space_outliner_, lb_to_expand, id, id_base_te, TSE_LIBRARY_OVERRIDE_BASE, 0); + + if (BLI_listbase_is_empty(&override_tree_element->subtree)) { + outliner_free_tree_element(override_tree_element, lb_to_expand); } } } } - return tenlib; + /* Remove ID base elements that turn out to be empty. */ + LISTBASE_FOREACH_MUTABLE (TreeElement *, te, &tree) { + if (BLI_listbase_is_empty(&te->subtree)) { + outliner_free_tree_element(te, &tree); + } + } + + return tree; } short TreeDisplayOverrideLibrary::id_filter_get() const @@ -178,17 +122,4 @@ short TreeDisplayOverrideLibrary::id_filter_get() const return 0; } -bool TreeDisplayOverrideLibrary::override_library_id_filter_poll(const Library *lib, ID *id) const -{ - if (id->lib != lib) { - return false; - } - - if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) { - return false; - } - - return true; -} - } // namespace blender::ed::outliner diff --git a/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc b/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc index 0ee5059a54d..19811e45b90 100644 --- a/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc +++ b/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc @@ -154,15 +154,6 @@ void TreeDisplayViewLayer::add_layer_collections_recursive(ListBase &tree, if (!exclude && show_objects_) { add_layer_collection_objects(ten->subtree, *lc, *ten); } - - const bool lib_overrides_visible = !exclude && (!SUPPORT_FILTER_OUTLINER(&space_outliner_) || - ((space_outliner_.filter & - SO_FILTER_NO_LIB_OVERRIDE) == 0)); - - if (lib_overrides_visible && ID_IS_OVERRIDE_LIBRARY_REAL(&lc->collection->id)) { - outliner_add_element( - &space_outliner_, &ten->subtree, &lc->collection->id, ten, TSE_LIBRARY_OVERRIDE_BASE, 0); - } } } diff --git a/source/blender/editors/space_outliner/tree/tree_element.cc b/source/blender/editors/space_outliner/tree/tree_element.cc index 3c2023d7905..ca67aad00db 100644 --- a/source/blender/editors/space_outliner/tree/tree_element.cc +++ b/source/blender/editors/space_outliner/tree/tree_element.cc @@ -107,7 +107,6 @@ void tree_element_expand(const AbstractTreeElement &tree_element, SpaceOutliner return; } tree_element.expand(space_outliner); - tree_element.postExpand(space_outliner); } bool tree_element_warnings_get(TreeElement *te, int *r_icon, const char **r_message) diff --git a/source/blender/editors/space_outliner/tree/tree_element.hh b/source/blender/editors/space_outliner/tree/tree_element.hh index 2fbc86705b9..6f2d803ae96 100644 --- a/source/blender/editors/space_outliner/tree/tree_element.hh +++ b/source/blender/editors/space_outliner/tree/tree_element.hh @@ -40,9 +40,6 @@ class AbstractTreeElement { { return true; } - virtual void postExpand(SpaceOutliner &) const - { - } /** * Just while transitioning to the new tree-element design: Some types are only partially ported, diff --git a/source/blender/editors/space_outliner/tree/tree_element_id.cc b/source/blender/editors/space_outliner/tree/tree_element_id.cc index 64c73f57107..ef5e056f229 100644 --- a/source/blender/editors/space_outliner/tree/tree_element_id.cc +++ b/source/blender/editors/space_outliner/tree/tree_element_id.cc @@ -93,17 +93,6 @@ TreeElementID::TreeElementID(TreeElement &legacy_te, ID &id) legacy_te_.idcode = GS(id.name); } -void TreeElementID::postExpand(SpaceOutliner &space_outliner) const -{ - const bool lib_overrides_visible = !SUPPORT_FILTER_OUTLINER(&space_outliner) || - ((space_outliner.filter & SO_FILTER_NO_LIB_OVERRIDE) == 0); - - if (lib_overrides_visible && ID_IS_OVERRIDE_LIBRARY_REAL(&id_)) { - outliner_add_element( - &space_outliner, &legacy_te_.subtree, &id_, &legacy_te_, TSE_LIBRARY_OVERRIDE_BASE, 0); - } -} - bool TreeElementID::expandPoll(const SpaceOutliner &space_outliner) const { const TreeStoreElem *tsepar = legacy_te_.parent ? TREESTORE(legacy_te_.parent) : nullptr; diff --git a/source/blender/editors/space_outliner/tree/tree_element_id.hh b/source/blender/editors/space_outliner/tree/tree_element_id.hh index 75dc7e737e2..b7519fe06f9 100644 --- a/source/blender/editors/space_outliner/tree/tree_element_id.hh +++ b/source/blender/editors/space_outliner/tree/tree_element_id.hh @@ -24,7 +24,6 @@ class TreeElementID : public AbstractTreeElement { static std::unique_ptr<TreeElementID> createFromID(TreeElement &legacy_te, ID &id); - void postExpand(SpaceOutliner &) const override; bool expandPoll(const SpaceOutliner &) const override; /** diff --git a/source/blender/editors/space_outliner/tree/tree_element_rna.cc b/source/blender/editors/space_outliner/tree/tree_element_rna.cc index abc7cd8f8ce..914104f1f06 100644 --- a/source/blender/editors/space_outliner/tree/tree_element_rna.cc +++ b/source/blender/editors/space_outliner/tree/tree_element_rna.cc @@ -52,7 +52,7 @@ bool TreeElementRNACommon::isRNAValid() const return rna_ptr_.data != nullptr; } -bool TreeElementRNACommon::expandPoll(const SpaceOutliner &) const +bool TreeElementRNACommon::expandPoll(const SpaceOutliner &UNUSED(space_outliner)) const { return isRNAValid(); } diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 3ccdf701a86..283bd99cd5d 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -1643,35 +1643,6 @@ void SEQUENCER_OT_split(struct wmOperatorType *ot) /** \name Duplicate Strips Operator * \{ */ -static void sequencer_backup_original_animation(Scene *scene, ListBase *list) -{ - if (scene->adt == NULL || scene->adt->action == NULL || - BLI_listbase_is_empty(&scene->adt->action->curves)) { - return; - } - - BLI_movelisttolist(list, &scene->adt->action->curves); -} - -static void sequencer_restore_original_animation(Scene *scene, ListBase *list) -{ - if (scene->adt == NULL || scene->adt->action == NULL || BLI_listbase_is_empty(list)) { - return; - } - - BLI_movelisttolist(&scene->adt->action->curves, list); -} - -static void sequencer_duplicate_animation(Scene *scene, Sequence *seq, ListBase *curves_backup) -{ - GSet *fcurves = SEQ_fcurves_by_strip_get(seq, curves_backup); - GSET_FOREACH_BEGIN (FCurve *, fcu, fcurves) { - FCurve *fcu_cpy = BKE_fcurve_copy(fcu); - BLI_addtail(&scene->adt->action->curves, fcu_cpy); - } - GSET_FOREACH_END(); -} - static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); @@ -1697,7 +1668,7 @@ static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) * original curves from backup. */ ListBase fcurves_original_backup = {NULL, NULL}; - sequencer_backup_original_animation(scene, &fcurves_original_backup); + SEQ_animation_backup_original(scene, &fcurves_original_backup); Sequence *seq = duplicated_strips.first; @@ -1712,11 +1683,11 @@ static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) SEQ_select_active_set(scene, seq); } seq->flag &= ~(SEQ_LEFTSEL + SEQ_RIGHTSEL + SEQ_LOCK); - sequencer_duplicate_animation(scene, seq, &fcurves_original_backup); + SEQ_animation_duplicate(scene, seq, &fcurves_original_backup); SEQ_ensure_unique_name(seq, scene); } - sequencer_restore_original_animation(scene, &fcurves_original_backup); + SEQ_animation_restore_original(scene, &fcurves_original_backup); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); return OPERATOR_FINISHED; @@ -2622,7 +2593,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op) */ ListBase fcurves_original_backup = {NULL, NULL}; - sequencer_backup_original_animation(scene, &fcurves_original_backup); + SEQ_animation_backup_original(scene, &fcurves_original_backup); sequencer_paste_animation(C); /* Copy strips, temporarily restoring pointers to actual data-blocks. This @@ -2654,7 +2625,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op) } } - sequencer_restore_original_animation(scene, &fcurves_original_backup); + SEQ_animation_restore_original(scene, &fcurves_original_backup); DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); DEG_relations_tag_update(bmain); diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 15fea301b1c..f5656e13c0e 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -165,7 +165,7 @@ BLI_INLINE int text_pixel_x_to_column(SpaceText *st, const int x) static bool text_new_poll(bContext *UNUSED(C)) { - return 1; + return true; } static bool text_data_poll(bContext *C) @@ -182,15 +182,15 @@ static bool text_edit_poll(bContext *C) Text *text = CTX_data_edit_text(C); if (!text) { - return 0; + return false; } if (ID_IS_LINKED(text)) { // BKE_report(op->reports, RPT_ERROR, "Cannot edit external library data"); - return 0; + return false; } - return 1; + return true; } bool text_space_edit_poll(bContext *C) @@ -199,15 +199,15 @@ bool text_space_edit_poll(bContext *C) Text *text = CTX_data_edit_text(C); if (!st || !text) { - return 0; + return false; } if (ID_IS_LINKED(text)) { // BKE_report(op->reports, RPT_ERROR, "Cannot edit external library data"); - return 0; + return false; } - return 1; + return true; } static bool text_region_edit_poll(bContext *C) @@ -217,19 +217,19 @@ static bool text_region_edit_poll(bContext *C) ARegion *region = CTX_wm_region(C); if (!st || !text) { - return 0; + return false; } if (!region || region->regiontype != RGN_TYPE_WINDOW) { - return 0; + return false; } if (ID_IS_LINKED(text)) { // BKE_report(op->reports, RPT_ERROR, "Cannot edit external library data"); - return 0; + return false; } - return 1; + return true; } /** \} */ diff --git a/source/blender/editors/space_view3d/view3d_cursor_snap.c b/source/blender/editors/space_view3d/view3d_cursor_snap.c index 53f7b3d5871..f3e45a14565 100644 --- a/source/blender/editors/space_view3d/view3d_cursor_snap.c +++ b/source/blender/editors/space_view3d/view3d_cursor_snap.c @@ -620,9 +620,6 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state, snap_elements &= ~SCE_SNAP_MODE_EDGE_PERPENDICULAR; } - eSnapSelect snap_select = (state->flag & V3D_SNAPCURSOR_SNAP_ONLY_ACTIVE) ? SNAP_ONLY_ACTIVE : - SNAP_ALL; - eSnapEditType edit_mode_type = (state->flag & V3D_SNAPCURSOR_SNAP_EDIT_GEOM_FINAL) ? SNAP_GEOM_FINAL : (state->flag & V3D_SNAPCURSOR_SNAP_EDIT_GEOM_CAGE) ? @@ -640,7 +637,7 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state, v3d, snap_elements, &(const struct SnapObjectParams){ - .snap_select = snap_select, + .snap_select = SNAP_ALL, .edit_mode_type = edit_mode_type, .use_occlusion_test = use_occlusion_test, }, diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 6f55acff6a2..30282df8026 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -2049,6 +2049,40 @@ static int mixed_bones_object_selectbuffer_extended(ViewContext *vc, } /** + * Compare result of 'GPU_select': 'GPUSelectResult', + * Needed for stable sorting, so cycling through all items near the cursor behaves predictably. + */ +static int gpu_select_buffer_depth_id_cmp(const void *sel_a_p, const void *sel_b_p) +{ + GPUSelectResult *a = (GPUSelectResult *)sel_a_p; + GPUSelectResult *b = (GPUSelectResult *)sel_b_p; + + if (a->depth < b->depth) { + return -1; + } + if (a->depth > b->depth) { + return 1; + } + + /* Depths match, sort by id. */ + uint sel_a = a->id; + uint sel_b = b->id; + +#ifdef __BIG_ENDIAN__ + BLI_endian_switch_uint32(&sel_a); + BLI_endian_switch_uint32(&sel_b); +#endif + + if (sel_a < sel_b) { + return -1; + } + if (sel_a > sel_b) { + return 1; + } + return 0; +} + +/** * \param has_bones: When true, skip non-bone hits, also allow bases to be used * that are visible but not select-able, * since you may be in pose mode with an un-selectable object. @@ -2058,36 +2092,40 @@ static int mixed_bones_object_selectbuffer_extended(ViewContext *vc, static Base *mouse_select_eval_buffer(ViewContext *vc, const GPUSelectResult *buffer, int hits, - Base *startbase, - bool has_bones, bool do_nearest, - int *r_sub_selection) + bool has_bones, + bool do_bones_get_priotity, + int *r_select_id_subelem) { ViewLayer *view_layer = vc->view_layer; View3D *v3d = vc->v3d; - Base *base, *basact = NULL; int a; - int sub_selection_id = 0; + + bool found = false; + int select_id = 0; + int select_id_subelem = 0; if (do_nearest) { uint min = 0xFFFFFFFF; - int selcol = 0; + int hit_index = -1; - if (has_bones) { + if (has_bones && do_bones_get_priotity) { /* we skip non-bone hits */ for (a = 0; a < hits; a++) { if (min > buffer[a].depth && (buffer[a].id & 0xFFFF0000)) { min = buffer[a].depth; - selcol = buffer[a].id & 0xFFFF; - sub_selection_id = (buffer[a].id & 0xFFFF0000) >> 16; + hit_index = a; } } } else { - int select_id_exclude = 0; - /* Only exclude active object when it is selected. */ - if (BASACT(view_layer) && (BASACT(view_layer)->flag & BASE_SELECTED) && hits > 1) { - select_id_exclude = BASACT(view_layer)->object->runtime.select_id; + + for (a = 0; a < hits; a++) { + /* Any object. */ + if (min > buffer[a].depth) { + min = buffer[a].depth; + hit_index = a; + } } /* Find the best active & non-active hits. @@ -2099,102 +2137,111 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, * * For this reason, keep track of the best hit as well as the best hit that * excludes the selected & active object, using this value when it's valid. */ + if ((hit_index != -1) && + /* Special case, cycling away from the active object should only be done when it + * doesn't have a bone selection, otherwise selecting sub-elements is difficult. */ + ((buffer[hit_index].id & 0xFFFF0000) == 0) && + /* Only exclude active object when it is selected. */ + (BASACT(view_layer) && (BASACT(view_layer)->flag & BASE_SELECTED)) && + /* Allow disabling this behavior entirely. */ + (U.experimental.use_select_nearest_on_first_click == false)) { + + const int select_id_active = BASACT(view_layer)->object->runtime.select_id; + + /* Check if `hit_index` is the current active object. */ + if ((buffer[hit_index].id & 0xFFFF) == select_id_active) { + uint min_not_active = 0xFFFFFFFF; + int hit_index_not_active = -1; + for (a = 0; a < hits; a++) { + /* Any object other than the active-selected. */ + if (select_id_active == (buffer[a].id & 0xFFFF)) { + continue; + } + if (min_not_active > buffer[a].depth) { + min_not_active = buffer[a].depth; + hit_index_not_active = a; + } + } - uint min_not_active = min; - int hit_index = -1, hit_index_not_active = -1; - - for (a = 0; a < hits; a++) { - /* Any object. */ - if (min > buffer[a].depth) { - min = buffer[a].depth; - hit_index = a; - } - /* Any object other than the active-selected. */ - if (select_id_exclude != 0) { - if (min_not_active > buffer[a].depth && select_id_exclude != (buffer[a].id & 0xFFFF)) { - min_not_active = buffer[a].depth; - hit_index_not_active = a; + /* When the active was selected, first try to use the index + * for the best non-active hit that was found. */ + if (hit_index_not_active != -1) { + hit_index = hit_index_not_active; } } } - - /* When the active was selected, first try to use the index - * for the best non-active hit that was found. */ - if (hit_index_not_active != -1) { - hit_index = hit_index_not_active; - } - - if (hit_index != -1) { - selcol = buffer[hit_index].id & 0xFFFF; - sub_selection_id = (buffer[hit_index].id & 0xFFFF0000) >> 16; - /* No need to set `min` to `buffer[hit_index].depth`, it's not used from now on. */ - } } - base = FIRSTBASE(view_layer); - while (base) { - if (has_bones ? BASE_VISIBLE(v3d, base) : BASE_SELECTABLE(v3d, base)) { - if (base->object->runtime.select_id == selcol) { - break; - } - } - base = base->next; - } - if (base) { - basact = base; + if (hit_index != -1) { + select_id = buffer[hit_index].id & 0xFFFF; + select_id_subelem = (buffer[hit_index].id & 0xFFFF0000) >> 16; + found = true; + /* No need to set `min` to `buffer[hit_index].depth`, it's not used from now on. */ } } else { - base = startbase; - while (base) { - /* skip objects with select restriction, to prevent prematurely ending this loop - * with an un-selectable choice */ - if (has_bones ? (base->flag & BASE_VISIBLE_VIEWLAYER) == 0 : - (base->flag & BASE_SELECTABLE) == 0) { - base = base->next; - if (base == NULL) { - base = FIRSTBASE(view_layer); - } - if (base == startbase) { - break; + { + GPUSelectResult *buffer_sorted = MEM_mallocN(sizeof(*buffer_sorted) * hits, __func__); + memcpy(buffer_sorted, buffer, sizeof(*buffer_sorted) * hits); + /* Remove non-bone objects. */ + if (has_bones && do_bones_get_priotity) { + /* Loop backwards to reduce re-ordering. */ + for (a = hits - 1; a >= 0; a--) { + if ((buffer_sorted[a].id & 0xFFFF0000) == 0) { + buffer_sorted[a] = buffer_sorted[--hits]; + } } } + qsort(buffer_sorted, hits, sizeof(GPUSelectResult), gpu_select_buffer_depth_id_cmp); + buffer = buffer_sorted; + } - if (has_bones ? BASE_VISIBLE(v3d, base) : BASE_SELECTABLE(v3d, base)) { - for (a = 0; a < hits; a++) { - if (has_bones) { - /* skip non-bone objects */ - if (buffer[a].id & 0xFFFF0000) { - if (base->object->runtime.select_id == (buffer[a].id & 0xFFFF)) { - basact = base; - } - } - } - else { - if (base->object->runtime.select_id == (buffer[a].id & 0xFFFF)) { - basact = base; - } + int hit_index = -1; + + /* It's possible there are no hits (all objects contained bones). */ + if (hits > 0) { + /* Only exclude active object when it is selected. */ + if (BASACT(view_layer) && (BASACT(view_layer)->flag & BASE_SELECTED)) { + const int select_id_active = BASACT(view_layer)->object->runtime.select_id; + for (int i_next = 0, i_prev = hits - 1; i_next < hits; i_prev = i_next++) { + if ((select_id_active == (buffer[i_prev].id & 0xFFFF)) && + (select_id_active != (buffer[i_next].id & 0xFFFF))) { + hit_index = i_next; + break; } } } - if (basact) { - break; + /* When the active object is unselected or not in `buffer`, use the nearest. */ + if (hit_index == -1) { + /* Just pick the nearest. */ + hit_index = 0; } + } - base = base->next; - if (base == NULL) { - base = FIRSTBASE(view_layer); - } - if (base == startbase) { - break; - } + if (hit_index != -1) { + select_id = buffer[hit_index].id & 0xFFFF; + select_id_subelem = (buffer[hit_index].id & 0xFFFF0000) >> 16; + found = true; } + MEM_freeN((void *)buffer); } - if (basact && r_sub_selection) { - *r_sub_selection = sub_selection_id; + Base *basact = NULL; + if (found) { + for (Base *base = FIRSTBASE(view_layer); base; base = base->next) { + if (has_bones ? BASE_VISIBLE(v3d, base) : BASE_SELECTABLE(v3d, base)) { + if (base->object->runtime.select_id == select_id) { + basact = base; + break; + } + } + } + + if (basact && r_select_id_subelem) { + *r_select_id_subelem = select_id_subelem; + } } return basact; @@ -2271,13 +2318,8 @@ static Base *ed_view3d_give_base_under_cursor_ex(bContext *C, if (hits > 0) { const bool has_bones = (r_material_slot == NULL) && selectbuffer_has_bones(buffer, hits); - basact = mouse_select_eval_buffer(&vc, - buffer, - hits, - vc.view_layer->object_bases.first, - has_bones, - do_nearest, - r_material_slot); + basact = mouse_select_eval_buffer( + &vc, buffer, hits, do_nearest, has_bones, true, r_material_slot); } return basact; @@ -2560,11 +2602,27 @@ static bool ed_object_select_pick(bContext *C, basact = basact_override; } else { - basact = - (gpu->hits > 0) ? - mouse_select_eval_buffer( - &vc, gpu->buffer, gpu->hits, startbase, gpu->has_bones, gpu->do_nearest, NULL) : - NULL; + /* Regarding bone priority. + * + * - When in pose-bone, it's useful that any selection containing a bone + * gets priority over other geometry (background scenery for example). + * + * - When in object-mode, don't prioritize bones as it would cause + * pose-objects behind other objects to get priority + * (mainly noticeable when #SCE_OBJECT_MODE_LOCK is disabled). + * + * This way prioritizing based on pose-mode has a bias to stay in pose-mode + * without having to enforce this through locking the object mode. */ + bool do_bones_get_priotity = (object_mode & OB_MODE_POSE) != 0; + + basact = (gpu->hits > 0) ? mouse_select_eval_buffer(&vc, + gpu->buffer, + gpu->hits, + gpu->do_nearest, + gpu->has_bones, + do_bones_get_priotity, + NULL) : + NULL; } /* Select pose-bones or camera-tracks. */ @@ -2587,7 +2645,7 @@ static bool ed_object_select_pick(bContext *C, /* Fallback to regular object selection if no new bundles were selected, * allows to select object parented to reconstruction object. */ basact = mouse_select_eval_buffer( - &vc, gpu->buffer, gpu->hits, startbase, false, gpu->do_nearest, NULL); + &vc, gpu->buffer, gpu->hits, gpu->do_nearest, false, false, NULL); } } } @@ -2689,6 +2747,11 @@ static bool ed_object_select_pick(bContext *C, if (params->sel_op == SEL_OP_SET) { if ((found && params->select_passthrough) && (basact->flag & BASE_SELECTED)) { found = false; + /* NOTE(@campbellbarton): Experimental behavior to set active even keeping the selection + * without this it's inconvenient to set the active object. */ + if (basact != oldbasact) { + use_activate_selected_base = true; + } } else if (found || params->deselect_all) { /* Deselect everything. */ diff --git a/source/blender/editors/transform/CMakeLists.txt b/source/blender/editors/transform/CMakeLists.txt index c8033d9d767..68c4f4e76ca 100644 --- a/source/blender/editors/transform/CMakeLists.txt +++ b/source/blender/editors/transform/CMakeLists.txt @@ -90,7 +90,7 @@ set(SRC transform_orientations.c transform_snap.c transform_snap_animation.c - transform_snap_object.c + transform_snap_object.cc transform_snap_sequencer.c transform.h diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 975f4370425..76d42fae444 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -59,8 +59,6 @@ * and being able to set it to zero is handy. */ /* #define USE_NUM_NO_ZERO */ -static void drawTransformApply(const struct bContext *C, ARegion *region, void *arg); - static void initSnapSpatial(TransInfo *t, float r_snap[2]); bool transdata_check_local_islands(TransInfo *t, short around) @@ -845,10 +843,6 @@ int transformEvent(TransInfo *t, const wmEvent *event) handled = true; } else if (event->type == MOUSEMOVE) { - if (t->modifiers & (MOD_CONSTRAINT_SELECT_AXIS | MOD_CONSTRAINT_SELECT_PLANE)) { - t->con.mode |= CON_SELECT; - } - copy_v2_v2_int(t->mval, event->mval); /* Use this for soft redraw. Might cause flicker in object mode */ @@ -1097,6 +1091,7 @@ int transformEvent(TransInfo *t, const wmEvent *event) /* Confirm. */ postSelectConstraint(t); t->modifiers &= ~(MOD_CONSTRAINT_SELECT_AXIS | MOD_CONSTRAINT_SELECT_PLANE); + t->redraw = TREDRAW_HARD; } else { if (t->options & CTX_CAMERA) { @@ -1108,6 +1103,7 @@ int transformEvent(TransInfo *t, const wmEvent *event) restoreTransObjects(t); transform_mode_init(t, NULL, TFM_TRACKBALL); } + t->redraw = TREDRAW_HARD; } else { t->modifiers |= (event->val == TFM_MODAL_AUTOCONSTRAINT) ? @@ -1116,13 +1112,13 @@ int transformEvent(TransInfo *t, const wmEvent *event) if (t->con.mode & CON_APPLY) { stopConstraint(t); } - else { - initSelectConstraint(t); - postSelectConstraint(t); - } + + initSelectConstraint(t); + /* Use #TREDRAW_SOFT so that #selectConstraint is only called on the next event. + * This allows us to "deselect" the contraint. */ + t->redraw = TREDRAW_SOFT; } } - t->redraw |= TREDRAW_HARD; handled = true; } break; @@ -1733,8 +1729,6 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve initTransInfo(C, t, op, event); if (t->spacetype == SPACE_VIEW3D) { - t->draw_handle_apply = ED_region_draw_cb_activate( - t->region->type, drawTransformApply, t, REGION_DRAW_PRE_VIEW); t->draw_handle_view = ED_region_draw_cb_activate( t->region->type, drawTransformView, t, REGION_DRAW_POST_VIEW); t->draw_handle_pixel = ED_region_draw_cb_activate( @@ -1925,18 +1919,19 @@ void transformApply(bContext *C, TransInfo *t) { t->context = C; - if ((t->redraw & TREDRAW_HARD) || (t->draw_handle_apply == NULL && (t->redraw & TREDRAW_SOFT))) { + if (t->redraw == TREDRAW_HARD) { selectConstraint(t); if (t->transform) { t->transform(t, t->mval); /* calls recalcData() */ - viewRedrawForce(C, t); } - t->redraw = TREDRAW_NOTHING; } - else if (t->redraw & TREDRAW_SOFT) { + + if (t->redraw & TREDRAW_SOFT) { viewRedrawForce(C, t); } + t->redraw = TREDRAW_NOTHING; + /* If auto confirm is on, break after one pass */ if (t->options & CTX_AUTOCONFIRM) { t->state = TRANS_CONFIRM; @@ -1945,16 +1940,6 @@ void transformApply(bContext *C, TransInfo *t) t->context = NULL; } -static void drawTransformApply(const bContext *C, ARegion *UNUSED(region), void *arg) -{ - TransInfo *t = arg; - - if (t->redraw & TREDRAW_SOFT) { - t->redraw |= TREDRAW_HARD; - transformApply((bContext *)C, t); - } -} - int transformEnd(bContext *C, TransInfo *t) { int exit_code = OPERATOR_RUNNING_MODAL; diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 713cf487ac7..37478dfc187 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -188,8 +188,8 @@ typedef enum { /** #TransInfo.redraw */ typedef enum { TREDRAW_NOTHING = 0, - TREDRAW_HARD = 1, - TREDRAW_SOFT = 2, + TREDRAW_SOFT = (1 << 0), + TREDRAW_HARD = (1 << 1) | TREDRAW_SOFT, } eRedrawFlag; /** #TransInfo.helpline */ @@ -663,7 +663,6 @@ typedef struct TransInfo { int mval[2]; /** use for 3d view. */ float zfac; - void *draw_handle_apply; void *draw_handle_view; void *draw_handle_pixel; void *draw_handle_cursor; diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index 81b35e4539b..0bb00032561 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -996,19 +996,10 @@ void selectConstraint(TransInfo *t) void postSelectConstraint(TransInfo *t) { - if (!(t->con.mode & CON_SELECT)) { - return; - } - - t->con.mode &= ~CON_AXIS0; - t->con.mode &= ~CON_AXIS1; - t->con.mode &= ~CON_AXIS2; t->con.mode &= ~CON_SELECT; - - setNearestAxis(t); - - startConstraint(t); - t->redraw = TREDRAW_HARD; + if (!(t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2))) { + t->con.mode &= ~CON_APPLY; + } } static void setNearestAxis2d(TransInfo *t) diff --git a/source/blender/editors/transform/transform_convert_object_texspace.c b/source/blender/editors/transform/transform_convert_object_texspace.c index 763af1f3384..1f58ec80f02 100644 --- a/source/blender/editors/transform/transform_convert_object_texspace.c +++ b/source/blender/editors/transform/transform_convert_object_texspace.c @@ -63,7 +63,6 @@ void createTransTexspace(TransInfo *t) } td->flag = TD_SELECTED; - copy_v3_v3(td->center, ob->obmat[3]); td->ob = ob; copy_m3_m4(td->mtx, ob->obmat); @@ -77,6 +76,7 @@ void createTransTexspace(TransInfo *t) } copy_v3_v3(td->iloc, td->loc); + copy_v3_v3(td->center, td->loc); copy_v3_v3(td->ext->isize, td->ext->size); } diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 3b9e2a982dc..975dbc2e986 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -718,9 +718,6 @@ void postTrans(bContext *C, TransInfo *t) if (t->draw_handle_view) { ED_region_draw_cb_exit(t->region->type, t->draw_handle_view); } - if (t->draw_handle_apply) { - ED_region_draw_cb_exit(t->region->type, t->draw_handle_apply); - } if (t->draw_handle_pixel) { ED_region_draw_cb_exit(t->region->type, t->draw_handle_pixel); } diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c index 955916ff437..aa8dad2b95f 100644 --- a/source/blender/editors/transform/transform_gizmo_3d.c +++ b/source/blender/editors/transform/transform_gizmo_3d.c @@ -939,7 +939,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C, for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *ob_iter = objects[ob_index]; - const bool use_mat_local = params->use_local_axis && (ob_iter != ob); + const bool use_mat_local = (ob_iter != ob); /* mislead counting bones... bah. We don't know the gizmo mode, could be mixed */ const int mode = TFM_ROTATION; @@ -951,7 +951,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C, } /* Use channels to get stats. */ - LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) { + LISTBASE_FOREACH (bPoseChannel *, pchan, &ob_iter->pose->chanbase) { if (!(pchan->bone->flag & BONE_TRANSFORM)) { continue; } diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 7ace6343985..23619a2049a 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -567,10 +567,10 @@ static char snap_flag_from_spacetype(TransInfo *t) if (t->spacetype == SPACE_NODE) { return ts->snap_flag_node; } - else if (t->spacetype == SPACE_IMAGE) { + if (t->spacetype == SPACE_IMAGE) { return ts->snap_uv_flag; } - else if (t->spacetype == SPACE_SEQ) { + if (t->spacetype == SPACE_SEQ) { return ts->snap_flag_seq; } return ts->snap_flag; @@ -579,89 +579,97 @@ static char snap_flag_from_spacetype(TransInfo *t) static short snap_mode_from_spacetype(TransInfo *t) { ToolSettings *ts = t->settings; - short r_snap_mode = SCE_SNAP_MODE_INCREMENT; if (t->spacetype == SPACE_NODE) { - r_snap_mode = ts->snap_node_mode; + return ts->snap_node_mode; } - else if (t->spacetype == SPACE_IMAGE) { - r_snap_mode = ts->snap_uv_mode; - if ((r_snap_mode & SCE_SNAP_MODE_INCREMENT) && (ts->snap_uv_flag & SCE_SNAP_ABS_GRID) && + + if (t->spacetype == SPACE_IMAGE) { + short snap_mode = ts->snap_uv_mode; + if ((snap_mode & SCE_SNAP_MODE_INCREMENT) && (ts->snap_uv_flag & SCE_SNAP_ABS_GRID) && (t->mode == TFM_TRANSLATION)) { - r_snap_mode &= ~SCE_SNAP_MODE_INCREMENT; - r_snap_mode |= SCE_SNAP_MODE_GRID; + snap_mode &= ~SCE_SNAP_MODE_INCREMENT; + snap_mode |= SCE_SNAP_MODE_GRID; } + return snap_mode; } - else if (t->spacetype == SPACE_SEQ) { - r_snap_mode = SEQ_tool_settings_snap_mode_get(t->scene); + + if (t->spacetype == SPACE_SEQ) { + return SEQ_tool_settings_snap_mode_get(t->scene); } - else if ((t->spacetype == SPACE_VIEW3D) && !(t->options & CTX_CAMERA)) { - /* All obedit types will match. */ - const int obedit_type = t->obedit_type; - if ((t->options & (CTX_GPENCIL_STROKES | CTX_CURSOR | CTX_OBMODE_XFORM_OBDATA)) || - ELEM(obedit_type, OB_MESH, OB_ARMATURE, OB_CURVES_LEGACY, OB_LATTICE, OB_MBALL, -1)) { - r_snap_mode = ts->snap_mode; - if ((r_snap_mode & SCE_SNAP_MODE_INCREMENT) && (ts->snap_flag & SCE_SNAP_ABS_GRID) && - (t->mode == TFM_TRANSLATION)) { - /* Special case in which snap to increments is transformed to snap to grid. */ - r_snap_mode &= ~SCE_SNAP_MODE_INCREMENT; - r_snap_mode |= SCE_SNAP_MODE_GRID; - } + + if (t->spacetype == SPACE_VIEW3D) { + if (t->options & (CTX_CAMERA | CTX_EDGE_DATA | CTX_PAINT_CURVE)) { + return SCE_SNAP_MODE_INCREMENT; } + + short snap_mode = ts->snap_mode; + if ((snap_mode & SCE_SNAP_MODE_INCREMENT) && (ts->snap_flag & SCE_SNAP_ABS_GRID) && + (t->mode == TFM_TRANSLATION)) { + /* Special case in which snap to increments is transformed to snap to grid. */ + snap_mode &= ~SCE_SNAP_MODE_INCREMENT; + snap_mode |= SCE_SNAP_MODE_GRID; + } + return snap_mode; } - else if (ELEM(t->spacetype, SPACE_ACTION, SPACE_NLA)) { + + if (ELEM(t->spacetype, SPACE_ACTION, SPACE_NLA)) { /* No incremental snapping. */ - r_snap_mode = 0; + return 0; } - return r_snap_mode; + return SCE_SNAP_MODE_INCREMENT; } static short snap_select_type_get(TransInfo *t) { - short r_snap_select = SNAP_ALL; - ViewLayer *view_layer = t->view_layer; Base *base_act = view_layer->basact; if (ELEM(t->spacetype, SPACE_VIEW3D, SPACE_IMAGE) && !(t->options & CTX_CAMERA)) { - const int obedit_type = t->obedit_type; if (t->options & (CTX_GPENCIL_STROKES | CTX_CURSOR | CTX_OBMODE_XFORM_OBDATA)) { /* In "Edit Strokes" mode, * snap tool can perform snap to selected or active objects (see T49632) * TODO: perform self snap in gpencil_strokes. * * When we're moving the origins, allow snapping onto our own geometry (see T69132). */ + return SNAP_ALL; } - else if ((obedit_type != -1) && - ELEM(obedit_type, OB_MESH, OB_ARMATURE, OB_CURVES_LEGACY, OB_LATTICE, OB_MBALL)) { + + const int obedit_type = t->obedit_type; + if (obedit_type != -1) { /* Edit mode */ - /* Temporary limited to edit mode meshes, armature, curves, metaballs. */ + if (ELEM(obedit_type, OB_MESH, OB_ARMATURE, OB_CURVES_LEGACY, OB_LATTICE, OB_MBALL)) { + /* Temporary limited to edit mode meshes, armature, curves, lattice and metaballs. */ - if ((obedit_type == OB_MESH) && (t->flag & T_PROP_EDIT)) { - /* Exclude editmesh if using proportional edit */ - r_snap_select = SNAP_NOT_ACTIVE; - } - else if (!t->tsnap.snap_self) { - r_snap_select = SNAP_NOT_ACTIVE; - } - else { - r_snap_select = SNAP_NOT_SELECTED; + if ((obedit_type == OB_MESH) && (t->flag & T_PROP_EDIT)) { + /* Exclude editmesh if using proportional edit */ + return SNAP_NOT_EDITED; + } + + if (!t->tsnap.snap_self) { + return SNAP_NOT_ACTIVE; + } + + return SNAP_NOT_SELECTED; } + + return SNAP_ALL; } - else if ((obedit_type == -1) && base_act && base_act->object && - (base_act->object->mode & OB_MODE_PARTICLE_EDIT)) { + + if (base_act && (base_act->object->mode & OB_MODE_PARTICLE_EDIT)) { /* Particles edit mode. */ + return SNAP_ALL; } - else if (obedit_type == -1) { - /* Object or pose mode. */ - r_snap_select = SNAP_NOT_SELECTED; - } + + /* Object or pose mode. */ + return SNAP_NOT_SELECTED; } - else if (ELEM(t->spacetype, SPACE_NODE, SPACE_SEQ)) { - r_snap_select = SNAP_NOT_SELECTED; + + if (ELEM(t->spacetype, SPACE_NODE, SPACE_SEQ)) { + return SNAP_NOT_SELECTED; } - return r_snap_select; + return SNAP_ALL; } static void initSnappingMode(TransInfo *t) diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.cc index 87053fe03d1..3ef5056de85 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.cc @@ -4,7 +4,7 @@ * \ingroup edtransform */ -#include <stdlib.h> +#include <cstdlib> #include "MEM_guardedalloc.h" @@ -55,11 +55,12 @@ enum eViewProj { VIEW_PROJ_PERSP = -1, }; -typedef struct SnapObjectData { - enum { - SNAP_MESH = 1, - SNAP_EDIT_MESH, - } type; +struct SnapObjectData { + enum class Type { + Mesh, + EditMesh, + }; + Type type; BVHTree *bvhtree[2]; /* MESH: loose edges, loose verts * EDIT_MESH: verts, edges. */ @@ -67,7 +68,7 @@ typedef struct SnapObjectData { union { struct { - /* SNAP_MESH */ + /* Type::Mesh */ BVHTreeFromMesh treedata_mesh; const struct MPoly *poly; uint has_looptris : 1; @@ -75,13 +76,13 @@ typedef struct SnapObjectData { uint has_loose_vert : 1; }; struct { - /* SNAP_EDIT_MESH */ + /* Type::EditMesh */ BVHTreeFromEditMesh treedata_editmesh; float min[3], max[3]; struct Mesh_Runtime *mesh_runtime; }; }; -} SnapObjectData; +}; struct SnapObjectContext { Scene *scene; @@ -129,29 +130,29 @@ struct SnapObjectContext { * \{ */ /* Mesh used for snapping. - * If NULL the BMesh should be used. */ -static Mesh *mesh_for_snap(Object *ob_eval, eSnapEditType edit_mode_type, bool *r_use_hide) + * If nullptr the BMesh should be used. */ +static const Mesh *mesh_for_snap(Object *ob_eval, eSnapEditType edit_mode_type, bool *r_use_hide) { - Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval); + const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval); bool use_hide = false; if (BKE_object_is_in_editmode(ob_eval)) { if (edit_mode_type == SNAP_GEOM_EDIT) { - return NULL; + return nullptr; } - Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(ob_eval); - Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(ob_eval); + const Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(ob_eval); + const Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(ob_eval); if ((edit_mode_type == SNAP_GEOM_FINAL) && editmesh_eval_final) { if (editmesh_eval_final->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) { - return NULL; + return nullptr; } me_eval = editmesh_eval_final; use_hide = true; } else if ((edit_mode_type == SNAP_GEOM_CAGE) && editmesh_eval_cage) { if (editmesh_eval_cage->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) { - return NULL; + return nullptr; } me_eval = editmesh_eval_cage; use_hide = true; @@ -185,24 +186,24 @@ static void bm_mesh_minmax(BMesh *bm, float r_min[3], float r_max[3]) static void snap_object_data_mesh_clear(SnapObjectData *sod) { - BLI_assert(sod->type == SNAP_MESH); + BLI_assert(sod->type == SnapObjectData::Type::Mesh); for (int i = 0; i < ARRAY_SIZE(sod->bvhtree); i++) { if (!sod->cached[i]) { BLI_bvhtree_free(sod->bvhtree[i]); } - sod->bvhtree[i] = NULL; + sod->bvhtree[i] = nullptr; } free_bvhtree_from_mesh(&sod->treedata_mesh); } static void snap_object_data_editmesh_clear(SnapObjectData *sod) { - BLI_assert(sod->type == SNAP_EDIT_MESH); + BLI_assert(sod->type == SnapObjectData::Type::EditMesh); for (int i = 0; i < ARRAY_SIZE(sod->bvhtree); i++) { if (!sod->cached[i]) { BLI_bvhtree_free(sod->bvhtree[i]); } - sod->bvhtree[i] = NULL; + sod->bvhtree[i] = nullptr; } free_bvhtree_from_editmesh(&sod->treedata_editmesh); } @@ -210,11 +211,11 @@ static void snap_object_data_editmesh_clear(SnapObjectData *sod) static void snap_object_data_clear(SnapObjectData *sod) { switch (sod->type) { - case SNAP_MESH: { + case SnapObjectData::Type::Mesh: { snap_object_data_mesh_clear(sod); break; } - case SNAP_EDIT_MESH: { + case SnapObjectData::Type::EditMesh: { snap_object_data_editmesh_clear(sod); break; } @@ -224,13 +225,15 @@ static void snap_object_data_clear(SnapObjectData *sod) static SnapObjectData *snap_object_data_lookup(SnapObjectContext *sctx, Object *ob_eval) { - SnapObjectData *sod = BLI_ghash_lookup(sctx->cache.object_map, ob_eval); - if (sod == NULL) { - if (sctx->cache.data_to_object_map != NULL) { - ob_eval = BLI_ghash_lookup(sctx->cache.data_to_object_map, ob_eval->data); + SnapObjectData *sod = static_cast<SnapObjectData *>( + BLI_ghash_lookup(sctx->cache.object_map, ob_eval)); + if (sod == nullptr) { + if (sctx->cache.data_to_object_map != nullptr) { + ob_eval = static_cast<Object *>( + BLI_ghash_lookup(sctx->cache.data_to_object_map, ob_eval->data)); /* Could be NULl when mixing edit-mode and non edit-mode objects. */ - if (ob_eval != NULL) { - sod = BLI_ghash_lookup(sctx->cache.object_map, ob_eval); + if (ob_eval != nullptr) { + sod = static_cast<SnapObjectData *>(BLI_ghash_lookup(sctx->cache.object_map, ob_eval)); } } } @@ -247,9 +250,9 @@ static SnapObjectData *snap_object_data_mesh_get(SnapObjectContext *sctx, bool init = false; if (BLI_ghash_ensure_p(sctx->cache.object_map, ob_eval, &sod_p)) { - sod = *sod_p; + sod = static_cast<SnapObjectData *>(*sod_p); bool is_dirty = false; - if (sod->type != SNAP_MESH) { + if (sod->type != SnapObjectData::Type::Mesh) { is_dirty = true; } else if (sod->treedata_mesh.tree && sod->treedata_mesh.cached && @@ -290,21 +293,22 @@ static SnapObjectData *snap_object_data_mesh_get(SnapObjectContext *sctx, } } else { - sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod)); + *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod)); + sod = static_cast<SnapObjectData *>(*sod_p); init = true; } if (init) { - sod->type = SNAP_MESH; + sod->type = SnapObjectData::Type::Mesh; /* The BVHTree from looptris is always required. */ - BLI_assert(sod->treedata_mesh.tree == NULL); + BLI_assert(sod->treedata_mesh.tree == nullptr); BKE_bvhtree_from_mesh_get(&sod->treedata_mesh, me_eval, use_hide ? BVHTREE_FROM_LOOPTRI_NO_HIDDEN : BVHTREE_FROM_LOOPTRI, 4); - if (sod->treedata_mesh.tree == NULL) { + if (sod->treedata_mesh.tree == nullptr) { sod->treedata_mesh.vert = me_eval->mvert; sod->treedata_mesh.vert_normals = BKE_mesh_vertex_normals_ensure(me_eval); sod->treedata_mesh.loop = me_eval->mloop; @@ -312,10 +316,10 @@ static SnapObjectData *snap_object_data_mesh_get(SnapObjectContext *sctx, BLI_assert(sod->has_looptris == false); } else { - BLI_assert(sod->treedata_mesh.vert != NULL); - BLI_assert(sod->treedata_mesh.vert_normals != NULL); - BLI_assert(sod->treedata_mesh.loop != NULL); - BLI_assert(sod->treedata_mesh.looptri != NULL); + BLI_assert(sod->treedata_mesh.vert != nullptr); + BLI_assert(sod->treedata_mesh.vert_normals != nullptr); + BLI_assert(sod->treedata_mesh.loop != nullptr); + BLI_assert(sod->treedata_mesh.looptri != nullptr); sod->has_looptris = true; } @@ -357,12 +361,12 @@ static SnapObjectData *snap_object_data_editmesh_get(SnapObjectContext *sctx, { /* Use object-data as the key in ghash since the editmesh * is used to create bvhtree and is the same for each linked object. */ - if (sctx->cache.data_to_object_map == NULL) { + if (sctx->cache.data_to_object_map == nullptr) { sctx->cache.data_to_object_map = BLI_ghash_ptr_new(__func__); } void **ob_p; if (BLI_ghash_ensure_p(sctx->cache.data_to_object_map, ob_eval->data, &ob_p)) { - ob_eval = *ob_p; + ob_eval = static_cast<Object *>(*ob_p); } else { *ob_p = ob_eval; @@ -370,10 +374,10 @@ static SnapObjectData *snap_object_data_editmesh_get(SnapObjectContext *sctx, } if (BLI_ghash_ensure_p(sctx->cache.object_map, ob_eval, &sod_p)) { - sod = *sod_p; + sod = static_cast<SnapObjectData *>(*sod_p); bool is_dirty = false; /* Check if the geometry has changed. */ - if (sod->type != SNAP_EDIT_MESH) { + if (sod->type != SnapObjectData::Type::EditMesh) { is_dirty = true; } else if (sod->treedata_editmesh.em != em) { @@ -413,12 +417,13 @@ static SnapObjectData *snap_object_data_editmesh_get(SnapObjectContext *sctx, } } else { - sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod)); + *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod)); + sod = static_cast<SnapObjectData *>(*sod_p); init = true; } if (init) { - sod->type = SNAP_EDIT_MESH; + sod->type = SnapObjectData::Type::EditMesh; sod->treedata_editmesh.em = em; sod->mesh_runtime = snap_object_data_editmesh_runtime_get(ob_eval); bm_mesh_minmax(em->bm, sod->min, sod->max); @@ -433,12 +438,12 @@ static SnapObjectData *snap_object_data_editmesh_get(SnapObjectContext *sctx, /** \name Iterator * \{ */ -typedef void (*IterSnapObjsCallback)(SnapObjectContext *sctx, - const struct SnapObjectParams *params, - Object *ob_eval, - float obmat[4][4], - bool is_object_active, - void *data); +using IterSnapObjsCallback = void (*)(SnapObjectContext *sctx, + const struct SnapObjectParams *params, + Object *ob_eval, + float obmat[4][4], + bool is_object_active, + void *data); static bool snap_object_is_snappable(const SnapObjectContext *sctx, const eSnapSelect snap_select, @@ -459,7 +464,11 @@ static bool snap_object_is_snappable(const SnapObjectContext *sctx, } if (snap_select == SNAP_NOT_ACTIVE) { - return base_act == base; + return base_act != base; + } + + if (snap_select == SNAP_NOT_EDITED) { + return base->object->mode != OB_MODE_EDIT; } if (snap_select == SNAP_NOT_SELECTED) { @@ -490,14 +499,8 @@ static void iter_snap_objects(SnapObjectContext *sctx, const eSnapSelect snap_select = params->snap_select; Base *base_act = view_layer->basact; - if (snap_select == SNAP_ONLY_ACTIVE) { - Object *obj_eval = DEG_get_evaluated_object(sctx->runtime.depsgraph, base_act->object); - sob_callback(sctx, params, obj_eval, obj_eval->obmat, true, data); - return; - } - const bool is_in_object_mode = !base_act || base_act->object->mode == OB_MODE_OBJECT; - for (Base *base = view_layer->object_bases.first; base != NULL; base = base->next) { + LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) { if (!snap_object_is_snappable(sctx, snap_select, base_act, base, is_in_object_mode)) { continue; } @@ -506,7 +509,7 @@ static void iter_snap_objects(SnapObjectContext *sctx, Object *obj_eval = DEG_get_evaluated_object(sctx->runtime.depsgraph, base->object); if (obj_eval->transflag & OB_DUPLI || BKE_object_has_geometry_set_instances(obj_eval)) { ListBase *lb = object_duplilist(sctx->runtime.depsgraph, sctx->scene, obj_eval); - for (DupliObject *dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) { + LISTBASE_FOREACH (DupliObject *, dupli_ob, lb) { BLI_assert(DEG_is_evaluated_object(dupli_ob->ob)); sob_callback(sctx, params, dupli_ob->ob, dupli_ob->mat, is_object_active, data); } @@ -554,7 +557,7 @@ static struct SnapObjectHitDepth *hit_depth_create(const float depth, const float obmat[4][4], uint ob_uuid) { - struct SnapObjectHitDepth *hit = MEM_mallocN(sizeof(*hit), __func__); + struct SnapObjectHitDepth *hit = MEM_new<SnapObjectHitDepth>(__func__); hit->depth = depth; copy_v3_v3(hit->co, co); @@ -570,8 +573,8 @@ static struct SnapObjectHitDepth *hit_depth_create(const float depth, static int hit_depth_cmp(const void *arg1, const void *arg2) { - const struct SnapObjectHitDepth *h1 = arg1; - const struct SnapObjectHitDepth *h2 = arg2; + const struct SnapObjectHitDepth *h1 = static_cast<const struct SnapObjectHitDepth *>(arg1); + const struct SnapObjectHitDepth *h2 = static_cast<const struct SnapObjectHitDepth *>(arg2); int val = 0; if (h1->depth < h2->depth) { @@ -586,7 +589,7 @@ static int hit_depth_cmp(const void *arg1, const void *arg2) static void raycast_all_cb(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) { - struct RayCastAll_Data *data = userdata; + struct RayCastAll_Data *data = static_cast<struct RayCastAll_Data *>(userdata); data->raycast_callback(data->bvhdata, index, ray, hit); if (hit->index != -1) { /* Get all values in world-space. */ @@ -719,7 +722,7 @@ static bool raycastMesh(SnapObjectContext *sctx, if (bb) { /* was BKE_boundbox_ray_hit_check, see: cf6ca226fa58 */ if (!isect_ray_aabb_v3_simple( - ray_start_local, ray_normal_local, bb->vec[0], bb->vec[6], &len_diff, NULL)) { + ray_start_local, ray_normal_local, bb->vec[0], bb->vec[6], &len_diff, nullptr)) { return retval; } } @@ -739,14 +742,14 @@ static bool raycastMesh(SnapObjectContext *sctx, BVHTreeFromMesh *treedata = &sod->treedata_mesh; - if (treedata->tree == NULL) { + if (treedata->tree == nullptr) { return retval; } float timat[3][3]; /* transpose inverse matrix for normals */ transpose_m3_m4(timat, imat); - BLI_assert(treedata->raycast_callback != NULL); + BLI_assert(treedata->raycast_callback != nullptr); if (r_hit_list) { struct RayCastAll_Data data; @@ -772,10 +775,9 @@ static bool raycastMesh(SnapObjectContext *sctx, retval = data.retval; } else { - BVHTreeRayHit hit = { - .index = -1, - .dist = local_depth, - }; + BVHTreeRayHit hit{}; + hit.index = -1; + hit.dist = local_depth; if (BLI_bvhtree_ray_cast(treedata->tree, ray_start_local, @@ -859,7 +861,7 @@ static bool raycastEditMesh(SnapObjectContext *sctx, /* was BKE_boundbox_ray_hit_check, see: cf6ca226fa58 */ if (!isect_ray_aabb_v3_simple( - ray_start_local, ray_normal_local, sod->min, sod->max, &len_diff, NULL)) { + ray_start_local, ray_normal_local, sod->min, sod->max, &len_diff, nullptr)) { return retval; } @@ -877,7 +879,7 @@ static bool raycastEditMesh(SnapObjectContext *sctx, BVHTreeFromEditMesh *treedata = &sod->treedata_editmesh; - if (treedata->tree == NULL) { + if (treedata->tree == nullptr) { /* Operators only update the editmesh looptris of the original mesh. */ BLI_assert(sod->treedata_editmesh.em == BKE_editmesh_from_object(DEG_get_original_object(ob_eval))); @@ -894,8 +896,16 @@ static bool raycastEditMesh(SnapObjectContext *sctx, sctx->callbacks.edit_mesh.test_face_fn, sctx->callbacks.edit_mesh.user_data); - bvhtree_from_editmesh_looptri_ex( - treedata, em, elem_mask, looptri_num_active, 0.0f, 4, 6, 0, NULL, NULL); + bvhtree_from_editmesh_looptri_ex(treedata, + em, + elem_mask, + looptri_num_active, + 0.0f, + 4, + 6, + BVHTREE_FROM_EM_LOOPTRI, + nullptr, + nullptr); MEM_freeN(elem_mask); } @@ -907,10 +917,10 @@ static bool raycastEditMesh(SnapObjectContext *sctx, 4, BVHTREE_FROM_EM_LOOPTRI, &sod->mesh_runtime->bvh_cache, - sod->mesh_runtime->eval_mutex); + static_cast<ThreadMutex *>(sod->mesh_runtime->eval_mutex)); } - if (treedata->tree == NULL) { + if (treedata->tree == nullptr) { return retval; } } @@ -943,10 +953,9 @@ static bool raycastEditMesh(SnapObjectContext *sctx, retval = data.retval; } else { - BVHTreeRayHit hit = { - .index = -1, - .dist = local_depth, - }; + BVHTreeRayHit hit{}; + hit.index = -1; + hit.dist = local_depth; if (BLI_bvhtree_ray_cast(treedata->tree, ray_start_local, @@ -1013,7 +1022,7 @@ static void raycast_obj_fn(SnapObjectContext *sctx, bool is_object_active, void *data) { - struct RaycastObjUserData *dt = data; + RaycastObjUserData *dt = static_cast<RaycastObjUserData *>(data); const uint ob_index = dt->ob_index++; bool use_occlusion_test = dt->use_occlusion_test; /* read/write args */ @@ -1032,8 +1041,8 @@ static void raycast_obj_fn(SnapObjectContext *sctx, case OB_MESH: { const eSnapEditType edit_mode_type = params->edit_mode_type; bool use_hide = false; - Mesh *me_eval = mesh_for_snap(ob_eval, edit_mode_type, &use_hide); - if (me_eval == NULL) { + const Mesh *me_eval = mesh_for_snap(ob_eval, edit_mode_type, &use_hide); + if (me_eval == nullptr) { /* Operators only update the editmesh looptris of the original mesh. */ BMEditMesh *em_orig = BKE_editmesh_from_object(DEG_get_original_object(ob_eval)); retval = raycastEditMesh(sctx, @@ -1154,20 +1163,19 @@ static bool raycastObjects(SnapObjectContext *sctx, } } - struct RaycastObjUserData data = { - .ray_start = ray_start, - .ray_dir = ray_dir, - .ob_index = 0, - .ray_depth = ray_depth, - .r_loc = r_loc, - .r_no = r_no, - .r_index = r_index, - .r_ob = r_ob, - .r_obmat = r_obmat, - .r_hit_list = r_hit_list, - .use_occlusion_test = params->use_occlusion_test, - .ret = false, - }; + RaycastObjUserData data = {}; + data.ray_start = ray_start; + data.ray_dir = ray_dir; + data.ob_index = 0; + data.ray_depth = ray_depth; + data.r_loc = r_loc; + data.r_no = r_no; + data.r_index = r_index; + data.r_ob = r_ob; + data.r_obmat = r_obmat; + data.r_hit_list = r_hit_list; + data.use_occlusion_test = params->use_occlusion_test; + data.ret = false; iter_snap_objects(sctx, params, raycast_obj_fn, &data); @@ -1211,24 +1219,24 @@ static bool snap_bound_box_check_dist(const float min[3], struct Nearest2dUserData; -typedef void (*Nearest2DGetVertCoCallback)(const int index, - const struct Nearest2dUserData *data, - const float **r_co); -typedef void (*Nearest2DGetEdgeVertsCallback)(const int index, +using Nearest2DGetVertCoCallback = void (*)(const int index, + const struct Nearest2dUserData *data, + const float **r_co); +using Nearest2DGetEdgeVertsCallback = void (*)(const int index, + const struct Nearest2dUserData *data, + int r_v_index[2]); +using Nearest2DGetTriVertsCallback = void (*)(const int index, const struct Nearest2dUserData *data, - int r_v_index[2]); -typedef void (*Nearest2DGetTriVertsCallback)(const int index, - const struct Nearest2dUserData *data, - int r_v_index[3]); + int r_v_index[3]); /* Equal the previous one */ -typedef void (*Nearest2DGetTriEdgesCallback)(const int index, +using Nearest2DGetTriEdgesCallback = void (*)(const int index, + const struct Nearest2dUserData *data, + int r_e_index[3]); +using Nearest2DCopyVertNoCallback = void (*)(const int index, const struct Nearest2dUserData *data, - int r_e_index[3]); -typedef void (*Nearest2DCopyVertNoCallback)(const int index, - const struct Nearest2dUserData *data, - float r_no[3]); + float r_no[3]); -typedef struct Nearest2dUserData { +struct Nearest2dUserData { Nearest2DGetVertCoCallback get_vert_co; Nearest2DGetEdgeVertsCallback get_edge_verts_index; Nearest2DGetTriVertsCallback get_tri_verts_index; @@ -1250,7 +1258,7 @@ typedef struct Nearest2dUserData { bool is_persp; bool use_backface_culling; -} Nearest2dUserData; +}; static void cb_mvert_co_get(const int index, const Nearest2dUserData *data, const float **r_co) { @@ -1386,7 +1394,7 @@ static void cb_snap_vert(void *userdata, const int clip_plane_len, BVHTreeNearest *nearest) { - Nearest2dUserData *data = userdata; + Nearest2dUserData *data = static_cast<Nearest2dUserData *>(userdata); const float *co; data->get_vert_co(index, data, &co); @@ -1410,7 +1418,7 @@ static void cb_snap_edge(void *userdata, const int clip_plane_len, BVHTreeNearest *nearest) { - struct Nearest2dUserData *data = userdata; + Nearest2dUserData *data = static_cast<Nearest2dUserData *>(userdata); int vindex[2]; data->get_edge_verts_index(index, data, vindex); @@ -1439,7 +1447,7 @@ static void cb_snap_edge_verts(void *userdata, const int clip_plane_len, BVHTreeNearest *nearest) { - struct Nearest2dUserData *data = userdata; + Nearest2dUserData *data = static_cast<Nearest2dUserData *>(userdata); int vindex[2]; data->get_edge_verts_index(index, data, vindex); @@ -1459,7 +1467,7 @@ static void cb_snap_tri_edges(void *userdata, const int clip_plane_len, BVHTreeNearest *nearest) { - Nearest2dUserData *data = userdata; + Nearest2dUserData *data = static_cast<Nearest2dUserData *>(userdata); if (data->use_backface_culling) { int vindex[3]; @@ -1494,7 +1502,7 @@ static void cb_snap_tri_verts(void *userdata, const int clip_plane_len, BVHTreeNearest *nearest) { - struct Nearest2dUserData *data = userdata; + Nearest2dUserData *data = static_cast<Nearest2dUserData *>(userdata); int vindex[3]; data->get_tri_verts_index(index, data, vindex); @@ -1523,7 +1531,7 @@ static void nearest2d_data_init(SnapObjectData *sod, bool use_backface_culling, Nearest2dUserData *r_nearest2d) { - if (sod->type == SNAP_MESH) { + if (sod->type == SnapObjectData::Type::Mesh) { r_nearest2d->get_vert_co = cb_mvert_co_get; r_nearest2d->get_edge_verts_index = cb_medge_verts_get; r_nearest2d->copy_vert_no = cb_mvert_no_copy; @@ -1537,12 +1545,12 @@ static void nearest2d_data_init(SnapObjectData *sod, r_nearest2d->looptri = sod->treedata_mesh.looptri; } else { - BLI_assert(sod->type == SNAP_EDIT_MESH); + BLI_assert(sod->type == SnapObjectData::Type::EditMesh); r_nearest2d->get_vert_co = cb_bvert_co_get; r_nearest2d->get_edge_verts_index = cb_bedge_verts_get; r_nearest2d->copy_vert_no = cb_bvert_no_copy; - r_nearest2d->get_tri_verts_index = NULL; - r_nearest2d->get_tri_edges_index = NULL; + r_nearest2d->get_tri_verts_index = nullptr; + r_nearest2d->get_tri_edges_index = nullptr; r_nearest2d->bm = sod->treedata_editmesh.em->bm; } @@ -1583,26 +1591,25 @@ static short snap_mesh_polygon(SnapObjectContext *sctx, mul_v4_m4v4(clip_planes_local[i], tobmat, sctx->runtime.clip_plane[i]); } - BVHTreeNearest nearest = { - .index = -1, - .dist_sq = square_f(*dist_px), - }; + BVHTreeNearest nearest{}; + nearest.index = -1; + nearest.dist_sq = square_f(*dist_px); SnapObjectData *sod = snap_object_data_lookup(sctx, ob_eval); - BLI_assert(sod != NULL); + BLI_assert(sod != nullptr); Nearest2dUserData nearest2d; nearest2d_data_init( sod, sctx->runtime.view_proj == VIEW_PROJ_PERSP, params->use_backface_culling, &nearest2d); - if (sod->type == SNAP_MESH) { + if (sod->type == SnapObjectData::Type::Mesh) { BVHTreeFromMesh *treedata = &sod->treedata_mesh; const MPoly *mp = &sod->poly[*r_index]; const MLoop *ml = &treedata->loop[mp->loopstart]; if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_EDGE) { elem = SCE_SNAP_MODE_EDGE; - BLI_assert(treedata->edge != NULL); + BLI_assert(treedata->edge != nullptr); for (int i = mp->totloop; i--; ml++) { cb_snap_edge(&nearest2d, ml->e, @@ -1625,7 +1632,7 @@ static short snap_mesh_polygon(SnapObjectContext *sctx, } } else { - BLI_assert(sod->type == SNAP_EDIT_MESH); + BLI_assert(sod->type == SnapObjectData::Type::EditMesh); BMEditMesh *em = sod->treedata_editmesh.em; BM_mesh_elem_table_ensure(em->bm, BM_FACE); @@ -1702,7 +1709,7 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx, } SnapObjectData *sod = snap_object_data_lookup(sctx, ob_eval); - BLI_assert(sod != NULL); + BLI_assert(sod != nullptr); Nearest2dUserData nearest2d; nearest2d_data_init( @@ -1724,10 +1731,9 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx, &neasrest_precalc, lpmat, sctx->runtime.win_size, sctx->runtime.mval); } - BVHTreeNearest nearest = { - .index = -1, - .dist_sq = square_f(original_dist_px), - }; + BVHTreeNearest nearest{}; + nearest.index = -1; + nearest.dist_sq = square_f(original_dist_px); float lambda; if (!isect_ray_line_v3(neasrest_precalc.ray_origin, @@ -1749,7 +1755,7 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx, int v_id = lambda < 0.5f ? 0 : 1; if (test_projected_vert_dist(&neasrest_precalc, - NULL, + nullptr, 0, nearest2d.is_persp, v_pair[v_id], @@ -1775,7 +1781,7 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx, mid_v3_v3v3(vmid, v_pair[0], v_pair[1]); if (test_projected_vert_dist(&neasrest_precalc, - NULL, + nullptr, 0, nearest2d.is_persp, vmid, @@ -1802,7 +1808,7 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx, &neasrest_precalc, sctx->runtime.pmat, sctx->runtime.win_size, sctx->runtime.mval); if (test_projected_vert_dist(&neasrest_precalc, - NULL, + nullptr, 0, nearest2d.is_persp, v_near, @@ -1855,8 +1861,8 @@ static short snapArmature(SnapObjectContext *sctx, dist_squared_to_projected_aabb_precalc( &neasrest_precalc, lpmat, sctx->runtime.win_size, sctx->runtime.mval); - bArmature *arm = ob_eval->data; - const bool is_editmode = arm->edbo != NULL; + bArmature *arm = static_cast<bArmature *>(ob_eval->data); + const bool is_editmode = arm->edbo != nullptr; if (is_editmode == false) { /* Test BoundBox */ @@ -2015,7 +2021,7 @@ static short snapCurve(SnapObjectContext *sctx, return 0; } - Curve *cu = ob_eval->data; + Curve *cu = static_cast<Curve *>(ob_eval->data); float dist_px_sq = square_f(*dist_px); float lpmat[4][4]; @@ -2060,7 +2066,7 @@ static short snapCurve(SnapObjectContext *sctx, bool is_persp = sctx->runtime.view_proj == VIEW_PROJ_PERSP; bool skip_selected = params->snap_select == SNAP_NOT_SELECTED; - for (Nurb *nu = (use_obedit ? cu->editnurb->nurbs.first : cu->nurb.first); nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, (use_obedit ? &cu->editnurb->nurbs : &cu->nurb)) { for (int u = 0; u < nu->pntsu; u++) { if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX) { if (use_obedit) { @@ -2243,7 +2249,7 @@ static short snapCamera(const SnapObjectContext *sctx, MovieClip *clip = BKE_object_movieclip_get(scene, object, false); MovieTracking *tracking; - if (clip == NULL) { + if (clip == nullptr) { return snap_object_center(sctx, object, obmat, dist_px, r_loc, r_no, r_index); } if (object->transflag & OB_DUPLI) { @@ -2262,11 +2268,8 @@ static short snapCamera(const SnapObjectContext *sctx, dist_squared_to_projected_aabb_precalc( &neasrest_precalc, sctx->runtime.pmat, sctx->runtime.win_size, sctx->runtime.mval); - MovieTrackingObject *tracking_object; - for (tracking_object = tracking->objects.first; tracking_object; - tracking_object = tracking_object->next) { + LISTBASE_FOREACH (MovieTrackingObject *, tracking_object, &tracking->objects) { ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object); - MovieTrackingTrack *track; float reconstructed_camera_mat[4][4], reconstructed_camera_imat[4][4]; float(*vertex_obmat)[4]; @@ -2277,7 +2280,7 @@ static short snapCamera(const SnapObjectContext *sctx, invert_m4_m4(reconstructed_camera_imat, reconstructed_camera_mat); } - for (track = tracksbase->first; track; track = track->next) { + LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) { float bundle_pos[3]; if ((track->flag & TRACK_HAS_BUNDLE) == 0) { @@ -2322,7 +2325,7 @@ static short snapCamera(const SnapObjectContext *sctx, static short snapMesh(SnapObjectContext *sctx, const struct SnapObjectParams *params, Object *ob_eval, - Mesh *me_eval, + const Mesh *me_eval, const float obmat[4][4], bool use_hide, /* read/write args */ @@ -2358,10 +2361,10 @@ static short snapMesh(SnapObjectContext *sctx, BVHTreeFromMesh *treedata, treedata_tmp; treedata = &sod->treedata_mesh; - if (sod->has_loose_edge && sod->bvhtree[0] == NULL) { + if (sod->has_loose_edge && sod->bvhtree[0] == nullptr) { sod->bvhtree[0] = BKE_bvhtree_from_mesh_get( &treedata_tmp, me_eval, BVHTREE_FROM_LOOSEEDGES, 2); - if (sod->bvhtree[0] == NULL) { + if (sod->bvhtree[0] == nullptr) { sod->has_loose_edge = false; } sod->cached[0] = treedata_tmp.cached; @@ -2374,10 +2377,10 @@ static short snapMesh(SnapObjectContext *sctx, } if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX) { - if (sod->has_loose_vert && sod->bvhtree[1] == NULL) { + if (sod->has_loose_vert && sod->bvhtree[1] == nullptr) { sod->bvhtree[1] = BKE_bvhtree_from_mesh_get( &treedata_tmp, me_eval, BVHTREE_FROM_LOOSEVERTS, 2); - if (sod->bvhtree[1] == NULL) { + if (sod->bvhtree[1] == nullptr) { sod->has_loose_vert = false; } sod->cached[1] = treedata_tmp.cached; @@ -2398,10 +2401,10 @@ static short snapMesh(SnapObjectContext *sctx, nearest2d_data_init( sod, sctx->runtime.view_proj == VIEW_PROJ_PERSP, params->use_backface_culling, &nearest2d); - BVHTreeNearest nearest = { - .index = -1, - .dist_sq = dist_px_sq, - }; + BVHTreeNearest nearest{}; + nearest.index = -1; + nearest.dist_sq = dist_px_sq; + int last_index = nearest.index; short elem = SCE_SNAP_MODE_VERTEX; @@ -2551,10 +2554,11 @@ static short snapEditMesh(SnapObjectContext *sctx, } if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX) { - BVHTreeFromEditMesh treedata = {.tree = sod->bvhtree[0]}; + BVHTreeFromEditMesh treedata{}; + treedata.tree = sod->bvhtree[0]; - if (treedata.tree == NULL) { - BLI_bitmap *verts_mask = NULL; + if (treedata.tree == nullptr) { + BLI_bitmap *verts_mask = nullptr; int verts_num_active = -1; if (sctx->callbacks.edit_mesh.test_vert_fn) { verts_mask = BLI_BITMAP_NEW(em->bm->totvert, __func__); @@ -2565,8 +2569,16 @@ static short snapEditMesh(SnapObjectContext *sctx, (bool (*)(BMElem *, void *))sctx->callbacks.edit_mesh.test_vert_fn, sctx->callbacks.edit_mesh.user_data); - bvhtree_from_editmesh_verts_ex( - &treedata, em, verts_mask, verts_num_active, 0.0f, 2, 6, 0, NULL, NULL); + bvhtree_from_editmesh_verts_ex(&treedata, + em, + verts_mask, + verts_num_active, + 0.0f, + 2, + 6, + BVHTREE_FROM_VERTS, + nullptr, + nullptr); MEM_freeN(verts_mask); } else { @@ -2583,10 +2595,11 @@ static short snapEditMesh(SnapObjectContext *sctx, } if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_EDGE) { - BVHTreeFromEditMesh treedata = {.tree = sod->bvhtree[1]}; + BVHTreeFromEditMesh treedata{}; + treedata.tree = sod->bvhtree[1]; - if (treedata.tree == NULL) { - BLI_bitmap *edges_mask = NULL; + if (treedata.tree == nullptr) { + BLI_bitmap *edges_mask = nullptr; int edges_num_active = -1; if (sctx->callbacks.edit_mesh.test_edge_fn) { edges_mask = BLI_BITMAP_NEW(em->bm->totedge, __func__); @@ -2597,8 +2610,16 @@ static short snapEditMesh(SnapObjectContext *sctx, (bool (*)(BMElem *, void *))sctx->callbacks.edit_mesh.test_edge_fn, sctx->callbacks.edit_mesh.user_data); - bvhtree_from_editmesh_edges_ex( - &treedata, em, edges_mask, edges_num_active, 0.0f, 2, 6, 0, NULL, NULL); + bvhtree_from_editmesh_edges_ex(&treedata, + em, + edges_mask, + edges_num_active, + 0.0f, + 2, + 6, + BVHTREE_FROM_VERTS, + nullptr, + nullptr); MEM_freeN(edges_mask); } else { @@ -2607,7 +2628,7 @@ static short snapEditMesh(SnapObjectContext *sctx, 2, BVHTREE_FROM_EM_EDGES, &sod->mesh_runtime->bvh_cache, - sod->mesh_runtime->eval_mutex); + static_cast<ThreadMutex *>(sod->mesh_runtime->eval_mutex)); } sod->bvhtree[1] = treedata.tree; sod->cached[1] = treedata.cached; @@ -2618,10 +2639,10 @@ static short snapEditMesh(SnapObjectContext *sctx, nearest2d_data_init( sod, sctx->runtime.view_proj == VIEW_PROJ_PERSP, params->use_backface_culling, &nearest2d); - BVHTreeNearest nearest = { - .index = -1, - .dist_sq = dist_px_sq, - }; + BVHTreeNearest nearest{}; + nearest.index = -1; + nearest.dist_sq = dist_px_sq; + short elem = SCE_SNAP_MODE_VERTEX; float tobmat[4][4], clip_planes_local[MAX_CLIPPLANE_LEN][4]; @@ -2713,15 +2734,15 @@ static void snap_obj_fn(SnapObjectContext *sctx, bool is_object_active, void *data) { - struct SnapObjUserData *dt = data; + SnapObjUserData *dt = static_cast<SnapObjUserData *>(data); short retval = 0; switch (ob_eval->type) { case OB_MESH: { const eSnapEditType edit_mode_type = params->edit_mode_type; bool use_hide; - Mesh *me_eval = mesh_for_snap(ob_eval, edit_mode_type, &use_hide); - if (me_eval == NULL) { + const Mesh *me_eval = mesh_for_snap(ob_eval, edit_mode_type, &use_hide); + if (me_eval == nullptr) { /* Operators only update the editmesh looptris of the original mesh. */ BMEditMesh *em_orig = BKE_editmesh_from_object(DEG_get_original_object(ob_eval)); retval = snapEditMesh( @@ -2762,7 +2783,7 @@ static void snap_obj_fn(SnapObjectContext *sctx, break; /* Use ATTR_FALLTHROUGH if we want to snap to the generated mesh. */ case OB_SURF: case OB_FONT: { - Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval); + const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval); if (mesh_eval) { retval |= snapMesh(sctx, params, @@ -2835,15 +2856,14 @@ static short snapObjectsRay(SnapObjectContext *sctx, Object **r_ob, float r_obmat[4][4]) { - struct SnapObjUserData data = { - .dist_px = dist_px, - .r_loc = r_loc, - .r_no = r_no, - .r_ob = r_ob, - .r_index = r_index, - .r_obmat = r_obmat, - .ret = 0, - }; + SnapObjUserData data = {}; + data.dist_px = dist_px; + data.r_loc = r_loc; + data.r_no = r_no; + data.r_ob = r_ob; + data.r_index = r_index; + data.r_obmat = r_obmat; + data.ret = 0; iter_snap_objects(sctx, params, snap_obj_fn, &data); @@ -2858,7 +2878,7 @@ static short snapObjectsRay(SnapObjectContext *sctx, SnapObjectContext *ED_transform_snap_object_context_create(Scene *scene, int flag) { - SnapObjectContext *sctx = MEM_callocN(sizeof(*sctx), __func__); + SnapObjectContext *sctx = MEM_cnew<SnapObjectContext>(__func__); sctx->flag = flag; @@ -2866,7 +2886,7 @@ SnapObjectContext *ED_transform_snap_object_context_create(Scene *scene, int fla sctx->cache.object_map = BLI_ghash_ptr_new(__func__); /* Initialize as needed (edit-mode only). */ - sctx->cache.data_to_object_map = NULL; + sctx->cache.data_to_object_map = nullptr; sctx->cache.mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); return sctx; @@ -2874,15 +2894,15 @@ SnapObjectContext *ED_transform_snap_object_context_create(Scene *scene, int fla static void snap_object_data_free(void *sod_v) { - SnapObjectData *sod = sod_v; + SnapObjectData *sod = static_cast<SnapObjectData *>(sod_v); snap_object_data_clear(sod); } void ED_transform_snap_object_context_destroy(SnapObjectContext *sctx) { - BLI_ghash_free(sctx->cache.object_map, NULL, snap_object_data_free); - if (sctx->cache.data_to_object_map != NULL) { - BLI_ghash_free(sctx->cache.data_to_object_map, NULL, NULL); + BLI_ghash_free(sctx->cache.object_map, nullptr, snap_object_data_free); + if (sctx->cache.data_to_object_map != nullptr) { + BLI_ghash_free(sctx->cache.data_to_object_map, nullptr, nullptr); } BLI_memarena_free(sctx->cache.mem_arena); @@ -2919,8 +2939,17 @@ bool ED_transform_snap_object_project_ray_ex(SnapObjectContext *sctx, sctx->runtime.depsgraph = depsgraph; sctx->runtime.v3d = v3d; - return raycastObjects( - sctx, params, ray_start, ray_normal, ray_depth, r_loc, r_no, r_index, r_ob, r_obmat, NULL); + return raycastObjects(sctx, + params, + ray_start, + ray_normal, + ray_depth, + r_loc, + r_no, + r_index, + r_ob, + r_obmat, + nullptr); } bool ED_transform_snap_object_project_ray_all(SnapObjectContext *sctx, @@ -2944,8 +2973,17 @@ bool ED_transform_snap_object_project_ray_all(SnapObjectContext *sctx, float ray_depth_prev = ray_depth; #endif - bool retval = raycastObjects( - sctx, params, ray_start, ray_normal, &ray_depth, NULL, NULL, NULL, NULL, NULL, r_hit_list); + bool retval = raycastObjects(sctx, + params, + ray_start, + ray_normal, + &ray_depth, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + r_hit_list); /* meant to be readonly for 'all' hits, ensure it is */ #ifdef DEBUG @@ -2988,9 +3026,9 @@ static bool transform_snap_context_project_ray_impl(SnapObjectContext *sctx, ray_depth, r_co, r_no, - NULL, - NULL, - NULL); + nullptr, + nullptr, + nullptr); return ret; } @@ -3006,7 +3044,7 @@ bool ED_transform_snap_object_project_ray(SnapObjectContext *sctx, float r_no[3]) { float ray_depth_fallback; - if (ray_depth == NULL) { + if (ray_depth == nullptr) { ray_depth_fallback = BVH_RAYCAST_DIST_MAX; ray_depth = &ray_depth_fallback; } @@ -3043,7 +3081,7 @@ static short transform_snap_context_project_view3d_mixed_impl( short retval = 0; bool has_hit = false; - Object *ob_eval = NULL; + Object *ob_eval = nullptr; float loc[3]; /* Not all snapping callbacks set the normal, * initialize this since any hit copies both the `loc` and `no`. */ @@ -3051,14 +3089,14 @@ static short transform_snap_context_project_view3d_mixed_impl( float obmat[4][4]; int index = -1; - const RegionView3D *rv3d = region->regiondata; + const RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata); bool use_occlusion_test = params->use_occlusion_test && !XRAY_ENABLED(v3d); if (snap_to_flag & SCE_SNAP_MODE_FACE || use_occlusion_test) { float ray_start[3], ray_normal[3]; if (!ED_view3d_win_to_ray_clipped_ex( - depsgraph, region, v3d, mval, NULL, ray_normal, ray_start, true)) { + depsgraph, region, v3d, mval, nullptr, ray_normal, ray_start, true)) { return 0; } @@ -3074,7 +3112,7 @@ static short transform_snap_context_project_view3d_mixed_impl( &index, &ob_eval, obmat, - NULL); + nullptr); if (has_hit) { if (r_face_nor) { @@ -3119,10 +3157,10 @@ static short transform_snap_context_project_view3d_mixed_impl( } planes_from_projmat(sctx->runtime.pmat, - NULL, - NULL, - NULL, - NULL, + nullptr, + nullptr, + nullptr, + nullptr, sctx->runtime.clip_plane[0], sctx->runtime.clip_plane[1]); @@ -3255,10 +3293,10 @@ short ED_transform_snap_object_project_view3d(SnapObjectContext *sctx, dist_px, r_loc, r_no, - NULL, - NULL, - NULL, - NULL); + nullptr, + nullptr, + nullptr, + nullptr); } bool ED_transform_snap_object_project_all_view3d_ex(SnapObjectContext *sctx, @@ -3274,7 +3312,7 @@ bool ED_transform_snap_object_project_all_view3d_ex(SnapObjectContext *sctx, float ray_start[3], ray_normal[3]; if (!ED_view3d_win_to_ray_clipped_ex( - depsgraph, region, v3d, mval, NULL, ray_normal, ray_start, true)) { + depsgraph, region, v3d, mval, nullptr, ray_normal, ray_start, true)) { return false; } diff --git a/source/blender/freestyle/intern/python/BPy_Convert.cpp b/source/blender/freestyle/intern/python/BPy_Convert.cpp index 55a33720465..02ed3f463c7 100644 --- a/source/blender/freestyle/intern/python/BPy_Convert.cpp +++ b/source/blender/freestyle/intern/python/BPy_Convert.cpp @@ -569,7 +569,7 @@ bool Vec3r_ptr_from_PyObject(PyObject *obj, Vec3r &vec) bool Vec2f_ptr_from_Vector(PyObject *obj, Vec2f &vec) { - if (!VectorObject_Check(obj) || ((VectorObject *)obj)->size != 2) { + if (!VectorObject_Check(obj) || ((VectorObject *)obj)->vec_num != 2) { return false; } if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1) { @@ -582,7 +582,7 @@ bool Vec2f_ptr_from_Vector(PyObject *obj, Vec2f &vec) bool Vec3f_ptr_from_Vector(PyObject *obj, Vec3f &vec) { - if (!VectorObject_Check(obj) || ((VectorObject *)obj)->size != 3) { + if (!VectorObject_Check(obj) || ((VectorObject *)obj)->vec_num != 3) { return false; } if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1) { @@ -596,7 +596,7 @@ bool Vec3f_ptr_from_Vector(PyObject *obj, Vec3f &vec) bool Vec3r_ptr_from_Vector(PyObject *obj, Vec3r &vec) { - if (!VectorObject_Check(obj) || ((VectorObject *)obj)->size != 3) { + if (!VectorObject_Check(obj) || ((VectorObject *)obj)->vec_num != 3) { return false; } if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1) { @@ -758,7 +758,7 @@ bool Vec3r_ptr_from_PyTuple(PyObject *obj, Vec3r &vec) bool float_array_from_PyObject(PyObject *obj, float *v, int n) { - if (VectorObject_Check(obj) && ((VectorObject *)obj)->size == n) { + if (VectorObject_Check(obj) && ((VectorObject *)obj)->vec_num == n) { if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1) { return false; } diff --git a/source/blender/freestyle/intern/python/BPy_MediumType.cpp b/source/blender/freestyle/intern/python/BPy_MediumType.cpp index 494e01967d6..cf8e900e003 100644 --- a/source/blender/freestyle/intern/python/BPy_MediumType.cpp +++ b/source/blender/freestyle/intern/python/BPy_MediumType.cpp @@ -21,7 +21,7 @@ using namespace Freestyle; PyDoc_STRVAR(MediumType_doc, "Class hierarchy: int > :class:`MediumType`\n" "\n" - "The different blending modes available to similate the interaction\n" + "The different blending modes available to simulate the interaction\n" "media-medium:\n" "\n" "* Stroke.DRY_MEDIUM: To simulate a dry medium such as Pencil or Charcoal.\n" diff --git a/source/blender/functions/intern/field.cc b/source/blender/functions/intern/field.cc index 7b514b6a49b..9f742f11ce4 100644 --- a/source/blender/functions/intern/field.cc +++ b/source/blender/functions/intern/field.cc @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "BLI_index_mask_ops.hh" #include "BLI_map.hh" #include "BLI_multi_value_map.hh" #include "BLI_set.hh" @@ -692,29 +693,21 @@ GPointer FieldConstant::value() const * FieldEvaluator. */ -static Vector<int64_t> indices_from_selection(IndexMask mask, const VArray<bool> &selection) +static IndexMask index_mask_from_selection(const IndexMask full_mask, + VArray<bool> &selection, + ResourceScope &scope) { - /* If the selection is just a single value, it's best to avoid calling this - * function when constructing an IndexMask and use an IndexRange instead. */ - BLI_assert(!selection.is_single()); - - Vector<int64_t> indices; if (selection.is_span()) { Span<bool> span = selection.get_internal_span(); - for (const int64_t i : mask) { - if (span[i]) { - indices.append(i); - } - } + return index_mask_ops::find_indices_based_on_predicate( + full_mask, 4096, scope.construct<Vector<int64_t>>(), [&](const int curve_index) { + return span[curve_index]; + }); } - else { - for (const int i : mask) { - if (selection[i]) { - indices.append(i); - } - } - } - return indices; + return index_mask_ops::find_indices_based_on_predicate( + full_mask, 1024, scope.construct<Vector<int64_t>>(), [&](const int curve_index) { + return selection[curve_index]; + }); } int FieldEvaluator::add_with_destination(GField field, GVMutableArray dst) @@ -763,7 +756,7 @@ static IndexMask evaluate_selection(const Field<bool> &selection_field, } return IndexRange(0); } - return scope.add_value(indices_from_selection(full_mask, selection)).as_span(); + return index_mask_from_selection(full_mask, selection, scope); } return full_mask; } @@ -799,8 +792,7 @@ IndexMask FieldEvaluator::get_evaluated_as_mask(const int field_index) } return IndexRange(0); } - - return scope_.add_value(indices_from_selection(mask_, varray)).as_span(); + return index_mask_from_selection(mask_, varray, scope_); } IndexMask FieldEvaluator::get_evaluated_selection_as_mask() diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc index 502f5f0232e..8d186edc607 100644 --- a/source/blender/geometry/intern/realize_instances.cc +++ b/source/blender/geometry/intern/realize_instances.cc @@ -1139,8 +1139,8 @@ static void execute_realize_curve_task(const RealizeInstancesOptions &options, const Curves &curves_id = *curves_info.curves; const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); - const IndexRange dst_point_range{task.start_indices.point, curves.points_size()}; - const IndexRange dst_curve_range{task.start_indices.curve, curves.curves_size()}; + const IndexRange dst_point_range{task.start_indices.point, curves.points_num()}; + const IndexRange dst_curve_range{task.start_indices.curve, curves.curves_num()}; copy_transformed_positions( curves.positions(), task.transform, dst_curves.positions().slice(dst_point_range)); @@ -1194,9 +1194,9 @@ static void execute_realize_curve_task(const RealizeInstancesOptions &options, [&](const AttributeDomain domain) { switch (domain) { case ATTR_DOMAIN_POINT: - return IndexRange(task.start_indices.point, curves.points_size()); + return IndexRange(task.start_indices.point, curves.points_num()); case ATTR_DOMAIN_CURVE: - return IndexRange(task.start_indices.curve, curves.curves_size()); + return IndexRange(task.start_indices.curve, curves.curves_num()); default: BLI_assert_unreachable(); return IndexRange(); diff --git a/source/blender/gpencil_modifiers/CMakeLists.txt b/source/blender/gpencil_modifiers/CMakeLists.txt index 752d4aea61c..6108629183c 100644 --- a/source/blender/gpencil_modifiers/CMakeLists.txt +++ b/source/blender/gpencil_modifiers/CMakeLists.txt @@ -37,6 +37,7 @@ set(SRC intern/MOD_gpencilbuild.c intern/MOD_gpencilcolor.c intern/MOD_gpencildash.c + intern/MOD_gpencilenvelope.c intern/MOD_gpencilhook.c intern/MOD_gpencillattice.c intern/MOD_gpencillength.c diff --git a/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h b/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h index ff280b9ca0d..e88d864a86e 100644 --- a/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h +++ b/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h @@ -35,6 +35,7 @@ extern GpencilModifierTypeInfo modifierType_Gpencil_WeightAngle; extern GpencilModifierTypeInfo modifierType_Gpencil_Lineart; extern GpencilModifierTypeInfo modifierType_Gpencil_Dash; extern GpencilModifierTypeInfo modifierType_Gpencil_Shrinkwrap; +extern GpencilModifierTypeInfo modifierType_Gpencil_Envelope; /* MOD_gpencil_util.c */ void gpencil_modifier_type_init(GpencilModifierTypeInfo *types[]); diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c index e766615101a..6cf7f6f11e5 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c @@ -56,6 +56,7 @@ void gpencil_modifier_type_init(GpencilModifierTypeInfo *types[]) INIT_GP_TYPE(Lineart); INIT_GP_TYPE(Dash); INIT_GP_TYPE(Shrinkwrap); + INIT_GP_TYPE(Envelope); #undef INIT_GP_TYPE } diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencildash.c b/source/blender/gpencil_modifiers/intern/MOD_gpencildash.c index 439073752da..e57b9df03f5 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencildash.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencildash.c @@ -97,12 +97,13 @@ static bool stroke_dash(const bGPDstroke *gps, int new_stroke_offset = 0; int trim_start = 0; + int sequence_length = 0; for (int i = 0; i < dmd->segments_len; i++) { - if (dmd->segments[i].dash + real_gap(&dmd->segments[i]) < 1) { - BLI_assert_unreachable(); - /* This means there's a part that doesn't have any length, can't do dot-dash. */ - return false; - } + sequence_length += dmd->segments[i].dash + real_gap(&dmd->segments[i]); + } + if (sequence_length < 1) { + /* This means the whole segment has no length, can't do dot-dash. */ + return false; } const DashGpencilModifierSegment *const first_segment = &dmd->segments[0]; @@ -147,6 +148,9 @@ static bool stroke_dash(const bGPDstroke *gps, bGPDstroke *stroke = BKE_gpencil_stroke_new( ds->mat_nr < 0 ? gps->mat_nr : ds->mat_nr, size, gps->thickness); + if (ds->flag & GP_DASH_USE_CYCLIC) { + stroke->flag |= GP_STROKE_CYCLIC; + } for (int is = 0; is < size; is++) { bGPDspoint *p = &gps->points[new_stroke_offset + is]; @@ -204,9 +208,10 @@ static void apply_dash_for_frame( dmd->flag & GP_LENGTH_INVERT_PASS, dmd->flag & GP_LENGTH_INVERT_LAYERPASS, dmd->flag & GP_LENGTH_INVERT_MATERIAL)) { - stroke_dash(gps, dmd, &result); - BLI_remlink(&gpf->strokes, gps); - BKE_gpencil_free_stroke(gps); + if (stroke_dash(gps, dmd, &result)) { + BLI_remlink(&gpf->strokes, gps); + BKE_gpencil_free_stroke(gps); + } } } bGPDstroke *gps_dash; @@ -232,6 +237,18 @@ static void bakeModifier(Main *UNUSED(bmain), /* -------------------------------- */ +static bool isDisabled(GpencilModifierData *md, int UNUSED(userRenderParams)) +{ + DashGpencilModifierData *dmd = (DashGpencilModifierData *)md; + + int sequence_length = 0; + for (int i = 0; i < dmd->segments_len; i++) { + sequence_length += dmd->segments[i].dash + real_gap(&dmd->segments[i]); + } + /* This means the whole segment has no length, can't do dot-dash. */ + return sequence_length < 1; +} + /* Generic "generateStrokes" callback */ static void generateStrokes(GpencilModifierData *md, Depsgraph *depsgraph, Object *ob) { @@ -323,6 +340,7 @@ static void panel_draw(const bContext *C, Panel *panel) uiItemR(sub, &ds_ptr, "radius", 0, NULL, ICON_NONE); uiItemR(sub, &ds_ptr, "opacity", 0, NULL, ICON_NONE); uiItemR(sub, &ds_ptr, "material_index", 0, NULL, ICON_NONE); + uiItemR(sub, &ds_ptr, "use_cyclic", 0, NULL, ICON_NONE); } gpencil_modifier_panel_end(layout, ptr); @@ -362,7 +380,7 @@ GpencilModifierTypeInfo modifierType_Gpencil_Dash = { /* initData */ initData, /* freeData */ freeData, - /* isDisabled */ NULL, + /* isDisabled */ isDisabled, /* updateDepsgraph */ NULL, /* dependsOnTime */ NULL, /* foreachIDLink */ foreachIDLink, diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilenvelope.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilenvelope.c new file mode 100644 index 00000000000..f8ac8d95493 --- /dev/null +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilenvelope.c @@ -0,0 +1,628 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2017 Blender Foundation. */ + +/** \file + * \ingroup modifiers + */ + +#include <stdio.h> + +#include "BLI_listbase.h" +#include "BLI_math.h" +#include "BLI_math_geom.h" +#include "BLI_utildefines.h" + +#include "BLT_translation.h" + +#include "DNA_defaults.h" +#include "DNA_gpencil_modifier_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" + +#include "BKE_colortools.h" +#include "BKE_context.h" +#include "BKE_deform.h" +#include "BKE_gpencil.h" +#include "BKE_gpencil_geom.h" +#include "BKE_gpencil_modifier.h" +#include "BKE_lib_query.h" +#include "BKE_modifier.h" +#include "BKE_screen.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" +#include "DEG_depsgraph_query.h" + +#include "UI_interface.h" +#include "UI_resources.h" + +#include "RNA_access.h" + +#include "MOD_gpencil_modifiertypes.h" +#include "MOD_gpencil_ui_common.h" +#include "MOD_gpencil_util.h" + +#include "MEM_guardedalloc.h" + +static void initData(GpencilModifierData *md) +{ + EnvelopeGpencilModifierData *gpmd = (EnvelopeGpencilModifierData *)md; + + BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(gpmd, modifier)); + + MEMCPY_STRUCT_AFTER(gpmd, DNA_struct_default_get(EnvelopeGpencilModifierData), modifier); +} + +static void copyData(const GpencilModifierData *md, GpencilModifierData *target) +{ + BKE_gpencil_modifier_copydata_generic(md, target); +} + +static float calc_min_radius_v3v3(float p1[3], float p2[3], float dir[3]) +{ + /* Use plane-conic-intersections to choose the maximal radius. + * The conic is defined in 4D as f({x,y,z,t}) = x*x + y*y + z*z - t*t = 0 + * Then a plane is defined parametrically as + * {p}(u, v) = {p1,0}*u + {p2,0}*(1-u) + {dir,1}*v with 0 <= u <= 1 and v >= 0 + * Now compute the intersection point with the smallest t. + * To do so, compute the parameters u, v such that f(p(u, v)) = 0 and v is minimal. + * This can be done analytically and the solution is: + * u = -dot(p2,dir) / dot(p1-p2, dir) +/- sqrt((dot(p2,dir) / dot(p1-p2, dir))^2 - + * (2*dot(p1-p2,p2)*dot(p2,dir)-dot(p2,p2)*dot(p1-p2,dir))/(dot(p1-p2,dir)*dot(p1-p2,p1-p2))); + * v = ({p1}u + {p2}*(1-u))^2 / (2*(dot(p1,dir)*u + dot(p2,dir)*(1-u))); + */ + float diff[3]; + float p1_dir = dot_v3v3(p1, dir); + float p2_dir = dot_v3v3(p2, dir); + float p2_sqr = len_squared_v3(p2); + float diff_dir = p1_dir - p2_dir; + float u = 0.5f; + if (diff_dir != 0.0f) { + float p = p2_dir / diff_dir; + sub_v3_v3v3(diff, p1, p2); + float diff_sqr = len_squared_v3(diff); + float diff_p2 = dot_v3v3(diff, p2); + float q = (2 * diff_p2 * p2_dir - p2_sqr * diff_dir) / (diff_dir * diff_sqr); + if (p * p - q >= 0) { + u = -p - sqrtf(p * p - q) * copysign(1.0f, p); + CLAMP(u, 0.0f, 1.0f); + } + else { + u = 0.5f - copysign(0.5f, p); + } + } + else { + float p1_sqr = len_squared_v3(p1); + u = p1_sqr < p2_sqr ? 1.0f : 0.0f; + } + float p[3]; + interp_v3_v3v3(p, p2, p1, u); + /* v is the determined minimal radius. In case p1 and p2 are the same, there is a + * simple proof for the following formula using the geometric mean theorem and Thales theorem. */ + float v = len_squared_v3(p) / (2 * interpf(p1_dir, p2_dir, u)); + if (v < 0 || !isfinite(v)) { + /* No limit to the radius from this segment. */ + return 1e16f; + } + return v; +} + +static float calc_radius_limit( + bGPDstroke *gps, bGPDspoint *points, float dir[3], int spread, const int i) +{ + const bool is_cyclic = (gps->flag & GP_STROKE_CYCLIC) != 0; + bGPDspoint *pt = &points[i]; + + /* NOTE this part is the second performance critical part. Improvements are welcome. */ + float radius_limit = 1e16f; + float p1[3], p2[3]; + if (is_cyclic) { + if (gps->totpoints / 2 < spread) { + spread = gps->totpoints / 2; + } + const int start = i + gps->totpoints; + for (int j = -spread; j <= spread; j++) { + j += (j == 0); + const int i1 = (start + j) % gps->totpoints; + const int i2 = (start + j + (j > 0) - (j < 0)) % gps->totpoints; + sub_v3_v3v3(p1, &points[i1].x, &pt->x); + sub_v3_v3v3(p2, &points[i2].x, &pt->x); + float r = calc_min_radius_v3v3(p1, p2, dir); + radius_limit = min_ff(radius_limit, r); + } + } + else { + const int start = max_ii(-spread, 1 - i); + const int end = min_ii(spread, gps->totpoints - 2 - i); + for (int j = start; j <= end; j++) { + if (j == 0) { + continue; + } + const int i1 = i + j; + const int i2 = i + j + (j > 0) - (j < 0); + sub_v3_v3v3(p1, &points[i1].x, &pt->x); + sub_v3_v3v3(p2, &points[i2].x, &pt->x); + float r = calc_min_radius_v3v3(p1, p2, dir); + radius_limit = min_ff(radius_limit, r); + } + } + return radius_limit; +} + +static void apply_stroke_envelope( + bGPDstroke *gps, int spread, const int def_nr, const bool invert_vg, const float thickness) +{ + const bool is_cyclic = (gps->flag & GP_STROKE_CYCLIC) != 0; + if (is_cyclic) { + const int half = gps->totpoints / 2; + spread = abs(((spread + half) % gps->totpoints) - half); + } + else { + spread = min_ii(spread, gps->totpoints - 1); + } + + const int spread_left = (spread + 2) / 2; + const int spread_right = (spread + 1) / 2; + + /* Copy the point data. Only need positions, but extracting them + * is probably just as expensive as a full copy. */ + bGPDspoint *old_points = (bGPDspoint *)MEM_dupallocN(gps->points); + + /* Deform the stroke to match the envelope shape. */ + for (int i = 0; i < gps->totpoints; i++) { + MDeformVert *dvert = gps->dvert != NULL ? &gps->dvert[i] : NULL; + + /* Verify in vertex group. */ + float weight = get_modifier_point_weight(dvert, invert_vg, def_nr); + if (weight < 0.0f) { + continue; + } + + int index1 = i - spread_left; + int index2 = i + spread_right; + CLAMP(index1, 0, gps->totpoints - 1); + CLAMP(index2, 0, gps->totpoints - 1); + + bGPDspoint *point = &gps->points[i]; + point->pressure *= interpf(thickness, 1.0f, weight); + + float closest[3]; + float closest2[3]; + copy_v3_v3(closest2, &point->x); + float dist = 0.0f; + float dist2 = 0.0f; + /* Create plane from point and neighbors and intersect that with the line. */ + float v1[3], v2[3], plane_no[3]; + sub_v3_v3v3( + v1, + &old_points[is_cyclic ? (i - 1 + gps->totpoints) % gps->totpoints : max_ii(0, i - 1)].x, + &old_points[i].x); + sub_v3_v3v3( + v2, + &old_points[is_cyclic ? (i + 1) % gps->totpoints : min_ii(gps->totpoints - 1, i + 1)].x, + &old_points[i].x); + normalize_v3(v1); + normalize_v3(v2); + sub_v3_v3v3(plane_no, v1, v2); + if (normalize_v3(plane_no) == 0.0f) { + continue; + } + /* Now find the intersections with the plane. */ + /* NOTE this part is the first performance critical part. Improvements are welcome. */ + float tmp_closest[3]; + for (int j = -spread_right; j <= spread_left; j++) { + const int i1 = is_cyclic ? (i + j - spread_left + gps->totpoints) % gps->totpoints : + max_ii(0, i + j - spread_left); + const int i2 = is_cyclic ? (i + j + spread_right) % gps->totpoints : + min_ii(gps->totpoints - 1, i + j + spread_right); + /*bool side = dot_v3v3(&old_points[i1].x, plane_no) < dot_v3v3(plane_no, &old_points[i2].x); + if (side) { + continue; + }*/ + float lambda = line_plane_factor_v3( + &point->x, plane_no, &old_points[i1].x, &old_points[i2].x); + if (lambda <= 0.0f || lambda >= 1.0f) { + continue; + } + interp_v3_v3v3(tmp_closest, &old_points[i1].x, &old_points[i2].x, lambda); + + float dir[3]; + sub_v3_v3v3(dir, tmp_closest, &point->x); + float d = len_v3(dir); + /* Use a formula to find the diameter of the circle that would touch the line. */ + float cos_angle = fabsf(dot_v3v3(plane_no, &old_points[i1].x) - + dot_v3v3(plane_no, &old_points[i2].x)) / + len_v3v3(&old_points[i1].x, &old_points[i2].x); + d *= 2 * cos_angle / (1 + cos_angle); + float to_closest[3]; + sub_v3_v3v3(to_closest, closest, &point->x); + if (dist == 0.0f) { + dist = d; + copy_v3_v3(closest, tmp_closest); + } + else if (dot_v3v3(to_closest, dir) >= 0) { + if (d > dist) { + dist = d; + copy_v3_v3(closest, tmp_closest); + } + } + else { + if (d > dist2) { + dist2 = d; + copy_v3_v3(closest2, tmp_closest); + } + } + } + if (dist == 0.0f) { + copy_v3_v3(closest, &point->x); + } + if (dist2 == 0.0f) { + copy_v3_v3(closest2, &point->x); + } + dist = dist + dist2; + + if (dist < FLT_EPSILON) { + continue; + } + + float use_dist = dist; + + /* Apply radius limiting to not cross existing lines. */ + float dir[3], new_center[3]; + interp_v3_v3v3(new_center, closest2, closest, 0.5f); + sub_v3_v3v3(dir, new_center, &point->x); + if (normalize_v3(dir) != 0.0f && (is_cyclic || (i > 0 && i < gps->totpoints - 1))) { + const float max_radius = calc_radius_limit(gps, old_points, dir, spread, i); + use_dist = min_ff(use_dist, 2 * max_radius); + } + + float fac = use_dist * weight; + /* The 50 is an internal constant for the default pixel size. The result can be messed up if + * #bGPdata.pixfactor is not default, but I think modifiers shouldn't access that. */ + point->pressure += fac * 50.0f * GP_DEFAULT_PIX_FACTOR; + interp_v3_v3v3(&point->x, &point->x, new_center, fac / len_v3v3(closest, closest2)); + } + + MEM_freeN(old_points); +} + +/** + * Apply envelope effect to the stroke. + */ +static void deformStroke(GpencilModifierData *md, + Depsgraph *UNUSED(depsgraph), + Object *ob, + bGPDlayer *gpl, + bGPDframe *UNUSED(gpf), + bGPDstroke *gps) +{ + EnvelopeGpencilModifierData *mmd = (EnvelopeGpencilModifierData *)md; + if (mmd->mode != GP_ENVELOPE_DEFORM) { + return; + } + const int def_nr = BKE_object_defgroup_name_index(ob, mmd->vgname); + + if (!is_stroke_affected_by_modifier(ob, + mmd->layername, + mmd->material, + mmd->pass_index, + mmd->layer_pass, + 3, + gpl, + gps, + mmd->flag & GP_ENVELOPE_INVERT_LAYER, + mmd->flag & GP_ENVELOPE_INVERT_PASS, + mmd->flag & GP_ENVELOPE_INVERT_LAYERPASS, + mmd->flag & GP_ENVELOPE_INVERT_MATERIAL)) { + return; + } + + if (mmd->spread <= 0) { + return; + } + + apply_stroke_envelope( + gps, mmd->spread, def_nr, (mmd->flag & GP_ENVELOPE_INVERT_VGROUP) != 0, mmd->thickness); +} + +static void add_stroke(Object *ob, + bGPDstroke *gps, + const int point_index, + const int connection_index, + const int size, + const int mat_nr, + const float thickness, + const float strength, + ListBase *results) +{ + bGPdata *gpd = ob->data; + bGPDstroke *gps_dst = BKE_gpencil_stroke_new(mat_nr, size, gps->thickness); + + const int size1 = size == 4 ? 2 : 1; + const int size2 = size - size1; + + memcpy(&gps_dst->points[0], &gps->points[connection_index], size1 * sizeof(bGPDspoint)); + memcpy(&gps_dst->points[size1], &gps->points[point_index], size2 * sizeof(bGPDspoint)); + + for (int i = 0; i < size; i++) { + gps_dst->points[i].pressure *= thickness; + gps_dst->points[i].strength *= strength; + memset(&gps_dst->points[i].runtime, 0, sizeof(bGPDspoint_Runtime)); + } + + if (gps->dvert != NULL) { + gps_dst->dvert = MEM_malloc_arrayN(size, sizeof(MDeformVert), __func__); + BKE_defvert_array_copy(&gps_dst->dvert[0], &gps->dvert[connection_index], size1); + BKE_defvert_array_copy(&gps_dst->dvert[size1], &gps->dvert[point_index], size2); + } + + BLI_addtail(results, gps_dst); + + /* Calc geometry data. */ + BKE_gpencil_stroke_geometry_update(gpd, gps_dst); +} + +static void add_stroke_cyclic(Object *ob, + bGPDstroke *gps, + const int point_index, + const int connection_index, + const int mat_nr, + const float thickness, + const float strength, + ListBase *results) +{ + bGPdata *gpd = ob->data; + bGPDstroke *gps_dst = BKE_gpencil_stroke_new(mat_nr, 4, gps->thickness); + + int connection_index2 = (connection_index + 1) % gps->totpoints; + int point_index2 = (point_index + 1) % gps->totpoints; + + gps_dst->points[0] = gps->points[connection_index]; + gps_dst->points[1] = gps->points[connection_index2]; + gps_dst->points[2] = gps->points[point_index]; + gps_dst->points[3] = gps->points[point_index2]; + for (int i = 0; i < 4; i++) { + gps_dst->points[i].pressure *= thickness; + gps_dst->points[i].strength *= strength; + memset(&gps_dst->points[i].runtime, 0, sizeof(bGPDspoint_Runtime)); + } + + if (gps->dvert != NULL) { + gps_dst->dvert = MEM_malloc_arrayN(4, sizeof(MDeformVert), __func__); + BKE_defvert_array_copy(&gps_dst->dvert[0], &gps->dvert[connection_index], 1); + BKE_defvert_array_copy(&gps_dst->dvert[1], &gps->dvert[connection_index2], 1); + BKE_defvert_array_copy(&gps_dst->dvert[2], &gps->dvert[point_index], 1); + BKE_defvert_array_copy(&gps_dst->dvert[3], &gps->dvert[point_index2], 1); + } + + BLI_addtail(results, gps_dst); + + /* Calc geometry data. */ + BKE_gpencil_stroke_geometry_update(gpd, gps_dst); +} + +static void add_stroke_simple(Object *ob, + bGPDstroke *gps, + const int point_index, + const int connection_index, + const int mat_nr, + const float thickness, + const float strength, + ListBase *results) +{ + bGPdata *gpd = ob->data; + bGPDstroke *gps_dst = BKE_gpencil_stroke_new(mat_nr, 2, gps->thickness); + + gps_dst->points[0] = gps->points[connection_index]; + gps_dst->points[0].pressure *= thickness; + gps_dst->points[0].strength *= strength; + memset(&gps_dst->points[0].runtime, 0, sizeof(bGPDspoint_Runtime)); + gps_dst->points[1] = gps->points[point_index]; + gps_dst->points[1].pressure *= thickness; + gps_dst->points[1].strength *= strength; + memset(&gps_dst->points[1].runtime, 0, sizeof(bGPDspoint_Runtime)); + + if (gps->dvert != NULL) { + gps_dst->dvert = MEM_malloc_arrayN(2, sizeof(MDeformVert), __func__); + BKE_defvert_array_copy(&gps_dst->dvert[0], &gps->dvert[connection_index], 1); + BKE_defvert_array_copy(&gps_dst->dvert[1], &gps->dvert[point_index], 1); + } + + BLI_addtail(results, gps_dst); + + /* Calc geometry data. */ + BKE_gpencil_stroke_geometry_update(gpd, gps_dst); +} + +static void generate_geometry(GpencilModifierData *md, Object *ob, bGPDlayer *gpl, bGPDframe *gpf) +{ + EnvelopeGpencilModifierData *mmd = (EnvelopeGpencilModifierData *)md; + ListBase duplicates = {0}; + LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) { + if (!is_stroke_affected_by_modifier(ob, + mmd->layername, + mmd->material, + mmd->pass_index, + mmd->layer_pass, + 3, + gpl, + gps, + mmd->flag & GP_ENVELOPE_INVERT_LAYER, + mmd->flag & GP_ENVELOPE_INVERT_PASS, + mmd->flag & GP_ENVELOPE_INVERT_LAYERPASS, + mmd->flag & GP_ENVELOPE_INVERT_MATERIAL)) { + continue; + } + + const int mat_nr = mmd->mat_nr < 0 ? gps->mat_nr : min_ii(mmd->mat_nr, ob->totcol - 1); + if (mmd->mode == GP_ENVELOPE_FILLS) { + if (gps->flag & GP_STROKE_CYCLIC) { + for (int i = 0; i < gps->totpoints; i++) { + const int connection_index = (i + mmd->spread) % gps->totpoints; + add_stroke_cyclic( + ob, gps, i, connection_index, mat_nr, mmd->thickness, mmd->strength, &duplicates); + } + } + else { + for (int i = 1; i < gps->totpoints - 1 && i < mmd->spread + 1; i++) { + add_stroke(ob, gps, i, 0, 3, mat_nr, mmd->thickness, mmd->strength, &duplicates); + } + for (int i = 0; i < gps->totpoints - 1; i++) { + const int connection_index = min_ii(i + mmd->spread, gps->totpoints - 1); + const int size = i == gps->totpoints - 2 ? 2 : + connection_index < gps->totpoints - 1 ? 4 : + 3; + add_stroke(ob, + gps, + i, + connection_index, + size, + mat_nr, + mmd->thickness, + mmd->strength, + &duplicates); + } + } + BLI_remlink(&gpf->strokes, gps); + BKE_gpencil_free_stroke(gps); + } + else { + BLI_assert(mmd->mode == GP_ENVELOPE_SEGMENTS); + if (gps->flag & GP_STROKE_CYCLIC) { + for (int i = 0; i < gps->totpoints; i++) { + const int connection_index = (i + 1 + mmd->spread) % gps->totpoints; + add_stroke_simple( + ob, gps, i, connection_index, mat_nr, mmd->thickness, mmd->strength, &duplicates); + } + } + else { + for (int i = -mmd->spread; i < gps->totpoints - 1; i++) { + const int connection_index = min_ii(i + 1 + mmd->spread, gps->totpoints - 1); + add_stroke_simple(ob, + gps, + max_ii(0, i), + connection_index, + mat_nr, + mmd->thickness, + mmd->strength, + &duplicates); + } + } + } + } + if (!BLI_listbase_is_empty(&duplicates)) { + /* Add strokes to the start of the stroke list to ensure the new lines are drawn underneath the + * original line. */ + BLI_movelisttolist_reverse(&gpf->strokes, &duplicates); + } +} + +/** + * Apply envelope effect to the strokes. + */ +static void generateStrokes(GpencilModifierData *md, Depsgraph *depsgraph, Object *ob) +{ + EnvelopeGpencilModifierData *mmd = (EnvelopeGpencilModifierData *)md; + if (mmd->mode == GP_ENVELOPE_DEFORM || mmd->spread <= 0) { + return; + } + Scene *scene = DEG_get_evaluated_scene(depsgraph); + bGPdata *gpd = (bGPdata *)ob->data; + + LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { + bGPDframe *gpf = BKE_gpencil_frame_retime_get(depsgraph, scene, ob, gpl); + if (gpf == NULL) { + continue; + } + generate_geometry(md, ob, gpl, gpf); + } +} + +static void bakeModifier(struct Main *UNUSED(bmain), + Depsgraph *depsgraph, + GpencilModifierData *md, + Object *ob) +{ + EnvelopeGpencilModifierData *mmd = (EnvelopeGpencilModifierData *)md; + if (mmd->mode == GP_ENVELOPE_DEFORM) { + generic_bake_deform_stroke(depsgraph, md, ob, false, deformStroke); + } + else { + bGPdata *gpd = ob->data; + + LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { + LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) { + generate_geometry(md, ob, gpl, gpf); + } + } + } +} + +static void foreachIDLink(GpencilModifierData *md, Object *ob, IDWalkFunc walk, void *userData) +{ + EnvelopeGpencilModifierData *mmd = (EnvelopeGpencilModifierData *)md; + + walk(userData, ob, (ID **)&mmd->material, IDWALK_CB_USER); +} + +static void panel_draw(const bContext *UNUSED(C), Panel *panel) +{ + uiLayout *layout = panel->layout; + + PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL); + + uiLayoutSetPropSep(layout, true); + + uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE); + + uiItemR(layout, ptr, "spread", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "thickness", 0, NULL, ICON_NONE); + + const int mode = RNA_enum_get(ptr, "mode"); + if (mode != GP_ENVELOPE_DEFORM) { + uiItemR(layout, ptr, "strength", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "mat_nr", 0, NULL, ICON_NONE); + } + + gpencil_modifier_panel_end(layout, ptr); +} + +static void mask_panel_draw(const bContext *UNUSED(C), Panel *panel) +{ + gpencil_modifier_masking_panel_draw(panel, true, true); +} + +static void panelRegister(ARegionType *region_type) +{ + PanelType *panel_type = gpencil_modifier_panel_register( + region_type, eGpencilModifierType_Envelope, panel_draw); + gpencil_modifier_subpanel_register( + region_type, "mask", "Influence", NULL, mask_panel_draw, panel_type); +} + +GpencilModifierTypeInfo modifierType_Gpencil_Envelope = { + /* name */ "Envelope", + /* structName */ "EnvelopeGpencilModifierData", + /* structSize */ sizeof(EnvelopeGpencilModifierData), + /* type */ eGpencilModifierTypeType_Gpencil, + /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + + /* copyData */ copyData, + + /* deformStroke */ deformStroke, + /* generateStrokes */ generateStrokes, + /* bakeModifier */ bakeModifier, + /* remapTime */ NULL, + + /* initData */ initData, + /* freeData */ NULL, + /* isDisabled */ NULL, + /* updateDepsgraph */ NULL, + /* dependsOnTime */ NULL, + /* foreachIDLink */ foreachIDLink, + /* foreachTexLink */ NULL, + /* panelRegister */ panelRegister, +}; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c index 8eaed56dc58..d80224e6639 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c @@ -105,15 +105,15 @@ static void deformStroke(GpencilModifierData *md, /* Apply deformed coordinates. */ pt = gps->points; + bGPDstroke gps_old = *gps; + gps_old.points = (bGPDspoint *)MEM_dupallocN(gps->points); for (i = 0; i < gps->totpoints; i++, pt++) { copy_v3_v3(&pt->x, vert_coords[i]); /* Smooth stroke. */ - if (mmd->smooth_factor > 0.0f) { - for (int r = 0; r < mmd->smooth_step; r++) { - BKE_gpencil_stroke_smooth_point(gps, i, mmd->smooth_factor, true); - } - } + BKE_gpencil_stroke_smooth_point( + &gps_old, i, mmd->smooth_factor, mmd->smooth_step, true, false, gps); } + MEM_freeN(gps_old.points); MEM_freeN(vert_coords); diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c index f8201eb6b4f..1992ebd1508 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c @@ -34,10 +34,14 @@ #include "UI_interface.h" #include "UI_resources.h" +#include "RNA_access.h" + #include "MOD_gpencil_modifiertypes.h" #include "MOD_gpencil_ui_common.h" #include "MOD_gpencil_util.h" +#include "MEM_guardedalloc.h" + static void initData(GpencilModifierData *md) { SmoothGpencilModifierData *gpmd = (SmoothGpencilModifierData *)md; @@ -94,45 +98,40 @@ static void deformStroke(GpencilModifierData *md, return; } - /* smooth stroke */ - if (mmd->factor > 0.0f) { - for (int r = 0; r < mmd->step; r++) { - for (int i = 0; i < gps->totpoints; i++) { - MDeformVert *dvert = gps->dvert != NULL ? &gps->dvert[i] : NULL; - - /* verify vertex group */ - float weight = get_modifier_point_weight( - dvert, (mmd->flag & GP_SMOOTH_INVERT_VGROUP) != 0, def_nr); - if (weight < 0.0f) { - continue; - } - - /* Custom curve to modulate value. */ - if (use_curve) { - float value = (float)i / (gps->totpoints - 1); - weight *= BKE_curvemapping_evaluateF(mmd->curve_intensity, 0, value); - } - - const float val = mmd->factor * weight; - /* perform smoothing */ - if (mmd->flag & GP_SMOOTH_MOD_LOCATION) { - BKE_gpencil_stroke_smooth_point(gps, i, val, false); - } - if (mmd->flag & GP_SMOOTH_MOD_STRENGTH) { - BKE_gpencil_stroke_smooth_strength(gps, i, val); - } - if ((mmd->flag & GP_SMOOTH_MOD_THICKNESS) && (val > 0.0f)) { - /* thickness need to repeat process several times */ - for (int r2 = 0; r2 < r * 10; r2++) { - BKE_gpencil_stroke_smooth_thickness(gps, i, val); - } - } - if (mmd->flag & GP_SMOOTH_MOD_UV) { - BKE_gpencil_stroke_smooth_uv(gps, i, val); - } + if (mmd->factor <= 0.0f || mmd->step <= 0) { + return; + } + + float *weights = NULL; + if (def_nr != -1 || use_curve) { + weights = MEM_malloc_arrayN(gps->totpoints, sizeof(*weights), __func__); + /* Calculate weights. */ + for (int i = 0; i < gps->totpoints; i++) { + MDeformVert *dvert = gps->dvert != NULL ? &gps->dvert[i] : NULL; + + /* Verify vertex group. */ + float weight = get_modifier_point_weight( + dvert, (mmd->flag & GP_SMOOTH_INVERT_VGROUP) != 0, def_nr); + + /* Custom curve to modulate value. */ + if (use_curve && weight > 0.0f) { + float value = (float)i / (gps->totpoints - 1); + weight *= BKE_curvemapping_evaluateF(mmd->curve_intensity, 0, value); } + + weights[i] = weight; } } + BKE_gpencil_stroke_smooth(gps, + mmd->factor, + mmd->step, + mmd->flag & GP_SMOOTH_MOD_LOCATION, + mmd->flag & GP_SMOOTH_MOD_STRENGTH, + mmd->flag & GP_SMOOTH_MOD_THICKNESS, + mmd->flag & GP_SMOOTH_MOD_UV, + mmd->flag & GP_SMOOTH_KEEP_SHAPE, + weights); + MEM_SAFE_FREE(weights); } static void bakeModifier(struct Main *UNUSED(bmain), @@ -161,7 +160,7 @@ static void foreachIDLink(GpencilModifierData *md, Object *ob, IDWalkFunc walk, static void panel_draw(const bContext *UNUSED(C), Panel *panel) { - uiLayout *row; + uiLayout *row, *col; uiLayout *layout = panel->layout; PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL); @@ -177,6 +176,10 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) uiItemR(layout, ptr, "factor", 0, NULL, ICON_NONE); uiItemR(layout, ptr, "step", 0, IFACE_("Repeat"), ICON_NONE); + col = uiLayoutColumn(layout, false); + uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_edit_position")); + uiItemR(col, ptr, "use_keep_shape", 0, NULL, ICON_NONE); + gpencil_modifier_panel_end(layout, ptr); } diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 190454c8dfe..7b20a18890a 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -12,8 +12,8 @@ endif() set(INC . intern - opengl metal + opengl ../blenkernel ../blenlib ../bmesh @@ -104,12 +104,12 @@ set(SRC GPU_shader.h GPU_shader_shared.h GPU_state.h + GPU_storage_buffer.h GPU_texture.h GPU_uniform_buffer.h GPU_vertex_buffer.h GPU_vertex_format.h GPU_viewport.h - GPU_storage_buffer.h intern/gpu_backend.hh intern/gpu_batch_private.hh @@ -426,9 +426,9 @@ set(SRC_SHADER_CREATE_INFOS ../draw/engines/workbench/shaders/infos/workbench_volume_info.hh ../draw/engines/image/shaders/infos/engine_image_info.hh ../draw/intern/shaders/draw_fullscreen_info.hh + ../draw/intern/shaders/draw_hair_refine_info.hh ../draw/intern/shaders/draw_object_infos_info.hh ../draw/intern/shaders/draw_view_info.hh - ../draw/intern/shaders/draw_hair_refine_info.hh shaders/infos/gpu_clip_planes_info.hh shaders/infos/gpu_shader_2D_area_borders_info.hh @@ -503,16 +503,33 @@ endif() if(WITH_GPU_SHADER_BUILDER) - add_executable(shader_builder - intern/gpu_shader_builder.cc - intern/gpu_shader_builder_stubs.cc - ${shader_create_info_list_file} - ) + # TODO(@fclem) Fix this mess. + if(APPLE) + add_executable(shader_builder + intern/gpu_shader_builder.cc + ${shader_create_info_list_file} + ) + else() + add_executable(shader_builder + intern/gpu_shader_builder.cc + intern/gpu_shader_builder_stubs.cc + ${shader_create_info_list_file} + ) + endif() + + setup_platform_linker_flags(shader_builder) + + if(APPLE) + target_link_libraries(shader_builder PUBLIC + bf_blenkernel + buildinfoobj + ) + else() + target_link_libraries(shader_builder PUBLIC + bf_blenkernel + ) + endif() - target_link_libraries(shader_builder PUBLIC - bf_blenkernel - ${PLATFORM_LINKLIBS} - ) target_include_directories(shader_builder PRIVATE ${INC} ${CMAKE_CURRENT_BINARY_DIR}) set(SRC_BAKED_CREATE_INFOS_FILE ${CMAKE_CURRENT_BINARY_DIR}/shader_baked.hh) diff --git a/source/blender/gpu/intern/gpu_shader_create_info.cc b/source/blender/gpu/intern/gpu_shader_create_info.cc index aef1984687d..0d26f17ede5 100644 --- a/source/blender/gpu/intern/gpu_shader_create_info.cc +++ b/source/blender/gpu/intern/gpu_shader_create_info.cc @@ -264,9 +264,14 @@ bool gpu_shader_create_info_compile_all() { using namespace blender::gpu; int success = 0; + int skipped = 0; int total = 0; for (ShaderCreateInfo *info : g_create_infos->values()) { if (info->do_static_compilation_) { + if (GPU_compute_shader_support() == false && info->compute_source_ != nullptr) { + skipped++; + continue; + } total++; GPUShader *shader = GPU_shader_create_from_info( reinterpret_cast<const GPUShaderCreateInfo *>(info)); @@ -322,12 +327,11 @@ bool gpu_shader_create_info_compile_all() GPU_shader_free(shader); } } - printf("===============================\n"); - printf("Shader Test compilation result: \n"); - printf("%d Total\n", total); - printf("%d Passed\n", success); - printf("%d Failed\n", total - success); - printf("===============================\n"); + printf("Shader Test compilation result: %d / %d passed", success, total); + if (skipped > 0) { + printf(" (skipped %d for compatibility reasons)", skipped); + } + printf("\n"); return success == total; } diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc index 5a55a2e8020..71428633d79 100644 --- a/source/blender/gpu/opengl/gl_shader.cc +++ b/source/blender/gpu/opengl/gl_shader.cc @@ -868,7 +868,7 @@ GLuint GLShader::create_shader_stage(GLenum gl_stage, MutableSpan<const char *> { GLuint shader = glCreateShader(gl_stage); if (shader == 0) { - fprintf(stderr, "GLShader: Error: Could not create shader object."); + fprintf(stderr, "GLShader: Error: Could not create shader object.\n"); return 0; } diff --git a/source/blender/gpu/opengl/gl_shader_log.cc b/source/blender/gpu/opengl/gl_shader_log.cc index 1d922916e4c..64567174d17 100644 --- a/source/blender/gpu/opengl/gl_shader_log.cc +++ b/source/blender/gpu/opengl/gl_shader_log.cc @@ -39,7 +39,8 @@ char *GLLogParser::parse_line(char *log_line, GPULogItem &log_item) if ((log_item.cursor.row != -1) && (log_item.cursor.column != -1)) { if (GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_OFFICIAL) || - GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_MAC, GPU_DRIVER_OFFICIAL)) { + GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_MAC, GPU_DRIVER_OFFICIAL) || + GPU_type_matches(GPU_DEVICE_APPLE, GPU_OS_MAC, GPU_DRIVER_OFFICIAL)) { /* 0:line */ log_item.cursor.row = log_item.cursor.column; log_item.cursor.column = -1; diff --git a/source/blender/imbuf/CMakeLists.txt b/source/blender/imbuf/CMakeLists.txt index 25961e6e1d5..e46326467cc 100644 --- a/source/blender/imbuf/CMakeLists.txt +++ b/source/blender/imbuf/CMakeLists.txt @@ -174,6 +174,19 @@ if(WITH_IMAGE_HDR) add_definitions(-DWITH_HDR) endif() +if(WITH_IMAGE_WEBP) + list(APPEND SRC + intern/webp.c + ) + list(APPEND INC_SYS + ${WEBP_INCLUDE_DIRS} + ) + list(APPEND LIB + ${WEBP_LIBRARIES} + ) + add_definitions(-DWITH_WEBP) +endif() + list(APPEND INC ../../../intern/opencolorio ) diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h index 98b7cc6e87f..934163846e4 100644 --- a/source/blender/imbuf/IMB_imbuf_types.h +++ b/source/blender/imbuf/IMB_imbuf_types.h @@ -80,6 +80,9 @@ enum eImbFileType { #ifdef WITH_DDS IMB_FTYPE_DDS = 13, #endif +#ifdef WITH_WEBP + IMB_FTYPE_WEBP = 14, +#endif }; /* Only for readability. */ diff --git a/source/blender/imbuf/IMB_openexr.h b/source/blender/imbuf/IMB_openexr.h index a41053b99bf..32f393fc017 100644 --- a/source/blender/imbuf/IMB_openexr.h +++ b/source/blender/imbuf/IMB_openexr.h @@ -44,12 +44,12 @@ void IMB_exr_add_channel(void *handle, * Read from file. */ bool IMB_exr_begin_read( - void *handle, const char *filename, int *width, int *height, bool parse_channels); + void *handle, const char *filepath, int *width, int *height, bool parse_channels); /** * Used for output files (from #RenderResult) (single and multi-layer, single and multi-view). */ bool IMB_exr_begin_write(void *handle, - const char *filename, + const char *filepath, int width, int height, int compress, @@ -59,7 +59,7 @@ bool IMB_exr_begin_write(void *handle, * (FSA and Save Buffers). */ void IMB_exrtile_begin_write( - void *handle, const char *filename, int mipmap, int width, int height, int tilex, int tiley); + void *handle, const char *filepath, int mipmap, int width, int height, int tilex, int tiley); /** * Still clumsy name handling, layers/channels can be ordered as list in list later. diff --git a/source/blender/imbuf/intern/IMB_filetype.h b/source/blender/imbuf/intern/IMB_filetype.h index 035c5b10c60..31f8b3a9505 100644 --- a/source/blender/imbuf/intern/IMB_filetype.h +++ b/source/blender/imbuf/intern/IMB_filetype.h @@ -238,3 +238,16 @@ void imb_loadtiletiff( bool imb_savetiff(struct ImBuf *ibuf, const char *filepath, int flags); /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Format: TIFF (#IMB_FTYPE_WEBP) + * \{ */ + +bool imb_is_a_webp(const unsigned char *buf, size_t size); +struct ImBuf *imb_loadwebp(const unsigned char *mem, + size_t size, + int flags, + char colorspace[IM_MAX_SPACE]); +bool imb_savewebp(struct ImBuf *ibuf, const char *name, int flags); + +/** \} */ diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index 2e8c5cc4a40..193fda01816 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -2449,12 +2449,12 @@ void IMB_colormanagement_imbuf_make_display_space( ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf, bool save_as_render, bool allocate_result, - const ImageFormatData *imf) + const ImageFormatData *image_format) { ImBuf *colormanaged_ibuf = ibuf; - const bool is_movie = BKE_imtype_is_movie(imf->imtype); - const bool requires_linear_float = BKE_imtype_requires_linear_float(imf->imtype); - const bool do_alpha_under = imf->planes != R_IMF_PLANES_RGBA; + const bool is_movie = BKE_imtype_is_movie(image_format->imtype); + const bool requires_linear_float = BKE_imtype_requires_linear_float(image_format->imtype); + const bool do_alpha_under = image_format->planes != R_IMF_PLANES_RGBA; if (ibuf->rect_float && ibuf->rect && (ibuf->userflags & (IB_DISPLAY_BUFFER_INVALID | IB_RECT_INVALID)) != 0) { @@ -2464,9 +2464,9 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf, const bool do_colormanagement_display = save_as_render && (is_movie || !requires_linear_float); const bool do_colormanagement_linear = save_as_render && requires_linear_float && - imf->linear_colorspace_settings.name[0] && + image_format->linear_colorspace_settings.name[0] && !IMB_colormanagement_space_name_is_scene_linear( - imf->linear_colorspace_settings.name); + image_format->linear_colorspace_settings.name); if (do_colormanagement_display || do_colormanagement_linear || do_alpha_under) { if (allocate_result) { @@ -2529,7 +2529,8 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf, * should be pretty safe since this image buffer is supposed to be used for * saving only and ftype would be overwritten a bit later by BKE_imbuf_write */ - colormanaged_ibuf->ftype = BKE_imtype_to_ftype(imf->imtype, &colormanaged_ibuf->foptions); + colormanaged_ibuf->ftype = BKE_imtype_to_ftype(image_format->imtype, + &colormanaged_ibuf->foptions); /* if file format isn't able to handle float buffer itself, * we need to allocate byte buffer and store color managed @@ -2543,8 +2544,10 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf, } /* perform color space conversions */ - colormanagement_imbuf_make_display_space( - colormanaged_ibuf, &imf->view_settings, &imf->display_settings, make_byte); + colormanagement_imbuf_make_display_space(colormanaged_ibuf, + &image_format->view_settings, + &image_format->display_settings, + make_byte); if (colormanaged_ibuf->rect_float) { /* float buffer isn't linear anymore, @@ -2552,7 +2555,7 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf, * no space conversion should happen if ibuf->float_colorspace != NULL */ colormanaged_ibuf->float_colorspace = display_transform_get_colorspace( - &imf->view_settings, &imf->display_settings); + &image_format->view_settings, &image_format->display_settings); } } else if (do_colormanagement_linear) { @@ -2565,7 +2568,7 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf, if (colormanaged_ibuf->rect_float) { const char *from_colorspace = (ibuf->float_colorspace) ? ibuf->float_colorspace->name : global_role_scene_linear; - const char *to_colorspace = imf->linear_colorspace_settings.name; + const char *to_colorspace = image_format->linear_colorspace_settings.name; IMB_colormanagement_transform(colormanaged_ibuf->rect_float, colormanaged_ibuf->x, diff --git a/source/blender/imbuf/intern/filetype.c b/source/blender/imbuf/intern/filetype.c index 60442f97885..548bc9e120c 100644 --- a/source/blender/imbuf/intern/filetype.c +++ b/source/blender/imbuf/intern/filetype.c @@ -197,6 +197,20 @@ const ImFileType IMB_FILE_TYPES[] = { .default_save_role = COLOR_ROLE_DEFAULT_FLOAT, }, #endif +#ifdef WITH_WEBP + { + .init = NULL, + .exit = NULL, + .is_a = imb_is_a_webp, + .load = imb_loadwebp, + .load_filepath = NULL, + .save = imb_savewebp, + .load_tile = NULL, + .flag = 0, + .filetype = IMB_FTYPE_WEBP, + .default_save_role = COLOR_ROLE_DEFAULT_BYTE, + }, +#endif {NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0}, }; diff --git a/source/blender/imbuf/intern/openexr/CMakeLists.txt b/source/blender/imbuf/intern/openexr/CMakeLists.txt index 681176d8cc4..c34a97f6837 100644 --- a/source/blender/imbuf/intern/openexr/CMakeLists.txt +++ b/source/blender/imbuf/intern/openexr/CMakeLists.txt @@ -17,8 +17,8 @@ set(INC_SYS ) set(SRC - openexr_api.h openexr_api.cpp + openexr_api.h ) set(LIB diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index aff9257d1f2..9948aaac5da 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -155,15 +155,15 @@ class IMemStream : public Imf::IStream { class IFileStream : public Imf::IStream { public: - IFileStream(const char *filename) : IStream(filename) + IFileStream(const char *filepath) : IStream(filepath) { /* utf-8 file path support on windows */ #if defined(WIN32) - wchar_t *wfilename = alloc_utf16_from_8(filename, 0); - ifs.open(wfilename, std::ios_base::binary); - free(wfilename); + wchar_t *wfilepath = alloc_utf16_from_8(filepath, 0); + ifs.open(wfilepath, std::ios_base::binary); + free(wfilepath); #else - ifs.open(filename, std::ios_base::binary); + ifs.open(filepath, std::ios_base::binary); #endif if (!ifs) { @@ -261,15 +261,15 @@ class OMemStream : public OStream { class OFileStream : public OStream { public: - OFileStream(const char *filename) : OStream(filename) + OFileStream(const char *filepath) : OStream(filepath) { /* utf-8 file path support on windows */ #if defined(WIN32) - wchar_t *wfilename = alloc_utf16_from_8(filename, 0); - ofs.open(wfilename, std::ios_base::binary); - free(wfilename); + wchar_t *wfilepath = alloc_utf16_from_8(filepath, 0); + ofs.open(wfilepath, std::ios_base::binary); + free(wfilepath); #else - ofs.open(filename, std::ios_base::binary); + ofs.open(filepath, std::ios_base::binary); #endif if (!ofs) { @@ -834,7 +834,7 @@ void IMB_exr_add_channel(void *handle, } bool IMB_exr_begin_write(void *handle, - const char *filename, + const char *filepath, int width, int height, int compress, @@ -872,7 +872,7 @@ bool IMB_exr_begin_write(void *handle, /* avoid crash/abort when we don't have permission to write here */ /* manually create ofstream, so we can handle utf-8 filepaths on windows */ try { - data->ofile_stream = new OFileStream(filename); + data->ofile_stream = new OFileStream(filepath); data->ofile = new OutputFile(*(data->ofile_stream), header); } catch (const std::exception &exc) { @@ -889,7 +889,7 @@ bool IMB_exr_begin_write(void *handle, } void IMB_exrtile_begin_write( - void *handle, const char *filename, int mipmap, int width, int height, int tilex, int tiley) + void *handle, const char *filepath, int mipmap, int width, int height, int tilex, int tiley) { ExrHandle *data = (ExrHandle *)handle; Header header(width, height); @@ -941,7 +941,7 @@ void IMB_exrtile_begin_write( /* avoid crash/abort when we don't have permission to write here */ /* manually create ofstream, so we can handle utf-8 filepaths on windows */ try { - data->ofile_stream = new OFileStream(filename); + data->ofile_stream = new OFileStream(filepath); data->mpofile = new MultiPartOutputFile(*(data->ofile_stream), &headers[0], headers.size()); } catch (const std::exception &) { @@ -954,19 +954,19 @@ void IMB_exrtile_begin_write( } bool IMB_exr_begin_read( - void *handle, const char *filename, int *width, int *height, const bool parse_channels) + void *handle, const char *filepath, int *width, int *height, const bool parse_channels) { ExrHandle *data = (ExrHandle *)handle; ExrChannel *echan; /* 32 is arbitrary, but zero length files crashes exr. */ - if (!(BLI_exists(filename) && BLI_file_size(filename) > 32)) { + if (!(BLI_exists(filepath) && BLI_file_size(filepath) > 32)) { return false; } /* avoid crash/abort when we don't have permission to write here */ try { - data->ifile_stream = new IFileStream(filename); + data->ifile_stream = new IFileStream(filepath); data->ifile = new MultiPartInputFile(*(data->ifile_stream)); } catch (const std::exception &) { diff --git a/source/blender/imbuf/intern/openexr/openexr_stub.cpp b/source/blender/imbuf/intern/openexr/openexr_stub.cpp index 2a655360aa5..f8f204af70c 100644 --- a/source/blender/imbuf/intern/openexr/openexr_stub.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_stub.cpp @@ -29,7 +29,7 @@ void IMB_exr_add_channel(void * /*handle*/, } bool IMB_exr_begin_read(void * /*handle*/, - const char * /*filename*/, + const char * /*filepath*/, int * /*width*/, int * /*height*/, const bool /*add_channels*/) @@ -37,7 +37,7 @@ bool IMB_exr_begin_read(void * /*handle*/, return false; } bool IMB_exr_begin_write(void * /*handle*/, - const char * /*filename*/, + const char * /*filepath*/, int /*width*/, int /*height*/, int /*compress*/, @@ -46,7 +46,7 @@ bool IMB_exr_begin_write(void * /*handle*/, return false; } void IMB_exrtile_begin_write(void * /*handle*/, - const char * /*filename*/, + const char * /*filepath*/, int /*mipmap*/, int /*width*/, int /*height*/, diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index 241f1a736f4..45b50c866fe 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -41,12 +41,12 @@ #define UTIL_DEBUG 0 const char *imb_ext_image[] = { - ".png", ".tga", ".bmp", ".jpg", ".jpeg", ".sgi", ".rgb", ".rgba", + ".png", ".tga", ".bmp", ".jpg", ".jpeg", ".sgi", ".rgb", ".rgba", #ifdef WITH_TIFF - ".tif", ".tiff", ".tx", + ".tif", ".tiff", ".tx", #endif #ifdef WITH_OPENJPEG - ".jp2", ".j2c", + ".jp2", ".j2c", #endif #ifdef WITH_HDR ".hdr", @@ -55,13 +55,16 @@ const char *imb_ext_image[] = { ".dds", #endif #ifdef WITH_CINEON - ".dpx", ".cin", + ".dpx", ".cin", #endif #ifdef WITH_OPENEXR ".exr", #endif #ifdef WITH_OPENIMAGEIO - ".psd", ".pdd", ".psb", + ".psd", ".pdd", ".psb", +#endif +#ifdef WITH_WEBP + ".webp", #endif NULL, }; diff --git a/source/blender/imbuf/intern/webp.c b/source/blender/imbuf/intern/webp.c new file mode 100644 index 00000000000..19fe2373ea0 --- /dev/null +++ b/source/blender/imbuf/intern/webp.c @@ -0,0 +1,129 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup imbuf + */ + +#include <stdio.h> +#include <stdlib.h> +#include <webp/decode.h> +#include <webp/encode.h> + +#include "BLI_fileops.h" +#include "BLI_utildefines.h" + +#include "IMB_colormanagement.h" +#include "IMB_colormanagement_intern.h" +#include "IMB_filetype.h" +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" + +#include "MEM_guardedalloc.h" + +bool imb_is_a_webp(const unsigned char *buf, size_t size) +{ + if (WebPGetInfo(buf, size, NULL, NULL)) { + return true; + } + return false; +} + +ImBuf *imb_loadwebp(const unsigned char *mem, + size_t size, + int flags, + char colorspace[IM_MAX_SPACE]) +{ + if (!imb_is_a_webp(mem, size)) { + return NULL; + } + + colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE); + + WebPBitstreamFeatures features; + if (WebPGetFeatures(mem, size, &features) != VP8_STATUS_OK) { + fprintf(stderr, "WebP: Failed to parse features\n"); + return NULL; + } + + const int planes = features.has_alpha ? 32 : 24; + ImBuf *ibuf = IMB_allocImBuf(features.width, features.height, planes, 0); + + if (ibuf == NULL) { + fprintf(stderr, "WebP: Failed to allocate image memory\n"); + return NULL; + } + + if ((flags & IB_test) == 0) { + ibuf->ftype = IMB_FTYPE_WEBP; + imb_addrectImBuf(ibuf); + /* Flip the image during decoding to match Blender. */ + unsigned char *last_row = (unsigned char *)(ibuf->rect + (ibuf->y - 1) * ibuf->x); + if (WebPDecodeRGBAInto(mem, size, last_row, (size_t)(ibuf->x) * ibuf->y * 4, -4 * ibuf->x) == + NULL) { + fprintf(stderr, "WebP: Failed to decode image\n"); + } + } + + return ibuf; +} + +bool imb_savewebp(struct ImBuf *ibuf, const char *name, int UNUSED(flags)) +{ + const int bytesperpixel = (ibuf->planes + 7) >> 3; + unsigned char *encoded_data, *last_row; + size_t encoded_data_size; + + if (bytesperpixel == 3) { + /* We must convert the ImBuf RGBA buffer to RGB as WebP expects a RGB buffer. */ + const size_t num_pixels = ibuf->x * ibuf->y; + const uint8_t *rgba_rect = (uint8_t *)ibuf->rect; + uint8_t *rgb_rect = MEM_mallocN(sizeof(uint8_t) * num_pixels * 3, "webp rgb_rect"); + for (int i = 0; i < num_pixels; i++) { + rgb_rect[i * 3 + 0] = rgba_rect[i * 4 + 0]; + rgb_rect[i * 3 + 1] = rgba_rect[i * 4 + 1]; + rgb_rect[i * 3 + 2] = rgba_rect[i * 4 + 2]; + } + + last_row = (unsigned char *)(rgb_rect + (ibuf->y - 1) * ibuf->x * 3); + + if (ibuf->foptions.quality == 100.0f) { + encoded_data_size = WebPEncodeLosslessRGB( + last_row, ibuf->x, ibuf->y, -3 * ibuf->x, &encoded_data); + } + else { + encoded_data_size = WebPEncodeRGB( + last_row, ibuf->x, ibuf->y, -3 * ibuf->x, ibuf->foptions.quality, &encoded_data); + } + MEM_freeN(rgb_rect); + } + else if (bytesperpixel == 4) { + last_row = (unsigned char *)(ibuf->rect + (ibuf->y - 1) * ibuf->x); + + if (ibuf->foptions.quality == 100.0f) { + encoded_data_size = WebPEncodeLosslessRGBA( + last_row, ibuf->x, ibuf->y, -4 * ibuf->x, &encoded_data); + } + else { + encoded_data_size = WebPEncodeRGBA( + last_row, ibuf->x, ibuf->y, -4 * ibuf->x, ibuf->foptions.quality, &encoded_data); + } + } + else { + fprintf(stderr, "WebP: Unsupported bytes per pixel: %d for file: '%s'\n", bytesperpixel, name); + return false; + } + + if (encoded_data != NULL) { + FILE *fp = BLI_fopen(name, "wb"); + if (!fp) { + free(encoded_data); + fprintf(stderr, "WebP: Cannot open file for writing: '%s'\n", name); + return false; + } + fwrite(encoded_data, encoded_data_size, 1, fp); + free(encoded_data); + fclose(fp); + } + + return true; +} diff --git a/source/blender/io/gpencil/gpencil_io.h b/source/blender/io/gpencil/gpencil_io.h index 6cd9fe087a6..215891e3e48 100644 --- a/source/blender/io/gpencil/gpencil_io.h +++ b/source/blender/io/gpencil/gpencil_io.h @@ -72,11 +72,11 @@ typedef enum eGpencilExportFrame { /** * Main export entry point function. */ -bool gpencil_io_export(const char *filename, struct GpencilIOParams *iparams); +bool gpencil_io_export(const char *filepath, struct GpencilIOParams *iparams); /** * Main import entry point function. */ -bool gpencil_io_import(const char *filename, struct GpencilIOParams *iparams); +bool gpencil_io_import(const char *filepath, struct GpencilIOParams *iparams); #ifdef __cplusplus } diff --git a/source/blender/io/gpencil/intern/gpencil_io_base.cc b/source/blender/io/gpencil/intern/gpencil_io_base.cc index 9379e72bdd9..05f1158c57d 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_base.cc +++ b/source/blender/io/gpencil/intern/gpencil_io_base.cc @@ -174,10 +174,10 @@ void GpencilIO::create_object_list() }); } -void GpencilIO::filename_set(const char *filename) +void GpencilIO::filepath_set(const char *filepath) { - BLI_strncpy(filename_, filename, FILE_MAX); - BLI_path_abs(filename_, BKE_main_blendfile_path(bmain_)); + BLI_strncpy(filepath_, filepath, FILE_MAX); + BLI_path_abs(filepath_, BKE_main_blendfile_path(bmain_)); } bool GpencilIO::gpencil_3D_point_to_screen_space(const float3 co, float2 &r_co) diff --git a/source/blender/io/gpencil/intern/gpencil_io_base.hh b/source/blender/io/gpencil/intern/gpencil_io_base.hh index 96ba49c31b1..a89b723ed6c 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_base.hh +++ b/source/blender/io/gpencil/intern/gpencil_io_base.hh @@ -40,7 +40,7 @@ class GpencilIO { bool invert_axis_[2]; float4x4 diff_mat_; - char filename_[FILE_MAX]; + char filepath_[FILE_MAX]; /* Used for sorting objects. */ struct ObjectZ { @@ -94,9 +94,9 @@ class GpencilIO { void selected_objects_boundbox_get(rctf *boundbox); /** * Set file input_text full path. - * \param filename: Path of the file provided by save dialog. + * \param filepath: Path of the file provided by save dialog. */ - void filename_set(const char *filename); + void filepath_set(const char *filepath); private: float avg_opacity_; diff --git a/source/blender/io/gpencil/intern/gpencil_io_capi.cc b/source/blender/io/gpencil/intern/gpencil_io_capi.cc index 5acac885a38..84b273bc570 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_capi.cc +++ b/source/blender/io/gpencil/intern/gpencil_io_capi.cc @@ -161,32 +161,32 @@ static bool gpencil_io_export_frame_svg(GpencilExporterSVG *exporter, } #endif -bool gpencil_io_import(const char *filename, GpencilIOParams *iparams) +bool gpencil_io_import(const char *filepath, GpencilIOParams *iparams) { - GpencilImporterSVG importer = GpencilImporterSVG(filename, iparams); + GpencilImporterSVG importer = GpencilImporterSVG(filepath, iparams); return gpencil_io_import_frame(&importer, *iparams); } -bool gpencil_io_export(const char *filename, GpencilIOParams *iparams) +bool gpencil_io_export(const char *filepath, GpencilIOParams *iparams) { Depsgraph *depsgraph_ = CTX_data_depsgraph_pointer(iparams->C); Scene *scene_ = CTX_data_scene(iparams->C); Object *ob = CTX_data_active_object(iparams->C); - UNUSED_VARS(filename, depsgraph_, scene_, ob); + UNUSED_VARS(filepath, depsgraph_, scene_, ob); switch (iparams->mode) { #ifdef WITH_PUGIXML case GP_EXPORT_TO_SVG: { - GpencilExporterSVG exporter = GpencilExporterSVG(filename, iparams); + GpencilExporterSVG exporter = GpencilExporterSVG(filepath, iparams); return gpencil_io_export_frame_svg(&exporter, scene_, iparams, true, true, true); break; } #endif #ifdef WITH_HARU case GP_EXPORT_TO_PDF: { - GpencilExporterPDF exporter = GpencilExporterPDF(filename, iparams); + GpencilExporterPDF exporter = GpencilExporterPDF(filepath, iparams); return gpencil_io_export_pdf(depsgraph_, scene_, ob, &exporter, iparams); break; } diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc index cc3eab02e07..205ab788e6d 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc +++ b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc @@ -43,10 +43,10 @@ static void error_handler(HPDF_STATUS error_no, HPDF_STATUS detail_no, void *UNU } /* Constructor. */ -GpencilExporterPDF::GpencilExporterPDF(const char *filename, const GpencilIOParams *iparams) +GpencilExporterPDF::GpencilExporterPDF(const char *filepath, const GpencilIOParams *iparams) : GpencilExporter(iparams) { - filename_set(filename); + filepath_set(filepath); invert_axis_[0] = false; invert_axis_[1] = false; @@ -78,16 +78,16 @@ bool GpencilExporterPDF::write() /* TODO: It looks `libharu` does not support unicode. */ #if 0 /* `ifdef WIN32` */ - char filename_cstr[FILE_MAX]; - BLI_strncpy(filename_cstr, filename_, FILE_MAX); + char filepath_cstr[FILE_MAX]; + BLI_strncpy(filepath_cstr, filepath_, FILE_MAX); - UTF16_ENCODE(filename_cstr); - std::wstring wstr(filename_cstr_16); + UTF16_ENCODE(filepath_cstr); + std::wstring wstr(filepath_cstr_16); res = HPDF_SaveToFile(pdf_, wstr.c_str()); - UTF16_UN_ENCODE(filename_cstr); + UTF16_UN_ENCODE(filepath_cstr); #else - res = HPDF_SaveToFile(pdf_, filename_); + res = HPDF_SaveToFile(pdf_, filepath_); #endif return (res == 0) ? true : false; diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.hh b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.hh index f6b9fe4fec1..bfec6bc506b 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.hh +++ b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.hh @@ -21,7 +21,7 @@ namespace blender::io::gpencil { class GpencilExporterPDF : public GpencilExporter { public: - GpencilExporterPDF(const char *filename, const struct GpencilIOParams *iparams); + GpencilExporterPDF(const char *filepath, const struct GpencilIOParams *iparams); bool new_document(); bool add_newpage(); bool add_body(); diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc b/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc index f8d30546e39..5d33a2806bd 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc +++ b/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc @@ -40,10 +40,10 @@ namespace blender ::io ::gpencil { /* Constructor. */ -GpencilExporterSVG::GpencilExporterSVG(const char *filename, const GpencilIOParams *iparams) +GpencilExporterSVG::GpencilExporterSVG(const char *filepath, const GpencilIOParams *iparams) : GpencilExporter(iparams) { - filename_set(filename); + filepath_set(filepath); invert_axis_[0] = false; invert_axis_[1] = true; @@ -66,16 +66,16 @@ bool GpencilExporterSVG::write() bool result = true; /* Support unicode character paths on Windows. */ #ifdef WIN32 - char filename_cstr[FILE_MAX]; - BLI_strncpy(filename_cstr, filename_, FILE_MAX); + char filepath_cstr[FILE_MAX]; + BLI_strncpy(filepath_cstr, filepath_, FILE_MAX); - UTF16_ENCODE(filename_cstr); - std::wstring wstr(filename_cstr_16); + UTF16_ENCODE(filepath_cstr); + std::wstring wstr(filepath_cstr_16); result = main_doc_.save_file(wstr.c_str()); - UTF16_UN_ENCODE(filename_cstr); + UTF16_UN_ENCODE(filepath_cstr); #else - result = main_doc_.save_file(filename_); + result = main_doc_.save_file(filepath_); #endif return result; diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_svg.hh b/source/blender/io/gpencil/intern/gpencil_io_export_svg.hh index 2e1cc231e68..7bbc2710693 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_export_svg.hh +++ b/source/blender/io/gpencil/intern/gpencil_io_export_svg.hh @@ -20,7 +20,7 @@ namespace blender::io::gpencil { class GpencilExporterSVG : public GpencilExporter { public: - GpencilExporterSVG(const char *filename, const struct GpencilIOParams *iparams); + GpencilExporterSVG(const char *filepath, const struct GpencilIOParams *iparams); bool add_newpage(); bool add_body(); bool write(); diff --git a/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc b/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc index bad5c7d6401..06460a1beba 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc +++ b/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc @@ -33,17 +33,17 @@ using blender::MutableSpan; namespace blender::io::gpencil { /* Constructor. */ -GpencilImporterSVG::GpencilImporterSVG(const char *filename, const GpencilIOParams *iparams) +GpencilImporterSVG::GpencilImporterSVG(const char *filepath, const GpencilIOParams *iparams) : GpencilImporter(iparams) { - filename_set(filename); + filepath_set(filepath); } bool GpencilImporterSVG::read() { bool result = true; NSVGimage *svg_data = nullptr; - svg_data = nsvgParseFromFile(filename_, "mm", 96.0f); + svg_data = nsvgParseFromFile(filepath_, "mm", 96.0f); if (svg_data == nullptr) { std::cout << " Could not open SVG.\n "; return false; diff --git a/source/blender/io/gpencil/intern/gpencil_io_import_svg.hh b/source/blender/io/gpencil/intern/gpencil_io_import_svg.hh index f1f4e9a6290..d868e672567 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_import_svg.hh +++ b/source/blender/io/gpencil/intern/gpencil_io_import_svg.hh @@ -21,7 +21,7 @@ namespace blender::io::gpencil { class GpencilImporterSVG : public GpencilImporter { public: - GpencilImporterSVG(const char *filename, const struct GpencilIOParams *iparams); + GpencilImporterSVG(const char *filepath, const struct GpencilIOParams *iparams); bool read(); diff --git a/source/blender/io/usd/CMakeLists.txt b/source/blender/io/usd/CMakeLists.txt index 01d0cfcd302..2b5ea39617e 100644 --- a/source/blender/io/usd/CMakeLists.txt +++ b/source/blender/io/usd/CMakeLists.txt @@ -107,10 +107,10 @@ list(APPEND LIB blender_add_lib(bf_usd "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") if(WIN32) - set_property(TARGET bf_usd APPEND_STRING PROPERTY LINK_FLAGS_DEBUG " /WHOLEARCHIVE:${USD_DEBUG_LIB}") - set_property(TARGET bf_usd APPEND_STRING PROPERTY LINK_FLAGS_RELEASE " /WHOLEARCHIVE:${USD_RELEASE_LIB}") - set_property(TARGET bf_usd APPEND_STRING PROPERTY LINK_FLAGS_RELWITHDEBINFO " /WHOLEARCHIVE:${USD_RELEASE_LIB}") - set_property(TARGET bf_usd APPEND_STRING PROPERTY LINK_FLAGS_MINSIZEREL " /WHOLEARCHIVE:${USD_RELEASE_LIB}") + set_property(TARGET bf_usd APPEND_STRING PROPERTY INTERFACE_LINK_OPTIONS "$<$<CONFIG:Debug>:/WHOLEARCHIVE:${USD_DEBUG_LIB}>") + set_property(TARGET bf_usd APPEND_STRING PROPERTY INTERFACE_LINK_OPTIONS "$<$<CONFIG:Release>:/WHOLEARCHIVE:${USD_RELEASE_LIB}>") + set_property(TARGET bf_usd APPEND_STRING PROPERTY INTERFACE_LINK_OPTIONS "$<$<CONFIG:RelWithDebInfo>:/WHOLEARCHIVE:${USD_RELEASE_LIB}>") + set_property(TARGET bf_usd APPEND_STRING PROPERTY INTERFACE_LINK_OPTIONS "$<$<CONFIG:MinSizeRel>:/WHOLEARCHIVE:${USD_RELEASE_LIB}>") endif() # Source: https://github.com/PixarAnimationStudios/USD/blob/master/BUILDING.md#linking-whole-archives diff --git a/source/blender/io/usd/intern/usd_capi_import.cc b/source/blender/io/usd/intern/usd_capi_import.cc index 49d5251198a..e5083700d7d 100644 --- a/source/blender/io/usd/intern/usd_capi_import.cc +++ b/source/blender/io/usd/intern/usd_capi_import.cc @@ -391,7 +391,7 @@ bool USD_import(struct bContext *C, else { /* Fake a job context, so that we don't need NULL pointer checks while importing. */ short stop = 0, do_update = 0; - float progress = 0.f; + float progress = 0.0f; import_startjob(job, &stop, &do_update, &progress); import_endjob(job); diff --git a/source/blender/io/usd/intern/usd_reader_light.cc b/source/blender/io/usd/intern/usd_reader_light.cc index 649ff45a6d0..55b9557dfb5 100644 --- a/source/blender/io/usd/intern/usd_reader_light.cc +++ b/source/blender/io/usd/intern/usd_reader_light.cc @@ -9,8 +9,6 @@ #include "DNA_light_types.h" #include "DNA_object_types.h" -#include <pxr/usd/usdLux/light.h> - #include <pxr/usd/usdLux/diskLight.h> #include <pxr/usd/usdLux/distantLight.h> #include <pxr/usd/usdLux/rectLight.h> @@ -40,14 +38,17 @@ void USDLightReader::read_object_data(Main *bmain, const double motionSampleTime if (!prim_) { return; } +#if PXR_VERSION >= 2111 + pxr::UsdLuxLightAPI light_api(prim_); +#else + pxr::UsdLuxLight light_api(prim_); +#endif - pxr::UsdLuxLight light_prim(prim_); - - if (!light_prim) { + if (!light_api) { return; } - pxr::UsdLuxShapingAPI shaping_api(light_prim); + pxr::UsdLuxShapingAPI shaping_api; /* Set light type. */ @@ -63,6 +64,8 @@ void USDLightReader::read_object_data(Main *bmain, const double motionSampleTime else if (prim_.IsA<pxr::UsdLuxSphereLight>()) { blight->type = LA_LOCAL; + shaping_api = pxr::UsdLuxShapingAPI(prim_); + if (shaping_api && shaping_api.GetShapingConeAngleAttr().IsAuthored()) { blight->type = LA_SPOT; } @@ -73,7 +76,7 @@ void USDLightReader::read_object_data(Main *bmain, const double motionSampleTime /* Set light values. */ - if (pxr::UsdAttribute intensity_attr = light_prim.GetIntensityAttr()) { + if (pxr::UsdAttribute intensity_attr = light_api.GetIntensityAttr()) { float intensity = 0.0f; if (intensity_attr.Get(&intensity, motionSampleTime)) { blight->energy = intensity * this->import_params_.light_intensity_scale; @@ -92,14 +95,14 @@ void USDLightReader::read_object_data(Main *bmain, const double motionSampleTime light_prim.GetDiffuseAttr().Get(&diffuse, motionSampleTime); #endif - if (pxr::UsdAttribute spec_attr = light_prim.GetSpecularAttr()) { + if (pxr::UsdAttribute spec_attr = light_api.GetSpecularAttr()) { float spec = 0.0f; if (spec_attr.Get(&spec, motionSampleTime)) { blight->spec_fac = spec; } } - if (pxr::UsdAttribute color_attr = light_prim.GetColorAttr()) { + if (pxr::UsdAttribute color_attr = light_api.GetColorAttr()) { pxr::GfVec3f color; if (color_attr.Get(&color, motionSampleTime)) { blight->r = color[0]; diff --git a/source/blender/io/usd/intern/usd_reader_stage.cc b/source/blender/io/usd/intern/usd_reader_stage.cc index 06f7d3ce3f5..583c58a1356 100644 --- a/source/blender/io/usd/intern/usd_reader_stage.cc +++ b/source/blender/io/usd/intern/usd_reader_stage.cc @@ -18,7 +18,13 @@ #include <pxr/usd/usdGeom/nurbsCurves.h> #include <pxr/usd/usdGeom/scope.h> #include <pxr/usd/usdGeom/xform.h> -#include <pxr/usd/usdLux/light.h> + +#if PXR_VERSION >= 2111 +# include <pxr/usd/usdLux/boundableLightBase.h> +# include <pxr/usd/usdLux/nonboundableLightBase.h> +#else +# include <pxr/usd/usdLux/light.h> +#endif #include <iostream> @@ -55,7 +61,12 @@ USDPrimReader *USDStageReader::create_reader_if_allowed(const pxr::UsdPrim &prim if (params_.import_meshes && prim.IsA<pxr::UsdGeomMesh>()) { return new USDMeshReader(prim, params_, settings_); } +#if PXR_VERSION >= 2111 + if (params_.import_lights && (prim.IsA<pxr::UsdLuxBoundableLightBase>() || + prim.IsA<pxr::UsdLuxNonboundableLightBase>())) { +#else if (params_.import_lights && prim.IsA<pxr::UsdLuxLight>()) { +#endif return new USDLightReader(prim, params_, settings_); } if (params_.import_volumes && prim.IsA<pxr::UsdVolVolume>()) { @@ -82,7 +93,11 @@ USDPrimReader *USDStageReader::create_reader(const pxr::UsdPrim &prim) if (prim.IsA<pxr::UsdGeomMesh>()) { return new USDMeshReader(prim, params_, settings_); } +#if PXR_VERSION >= 2111 + if (prim.IsA<pxr::UsdLuxBoundableLightBase>() || prim.IsA<pxr::UsdLuxNonboundableLightBase>()) { +#else if (prim.IsA<pxr::UsdLuxLight>()) { +#endif return new USDLightReader(prim, params_, settings_); } if (prim.IsA<pxr::UsdVolVolume>()) { diff --git a/source/blender/io/usd/intern/usd_reader_volume.cc b/source/blender/io/usd/intern/usd_reader_volume.cc index aec30539ee6..13044de5002 100644 --- a/source/blender/io/usd/intern/usd_reader_volume.cc +++ b/source/blender/io/usd/intern/usd_reader_volume.cc @@ -54,18 +54,6 @@ void USDVolumeReader::read_object_data(Main *bmain, const double motionSampleTim pxr::UsdVolOpenVDBAsset fieldBase(fieldPrim); - pxr::UsdAttribute fieldNameAttr = fieldBase.GetFieldNameAttr(); - - if (fieldNameAttr.IsAuthored()) { - pxr::TfToken fieldName; - fieldNameAttr.Get(&fieldName, motionSampleTime); - - /* A Blender volume creates density by default. */ - if (fieldName != usdtokens::density) { - BKE_volume_grid_add(volume, fieldName.GetString().c_str(), VOLUME_GRID_FLOAT); - } - } - pxr::UsdAttribute filepathAttr = fieldBase.GetFilePathAttr(); if (filepathAttr.IsAuthored()) { diff --git a/source/blender/io/usd/intern/usd_reader_xform.cc b/source/blender/io/usd/intern/usd_reader_xform.cc index 4cb7d4e1845..bc6e2dd5297 100644 --- a/source/blender/io/usd/intern/usd_reader_xform.cc +++ b/source/blender/io/usd/intern/usd_reader_xform.cc @@ -131,7 +131,7 @@ bool USDXformReader::is_root_xform_prim() const return false; } - if (prim_.IsInMaster()) { + if (prim_.IsInPrototype()) { /* We don't consider prototypes to be root prims, * because we never want to apply global scaling * or rotations to the prototypes themselves. */ diff --git a/source/blender/io/usd/intern/usd_writer_light.cc b/source/blender/io/usd/intern/usd_writer_light.cc index 282393bbcd2..982bc31d767 100644 --- a/source/blender/io/usd/intern/usd_writer_light.cc +++ b/source/blender/io/usd/intern/usd_writer_light.cc @@ -33,7 +33,12 @@ void USDLightWriter::do_write(HierarchyContext &context) pxr::UsdTimeCode timecode = get_export_time_code(); Light *light = static_cast<Light *>(context.object->data); - pxr::UsdLuxLight usd_light; +#if PXR_VERSION >= 2111 + pxr::UsdLuxLightAPI usd_light_api; +#else + pxr::UsdLuxLight usd_light_api; + +#endif switch (light->type) { case LA_AREA: @@ -42,21 +47,33 @@ void USDLightWriter::do_write(HierarchyContext &context) case LA_AREA_ELLIPSE: { /* An ellipse light will deteriorate into a disk light. */ pxr::UsdLuxDiskLight disk_light = pxr::UsdLuxDiskLight::Define(stage, usd_path); disk_light.CreateRadiusAttr().Set(light->area_size, timecode); - usd_light = disk_light; +#if PXR_VERSION >= 2111 + usd_light_api = disk_light.LightAPI(); +#else + usd_light_api = disk_light; +#endif break; } case LA_AREA_RECT: { pxr::UsdLuxRectLight rect_light = pxr::UsdLuxRectLight::Define(stage, usd_path); rect_light.CreateWidthAttr().Set(light->area_size, timecode); rect_light.CreateHeightAttr().Set(light->area_sizey, timecode); - usd_light = rect_light; +#if PXR_VERSION >= 2111 + usd_light_api = rect_light.LightAPI(); +#else + usd_light_api = rect_light; +#endif break; } case LA_AREA_SQUARE: { pxr::UsdLuxRectLight rect_light = pxr::UsdLuxRectLight::Define(stage, usd_path); rect_light.CreateWidthAttr().Set(light->area_size, timecode); rect_light.CreateHeightAttr().Set(light->area_size, timecode); - usd_light = rect_light; +#if PXR_VERSION >= 2111 + usd_light_api = rect_light.LightAPI(); +#else + usd_light_api = rect_light; +#endif break; } } @@ -64,12 +81,23 @@ void USDLightWriter::do_write(HierarchyContext &context) case LA_LOCAL: { pxr::UsdLuxSphereLight sphere_light = pxr::UsdLuxSphereLight::Define(stage, usd_path); sphere_light.CreateRadiusAttr().Set(light->area_size, timecode); - usd_light = sphere_light; +#if PXR_VERSION >= 2111 + usd_light_api = sphere_light.LightAPI(); +#else + usd_light_api = sphere_light; +#endif break; } - case LA_SUN: - usd_light = pxr::UsdLuxDistantLight::Define(stage, usd_path); + case LA_SUN: { + pxr::UsdLuxDistantLight distant_light = pxr::UsdLuxDistantLight::Define(stage, usd_path); + /* TODO(makowalski): set angle attribute here. */ +#if PXR_VERSION >= 2111 + usd_light_api = distant_light.LightAPI(); +#else + usd_light_api = distant_light; +#endif break; + } default: BLI_assert_msg(0, "is_supported() returned true for unsupported light type"); } @@ -85,10 +113,10 @@ void USDLightWriter::do_write(HierarchyContext &context) else { usd_intensity = light->energy / 100.0f; } - usd_light.CreateIntensityAttr().Set(usd_intensity, timecode); + usd_light_api.CreateIntensityAttr().Set(usd_intensity, timecode); - usd_light.CreateColorAttr().Set(pxr::GfVec3f(light->r, light->g, light->b), timecode); - usd_light.CreateSpecularAttr().Set(light->spec_fac, timecode); + usd_light_api.CreateColorAttr().Set(pxr::GfVec3f(light->r, light->g, light->b), timecode); + usd_light_api.CreateSpecularAttr().Set(light->spec_fac, timecode); } } // namespace blender::io::usd diff --git a/source/blender/io/usd/intern/usd_writer_material.cc b/source/blender/io/usd/intern/usd_writer_material.cc index 29ab0479f6e..b548a666ef7 100644 --- a/source/blender/io/usd/intern/usd_writer_material.cc +++ b/source/blender/io/usd/intern/usd_writer_material.cc @@ -163,7 +163,7 @@ void create_usd_preview_surface_material(const USDExporterContext &usd_export_co created_shader = create_usd_preview_shader(usd_export_context, usd_material, input_node); preview_surface.CreateInput(input_spec.input_name, input_spec.input_type) - .ConnectToSource(created_shader, input_spec.source_name); + .ConnectToSource(created_shader.ConnectableAPI(), input_spec.source_name); } else if (input_spec.set_default_value) { /* Set hardcoded value. */ @@ -217,7 +217,7 @@ void create_usd_viewport_material(const USDExporterContext &usd_export_context, shader.CreateInput(usdtokens::metallic, pxr::SdfValueTypeNames->Float).Set(material->metallic); /* Connect the shader and the material together. */ - usd_material.CreateSurfaceOutput().ConnectToSource(shader, usdtokens::surface); + usd_material.CreateSurfaceOutput().ConnectToSource(shader.ConnectableAPI(), usdtokens::surface); } /* Return USD Preview Surface input map singleton. */ @@ -293,12 +293,12 @@ static void create_uvmap_shader(const USDExporterContext &usd_export_context, uv_shader.CreateInput(usdtokens::varname, pxr::SdfValueTypeNames->Token) .Set(pxr::TfToken(uv_set)); usd_tex_shader.CreateInput(usdtokens::st, pxr::SdfValueTypeNames->Float2) - .ConnectToSource(uv_shader, usdtokens::result); + .ConnectToSource(uv_shader.ConnectableAPI(), usdtokens::result); } else { uv_shader.CreateInput(usdtokens::varname, pxr::SdfValueTypeNames->Token).Set(default_uv); usd_tex_shader.CreateInput(usdtokens::st, pxr::SdfValueTypeNames->Float2) - .ConnectToSource(uv_shader, usdtokens::result); + .ConnectToSource(uv_shader.ConnectableAPI(), usdtokens::result); } } @@ -313,7 +313,7 @@ static void create_uvmap_shader(const USDExporterContext &usd_export_context, if (uv_shader.GetPrim().IsValid()) { uv_shader.CreateInput(usdtokens::varname, pxr::SdfValueTypeNames->Token).Set(default_uv); usd_tex_shader.CreateInput(usdtokens::st, pxr::SdfValueTypeNames->Float2) - .ConnectToSource(uv_shader, usdtokens::result); + .ConnectToSource(uv_shader.ConnectableAPI(), usdtokens::result); } } } @@ -488,7 +488,7 @@ static pxr::UsdShadeShader create_usd_preview_shader(const USDExporterContext &u case SH_NODE_BSDF_DIFFUSE: case SH_NODE_BSDF_PRINCIPLED: { shader.CreateIdAttr(pxr::VtValue(usdtokens::preview_surface)); - material.CreateSurfaceOutput().ConnectToSource(shader, usdtokens::surface); + material.CreateSurfaceOutput().ConnectToSource(shader.ConnectableAPI(), usdtokens::surface); break; } diff --git a/source/blender/io/wavefront_obj/CMakeLists.txt b/source/blender/io/wavefront_obj/CMakeLists.txt index 8045d51e0da..cc375577b52 100644 --- a/source/blender/io/wavefront_obj/CMakeLists.txt +++ b/source/blender/io/wavefront_obj/CMakeLists.txt @@ -13,6 +13,7 @@ set(INC ../../makesrna ../../nodes ../../windowmanager + ../../../../extern/fmtlib/include ../../../../intern/guardedalloc ) diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_io.hh b/source/blender/io/wavefront_obj/exporter/obj_export_io.hh index 3bee93b36a5..0095384609a 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_io.hh +++ b/source/blender/io/wavefront_obj/exporter/obj_export_io.hh @@ -8,7 +8,6 @@ #include <cstdio> #include <string> -#include <system_error> #include <type_traits> #include <vector> @@ -17,6 +16,11 @@ #include "BLI_string_ref.hh" #include "BLI_utility_mixins.hh" +/* SEP macro from BLI path utils clashes with SEP symbol in fmt headers. */ +#undef SEP +#define FMT_HEADER_ONLY +#include <fmt/format.h> + namespace blender::io::obj { enum class eFileType { @@ -124,40 +128,40 @@ constexpr FormattingSyntax syntax_elem_to_formatting(const eOBJSyntaxElement key { switch (key) { case eOBJSyntaxElement::vertex_coords: { - return {"v %f %f %f\n", 3, is_type_float<T...>}; + return {"v {:.6f} {:.6f} {:.6f}\n", 3, is_type_float<T...>}; } case eOBJSyntaxElement::uv_vertex_coords: { - return {"vt %f %f\n", 2, is_type_float<T...>}; + return {"vt {:.6f} {:.6f}\n", 2, is_type_float<T...>}; } case eOBJSyntaxElement::normal: { - return {"vn %.4f %.4f %.4f\n", 3, is_type_float<T...>}; + return {"vn {:.4f} {:.4f} {:.4f}\n", 3, is_type_float<T...>}; } case eOBJSyntaxElement::poly_element_begin: { return {"f", 0, is_type_string_related<T...>}; } case eOBJSyntaxElement::vertex_uv_normal_indices: { - return {" %d/%d/%d", 3, is_type_integral<T...>}; + return {" {}/{}/{}", 3, is_type_integral<T...>}; } case eOBJSyntaxElement::vertex_normal_indices: { - return {" %d//%d", 2, is_type_integral<T...>}; + return {" {}//{}", 2, is_type_integral<T...>}; } case eOBJSyntaxElement::vertex_uv_indices: { - return {" %d/%d", 2, is_type_integral<T...>}; + return {" {}/{}", 2, is_type_integral<T...>}; } case eOBJSyntaxElement::vertex_indices: { - return {" %d", 1, is_type_integral<T...>}; + return {" {}", 1, is_type_integral<T...>}; } case eOBJSyntaxElement::poly_usemtl: { - return {"usemtl %s\n", 1, is_type_string_related<T...>}; + return {"usemtl {}\n", 1, is_type_string_related<T...>}; } case eOBJSyntaxElement::edge: { - return {"l %d %d\n", 2, is_type_integral<T...>}; + return {"l {} {}\n", 2, is_type_integral<T...>}; } case eOBJSyntaxElement::cstype: { return {"cstype bspline\n", 0, is_type_string_related<T...>}; } case eOBJSyntaxElement::nurbs_degree: { - return {"deg %d\n", 1, is_type_integral<T...>}; + return {"deg {}\n", 1, is_type_integral<T...>}; } case eOBJSyntaxElement::curve_element_begin: { return {"curv 0.0 1.0", 0, is_type_string_related<T...>}; @@ -166,7 +170,7 @@ constexpr FormattingSyntax syntax_elem_to_formatting(const eOBJSyntaxElement key return {"parm u 0.0", 0, is_type_string_related<T...>}; } case eOBJSyntaxElement::nurbs_parameters: { - return {" %f", 1, is_type_float<T...>}; + return {" {:.6f}", 1, is_type_float<T...>}; } case eOBJSyntaxElement::nurbs_parameter_end: { return {" 1.0\n", 0, is_type_string_related<T...>}; @@ -184,19 +188,19 @@ constexpr FormattingSyntax syntax_elem_to_formatting(const eOBJSyntaxElement key return {"\n", 0, is_type_string_related<T...>}; } case eOBJSyntaxElement::mtllib: { - return {"mtllib %s\n", 1, is_type_string_related<T...>}; + return {"mtllib {}\n", 1, is_type_string_related<T...>}; } case eOBJSyntaxElement::smooth_group: { - return {"s %d\n", 1, is_type_integral<T...>}; + return {"s {}\n", 1, is_type_integral<T...>}; } case eOBJSyntaxElement::object_group: { - return {"g %s\n", 1, is_type_string_related<T...>}; + return {"g {}\n", 1, is_type_string_related<T...>}; } case eOBJSyntaxElement::object_name: { - return {"o %s\n", 1, is_type_string_related<T...>}; + return {"o {}\n", 1, is_type_string_related<T...>}; } case eOBJSyntaxElement::string: { - return {"%s", 1, is_type_string_related<T...>}; + return {"{}", 1, is_type_string_related<T...>}; } } } @@ -206,56 +210,56 @@ constexpr FormattingSyntax syntax_elem_to_formatting(const eMTLSyntaxElement key { switch (key) { case eMTLSyntaxElement::newmtl: { - return {"newmtl %s\n", 1, is_type_string_related<T...>}; + return {"newmtl {}\n", 1, is_type_string_related<T...>}; } case eMTLSyntaxElement::Ni: { - return {"Ni %.6f\n", 1, is_type_float<T...>}; + return {"Ni {:.6f}\n", 1, is_type_float<T...>}; } case eMTLSyntaxElement::d: { - return {"d %.6f\n", 1, is_type_float<T...>}; + return {"d {:.6f}\n", 1, is_type_float<T...>}; } case eMTLSyntaxElement::Ns: { - return {"Ns %.6f\n", 1, is_type_float<T...>}; + return {"Ns {:.6f}\n", 1, is_type_float<T...>}; } case eMTLSyntaxElement::illum: { - return {"illum %d\n", 1, is_type_integral<T...>}; + return {"illum {}\n", 1, is_type_integral<T...>}; } case eMTLSyntaxElement::Ka: { - return {"Ka %.6f %.6f %.6f\n", 3, is_type_float<T...>}; + return {"Ka {:.6f} {:.6f} {:.6f}\n", 3, is_type_float<T...>}; } case eMTLSyntaxElement::Kd: { - return {"Kd %.6f %.6f %.6f\n", 3, is_type_float<T...>}; + return {"Kd {:.6f} {:.6f} {:.6f}\n", 3, is_type_float<T...>}; } case eMTLSyntaxElement::Ks: { - return {"Ks %.6f %.6f %.6f\n", 3, is_type_float<T...>}; + return {"Ks {:.6f} {:.6f} {:.6f}\n", 3, is_type_float<T...>}; } case eMTLSyntaxElement::Ke: { - return {"Ke %.6f %.6f %.6f\n", 3, is_type_float<T...>}; + return {"Ke {:.6f} {:.6f} {:.6f}\n", 3, is_type_float<T...>}; } /* Keep only one space between options since filepaths may have leading spaces too. */ case eMTLSyntaxElement::map_Kd: { - return {"map_Kd %s %s\n", 2, is_type_string_related<T...>}; + return {"map_Kd {} {}\n", 2, is_type_string_related<T...>}; } case eMTLSyntaxElement::map_Ks: { - return {"map_Ks %s %s\n", 2, is_type_string_related<T...>}; + return {"map_Ks {} {}\n", 2, is_type_string_related<T...>}; } case eMTLSyntaxElement::map_Ns: { - return {"map_Ns %s %s\n", 2, is_type_string_related<T...>}; + return {"map_Ns {} {}\n", 2, is_type_string_related<T...>}; } case eMTLSyntaxElement::map_d: { - return {"map_d %s %s\n", 2, is_type_string_related<T...>}; + return {"map_d {} {}\n", 2, is_type_string_related<T...>}; } case eMTLSyntaxElement::map_refl: { - return {"map_refl %s %s\n", 2, is_type_string_related<T...>}; + return {"map_refl {} {}\n", 2, is_type_string_related<T...>}; } case eMTLSyntaxElement::map_Ke: { - return {"map_Ke %s %s\n", 2, is_type_string_related<T...>}; + return {"map_Ke {} {}\n", 2, is_type_string_related<T...>}; } case eMTLSyntaxElement::map_Bump: { - return {"map_Bump %s %s\n", 2, is_type_string_related<T...>}; + return {"map_Bump {} {}\n", 2, is_type_string_related<T...>}; } case eMTLSyntaxElement::string: { - return {"%s", 1, is_type_string_related<T...>}; + return {"{}", 1, is_type_string_related<T...>}; } } } @@ -270,9 +274,7 @@ constexpr FormattingSyntax syntax_elem_to_formatting(const eMTLSyntaxElement key * Call write_fo_file once in a while to write the memory buffer(s) * into the given file. */ -template<eFileType filetype, - size_t buffer_chunk_size = 64 * 1024, - size_t write_local_buffer_size = 1024> +template<eFileType filetype, size_t buffer_chunk_size = 64 * 1024> class FormatHandler : NonCopyable, NonMovable { private: typedef std::vector<char> VectorChar; @@ -299,7 +301,7 @@ class FormatHandler : NonCopyable, NonMovable { return blocks_.size(); } - void append_from(FormatHandler<filetype, buffer_chunk_size, write_local_buffer_size> &v) + void append_from(FormatHandler<filetype, buffer_chunk_size> &v) { blocks_.insert(blocks_.end(), std::make_move_iterator(v.blocks_.begin()), @@ -328,33 +330,6 @@ class FormatHandler : NonCopyable, NonMovable { } private: - /* Remove this after upgrading to C++20. */ - template<typename T> using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>; - - /** - * Make #std::string etc., usable for `fprintf` family. int float etc. are not affected. - * \return: `const char *` or the original argument if the argument is - * not related to #std::string. - */ - template<typename T> constexpr auto convert_to_primitive(T &&arg) const - { - if constexpr (std::is_same_v<remove_cvref_t<T>, std::string> || - std::is_same_v<remove_cvref_t<T>, blender::StringRefNull>) { - return arg.c_str(); - } - else if constexpr (std::is_same_v<remove_cvref_t<T>, blender::StringRef>) { - BLI_STATIC_ASSERT( - (always_false<T>::value), - "Null-terminated string not present. Please use blender::StringRefNull instead."); - /* Another trick to cause a compile-time error: returning nothing to #std::printf. */ - return; - } - else { - /* For int, float etc. */ - return std::forward<T>(arg); - } - } - /* Ensure the last block contains at least this amount of free space. * If not, add a new block with max of block size & the amount of space needed. */ void ensure_space(size_t at_least) @@ -365,38 +340,15 @@ class FormatHandler : NonCopyable, NonMovable { } } - template<typename... T> constexpr void write_impl(const char *fmt, T &&...args) + template<typename... T> void write_impl(const char *fmt, T &&...args) { - if constexpr (sizeof...(T) == 0) { - /* No arguments: just emit the format string. */ - size_t len = strlen(fmt); - ensure_space(len); - VectorChar &bb = blocks_.back(); - bb.insert(bb.end(), fmt, fmt + len); - } - else { - /* Format into a local buffer. */ - char buf[write_local_buffer_size]; - int needed = std::snprintf( - buf, write_local_buffer_size, fmt, convert_to_primitive(std::forward<T>(args))...); - if (needed < 0) - throw std::system_error( - errno, std::system_category(), "Failed to format obj export string into a buffer"); - ensure_space(needed + 1); /* Ensure space for zero terminator. */ - VectorChar &bb = blocks_.back(); - if (needed < write_local_buffer_size) { - /* String formatted successfully into the local buffer, copy it. */ - bb.insert(bb.end(), buf, buf + needed); - } - else { - /* Would need more space than the local buffer: insert said space and format again into - * that. */ - size_t bbEnd = bb.size(); - bb.insert(bb.end(), needed, ' '); - std::snprintf( - bb.data() + bbEnd, needed + 1, fmt, convert_to_primitive(std::forward<T>(args))...); - } - } + /* Format into a local buffer. */ + fmt::memory_buffer buf; + fmt::format_to(fmt::appender(buf), fmt, std::forward<T>(args)...); + size_t len = buf.size(); + ensure_space(len); + VectorChar &bb = blocks_.back(); + bb.insert(bb.end(), buf.begin(), buf.end()); } }; diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc index fb9074999f9..8c9b04a5ac3 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc @@ -33,7 +33,7 @@ OBJMesh::OBJMesh(Depsgraph *depsgraph, const OBJExportParams &export_params, Obj { /* We need to copy the object because it may be in temporary space. */ Object *obj_eval = DEG_get_evaluated_object(depsgraph, mesh_object); - export_object_eval_ = *obj_eval; + export_object_eval_ = dna::shallow_copy(*obj_eval); export_mesh_eval_ = export_params.apply_modifiers ? BKE_object_get_evaluated_mesh(&export_object_eval_) : BKE_object_get_pre_modified_mesh(&export_object_eval_); @@ -89,7 +89,7 @@ std::pair<Mesh *, bool> OBJMesh::triangulate_mesh_eval() if (export_mesh_eval_->totpoly <= 0) { return {export_mesh_eval_, false}; } - const BMeshCreateParams bm_create_params = {0u}; + const BMeshCreateParams bm_create_params = {false}; BMeshFromMeshParams bm_convert_params{}; bm_convert_params.calc_face_normal = true; bm_convert_params.calc_vert_normal = true; diff --git a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc index b8fecfb25f3..7e3a9228c3b 100644 --- a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc +++ b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc @@ -241,7 +241,7 @@ TEST(obj_exporter_writer, mtllib) TEST(obj_exporter_writer, format_handler_buffer_chunking) { /* Use a tiny buffer chunk size, so that the test below ends up creating several blocks. */ - FormatHandler<eFileType::OBJ, 16, 8> h; + FormatHandler<eFileType::OBJ, 16> h; h.write<eOBJSyntaxElement::object_name>("abc"); h.write<eOBJSyntaxElement::object_name>("abcd"); h.write<eOBJSyntaxElement::object_name>("abcde"); diff --git a/source/blender/makesdna/DNA_curves_types.h b/source/blender/makesdna/DNA_curves_types.h index f1626781fc6..97cc588e639 100644 --- a/source/blender/makesdna/DNA_curves_types.h +++ b/source/blender/makesdna/DNA_curves_types.h @@ -28,6 +28,7 @@ typedef enum CurveType { CURVE_TYPE_BEZIER = 2, CURVE_TYPE_NURBS = 3, } CurveType; +#define CURVE_TYPES_NUM 4 typedef enum HandleType { /** The handle can be moved anywhere, and doesn't influence the point's other handle. */ diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index ad2ef05da13..cf43574af55 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -52,7 +52,7 @@ typedef struct CustomDataLayer { typedef struct CustomDataExternal { /** FILE_MAX. */ - char filename[1024]; + char filepath[1024]; } CustomDataExternal; /** diff --git a/source/blender/makesdna/DNA_defs.h b/source/blender/makesdna/DNA_defs.h index b4230209dd5..bfeb809b369 100644 --- a/source/blender/makesdna/DNA_defs.h +++ b/source/blender/makesdna/DNA_defs.h @@ -46,3 +46,100 @@ /* non-id name variables should use this length */ #define MAX_NAME 64 + +/* #DNA_DEFINE_CXX_METHODS is used to define C++ methods which are needed for proper/safe resource + * management, making unsafe (from an ownership perspective: i.e. pointers which sometimes needs to + * be set to nullptr on copy, sometimes needs to be dupalloc-ed) operations explicit, and taking + * care of compiler specific warnings when dealing with members marked with DNA_DEPRECATED. + * + * The `class_name` argument is to match the structure name the macro is used from. + * + * Typical usage example: + * + * typedef struct Object { + * DNA_DEFINE_CXX_METHODS(Object) + * } Object; + */ +#ifndef __cplusplus +# define DNA_DEFINE_CXX_METHODS(class_name) +#else + +/* Forward-declared here since there is no simple header file to be pulled for this functionality. + * Avoids pulling `string.h` from this header to get access to #memcpy. */ +extern "C" void _DNA_internal_memcpy(void *dst, const void *src, size_t size); +extern "C" void _DNA_internal_memzero(void *dst, size_t size); + +namespace blender::dna::internal { + +template<class T> class ShallowDataConstRef { + public: + constexpr explicit ShallowDataConstRef(const T &ref) : ref_(ref) + { + } + + inline const T *get_pointer() const + { + return &ref_; + } + + private: + const T &ref_; +}; + +} // namespace blender::dna::internal + +# define DNA_DEFINE_CXX_METHODS(class_name) \ + class_name() = default; \ + ~class_name() = default; \ + /* Delete copy and assignment, which are not safe for resource ownership. */ \ + class_name(const class_name &other) = delete; \ + class_name(class_name &&other) noexcept = delete; \ + class_name &operator=(const class_name &other) = delete; \ + class_name &operator=(class_name &&other) = delete; \ + /* Support for shallow copy. */ \ + /* NOTE: Calling the default constructor works-around deprecated warning generated by GCC. */ \ + class_name(const blender::dna::internal::ShallowDataConstRef<class_name> ref) : class_name() \ + { \ + _DNA_internal_memcpy(this, ref.get_pointer(), sizeof(class_name)); \ + } \ + class_name &operator=(const blender::dna::internal::ShallowDataConstRef<class_name> ref) \ + { \ + if (this != ref.get_pointer()) { \ + _DNA_internal_memcpy(this, ref.get_pointer(), sizeof(class_name)); \ + } \ + return *this; \ + } + +namespace blender::dna { + +/* Creates shallow copy of the given object. + * The entire object is copied as-is using memory copy. + * + * Typical usage: + * Object temp_object = blender::dna::shallow_copy(*input_object); + * + * From the implementation detail go via copy constructor/assign operator defined in the structure. + */ +template<class T> +[[nodiscard]] inline internal::ShallowDataConstRef<T> shallow_copy(const T &other) +{ + return internal::ShallowDataConstRef(other); +} + +/* Fill underlying memory used by DNA object with zeroes. */ +template<class T> inline void zero_memory(T &object) +{ + /* TODO(sergey): Consider adding static assert for T being a trivial type. */ + _DNA_internal_memzero(&object, sizeof(T)); +} + +/* Copy memory from one DNA object to another. */ +template<class T> inline void copy_memory(T &dst, const T &src) +{ + /* TODO(sergey): Consider adding static assert for T being a trivial type. */ + _DNA_internal_memcpy(&dst, &src, sizeof(T)); +} + +} // namespace blender::dna + +#endif diff --git a/source/blender/makesdna/DNA_gpencil_modifier_defaults.h b/source/blender/makesdna/DNA_gpencil_modifier_defaults.h index 3e06259dfd5..9d14ca039ac 100644 --- a/source/blender/makesdna/DNA_gpencil_modifier_defaults.h +++ b/source/blender/makesdna/DNA_gpencil_modifier_defaults.h @@ -193,7 +193,7 @@ .vgname = "", \ .pass_index = 0, \ .flag = GP_SMOOTH_MOD_LOCATION, \ - .factor = 0.5f, \ + .factor = 1.0f, \ .step = 1, \ .layer_pass = 0, \ .curve_intensity = NULL, \ @@ -366,5 +366,14 @@ .smooth_step = 1, \ } +#define _DNA_DEFAULT_EnvelopeGpencilModifierData \ + { \ + .spread = 10, \ + .mode = GP_ENVELOPE_SEGMENTS, \ + .mat_nr = -1, \ + .thickness = 1.0f, \ + .strength = 1.0f, \ + } + /* clang-format off */ diff --git a/source/blender/makesdna/DNA_gpencil_modifier_types.h b/source/blender/makesdna/DNA_gpencil_modifier_types.h index 0539b84e093..7568dc5ff9a 100644 --- a/source/blender/makesdna/DNA_gpencil_modifier_types.h +++ b/source/blender/makesdna/DNA_gpencil_modifier_types.h @@ -46,6 +46,7 @@ typedef enum GpencilModifierType { eGpencilModifierType_Dash = 22, eGpencilModifierType_WeightAngle = 23, eGpencilModifierType_Shrinkwrap = 24, + eGpencilModifierType_Envelope = 25, /* Keep last. */ NUM_GREASEPENCIL_MODIFIER_TYPES, } GpencilModifierType; @@ -521,7 +522,7 @@ typedef struct DashGpencilModifierSegment { float radius; float opacity; int mat_nr; - int _pad; + int flag; } DashGpencilModifierSegment; typedef struct DashGpencilModifierData { @@ -545,6 +546,14 @@ typedef struct DashGpencilModifierData { } DashGpencilModifierData; +typedef enum eDashGpencil_Flag { + GP_DASH_INVERT_LAYER = (1 << 0), + GP_DASH_INVERT_PASS = (1 << 1), + GP_DASH_INVERT_LAYERPASS = (1 << 2), + GP_DASH_INVERT_MATERIAL = (1 << 3), + GP_DASH_USE_CYCLIC = (1 << 7), +} eDashGpencil_Flag; + typedef struct MirrorGpencilModifierData { GpencilModifierData modifier; struct Object *object; @@ -749,6 +758,7 @@ typedef enum eSmoothGpencil_Flag { GP_SMOOTH_INVERT_LAYERPASS = (1 << 7), GP_SMOOTH_INVERT_MATERIAL = (1 << 4), GP_SMOOTH_CUSTOM_CURVE = (1 << 8), + GP_SMOOTH_KEEP_SHAPE = (1 << 9), } eSmoothGpencil_Flag; typedef struct ArmatureGpencilModifierData { @@ -1127,6 +1137,46 @@ typedef enum eShrinkwrapGpencil_Flag { GP_SHRINKWRAP_INVERT_VGROUP = (1 << 6), } eShrinkwrapGpencil_Flag; +typedef struct EnvelopeGpencilModifierData { + GpencilModifierData modifier; + /** Material for filtering. */ + struct Material *material; + /** Layer name. */ + char layername[64]; + /** Optional vertexgroup name, MAX_VGROUP_NAME. */ + char vgname[64]; + /** Custom index for passes. */ + int pass_index; + /** Several flags. */ + int flag; + int mode; + /** Material for the new strokes. */ + int mat_nr; + /** Thickness multiplier for the new strokes. */ + float thickness; + /** Strength multiplier for the new strokes. */ + float strength; + /** Custom index for passes. */ + int layer_pass; + /* Length of the envelope effect. */ + int spread; +} EnvelopeGpencilModifierData; + +typedef enum eEnvelopeGpencil_Flag { + GP_ENVELOPE_INVERT_LAYER = (1 << 0), + GP_ENVELOPE_INVERT_PASS = (1 << 1), + GP_ENVELOPE_INVERT_VGROUP = (1 << 2), + GP_ENVELOPE_INVERT_LAYERPASS = (1 << 3), + GP_ENVELOPE_INVERT_MATERIAL = (1 << 4), +} eEnvelopeGpencil_Flag; + +/* Texture->mode */ +typedef enum eEnvelopeGpencil_Mode { + GP_ENVELOPE_DEFORM = 0, + GP_ENVELOPE_SEGMENTS = 1, + GP_ENVELOPE_FILLS = 2, +} eEnvelopeGpencil_Mode; + #ifdef __cplusplus } #endif diff --git a/source/blender/makesdna/DNA_modifier_defaults.h b/source/blender/makesdna/DNA_modifier_defaults.h index 299ac4e2fbe..77730ce254c 100644 --- a/source/blender/makesdna/DNA_modifier_defaults.h +++ b/source/blender/makesdna/DNA_modifier_defaults.h @@ -309,7 +309,7 @@ .falloff = 0.0f, \ .curfalloff = NULL, \ .indexar = NULL, \ - .totindex = 0, \ + .indexar_num = 0, \ .force = 1.0f, \ .name = "", \ } @@ -317,7 +317,7 @@ #define _DNA_DEFAULT_LaplacianDeformModifierData \ { \ .anchor_grp_name = "", \ - .total_verts = 0, \ + .verts_num = 0, \ .repeat = 1, \ .vertexco = NULL, \ .cache_system = NULL, \ @@ -381,13 +381,13 @@ .bindinfluences = NULL, \ .bindoffsets = NULL, \ .bindcagecos = NULL, \ - .totvert = 0, \ - .totcagevert = 0, \ + .verts_num = 0, \ + .cage_verts_num = 0, \ .dyngrid = NULL, \ .dyninfluences = NULL, \ .dynverts = NULL, \ .dyngridsize = 0, \ - .totinfluence = 0, \ + .influences_num = 0, \ .dyncellmin = {0.0f, 0.0f, 0.0f}, \ .dyncellwidth = 0.0f, \ .bindmat = _DNA_DEFAULT_UNIT_M4, \ @@ -621,7 +621,7 @@ .mesh = NULL, \ .bvhtree = NULL, \ .cfra = 0, \ - .numverts = 0, \ + .verts_num = 0, \ } #define _DNA_DEFAULT_SurfaceDeformModifierData \ @@ -630,9 +630,9 @@ .target = NULL, \ .verts = NULL, \ .falloff = 4.0f, \ - .num_mesh_verts = 0, \ - .num_bind_verts = 0, \ - .numpoly = 0, \ + .mesh_verts_num = 0, \ + .bind_verts_num = 0, \ + .polys_num = 0, \ .flags = 0, \ .mat = _DNA_DEFAULT_UNIT_M4, \ .strength = 1.0f, \ @@ -650,7 +650,7 @@ #define _DNA_DEFAULT_UVProjectModifierData \ { \ .projectors = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, \ - .num_projectors = 1, \ + .projectors_num = 1, \ .aspectx = 1.0f, \ .aspecty = 1.0f, \ .scalex = 1.0f, \ diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 470497aabce..73c4eeaaab3 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -617,7 +617,7 @@ typedef struct UVProjectModifierData { */ struct Object *projectors[10]; char _pad2[4]; - int num_projectors; + int projectors_num; float aspectx, aspecty; float scalex, scaley; /** MAX_CUSTOMDATA_LAYER_NAME. */ @@ -812,7 +812,7 @@ typedef struct HookModifierData { /** If NULL, it's using vertexgroup. */ int *indexar; - int totindex; + int indexar_num; float force; /** Optional vertexgroup name, MAX_VGROUP_NAME. */ char name[64]; @@ -895,7 +895,7 @@ typedef struct SurfaceModifierData { /** Bounding volume hierarchy of the mesh faces. */ struct BVHTreeFromMesh *bvhtree; - int cfra, numverts; + int cfra, verts_num; } SurfaceModifierData; typedef struct BooleanModifierData { @@ -945,7 +945,7 @@ typedef struct MDefInfluence { typedef struct MDefCell { int offset; - int totinfluence; + int influences_num; } MDefCell; typedef struct MeshDeformModifierData { @@ -967,7 +967,7 @@ typedef struct MeshDeformModifierData { /** Coordinates that cage was bound with. */ float *bindcagecos; /** Total vertices in mesh and cage. */ - int totvert, totcagevert; + int verts_num, cage_verts_num; /* result of dynamic binding */ /** Grid with dynamic binding cell points. */ @@ -979,7 +979,7 @@ typedef struct MeshDeformModifierData { /** Size of the dynamic bind grid. */ int dyngridsize; /** Total number of vertex influences. */ - int totinfluence; + int influences_num; /** Offset of the dynamic bind grid. */ float dyncellmin[3]; /** Width of dynamic bind cell. */ @@ -998,7 +998,7 @@ typedef struct MeshDeformModifierData { struct MeshDeformModifierData *mmd, struct Mesh *cagemesh, float *vertexcos, - int totvert, + int verts_num, float cagemat[4][4]); } MeshDeformModifierData; @@ -2018,7 +2018,7 @@ typedef struct LaplacianDeformModifierData { ModifierData modifier; /** MAX_VGROUP_NAME. */ char anchor_grp_name[64]; - int total_verts, repeat; + int verts_num, repeat; float *vertexco; /** Runtime only. */ void *cache_system; @@ -2201,7 +2201,7 @@ enum { typedef struct SDefBind { unsigned int *vert_inds; - unsigned int numverts; + unsigned int verts_num; int mode; float *vert_weights; float normal_dist; @@ -2210,7 +2210,7 @@ typedef struct SDefBind { typedef struct SDefVert { SDefBind *binds; - unsigned int numbinds; + unsigned int binds_num; unsigned int vertex_idx; } SDefVert; @@ -2223,7 +2223,7 @@ typedef struct SurfaceDeformModifierData { /** Vertex bind data. */ SDefVert *verts; float falloff; - unsigned int num_mesh_verts, num_bind_verts, numpoly; + unsigned int mesh_verts_num, bind_verts_num, polys_num; int flags; float mat[4][4]; float strength; diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 99d7e15fa7a..73539bea8ee 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -1189,7 +1189,7 @@ typedef struct NodeCryptomatte { /** Legacy attributes */ /* Number of input sockets. */ - int num_inputs; + int inputs_num; char _pad[4]; NodeCryptomatte_Runtime runtime; diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 9e0bf7dcc5a..838a4ed2818 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -203,7 +203,7 @@ typedef struct Object_Runtime { float (*crazyspace_deform_imats)[3][3]; float (*crazyspace_deform_cos)[3]; - int crazyspace_num_verts; + int crazyspace_verts_num; int _pad3[3]; } Object_Runtime; @@ -233,6 +233,8 @@ enum eObjectLineArt_Flags { }; typedef struct Object { + DNA_DEFINE_CXX_METHODS(Object) + ID id; /** Animation data (must be immediately after id for utilities to use it). */ struct AnimData *adt; diff --git a/source/blender/makesdna/DNA_particle_defaults.h b/source/blender/makesdna/DNA_particle_defaults.h index 138aa6f1f98..108252a5e6c 100644 --- a/source/blender/makesdna/DNA_particle_defaults.h +++ b/source/blender/makesdna/DNA_particle_defaults.h @@ -56,8 +56,8 @@ .rotmode = PART_ROT_VEL, \ .avemode = PART_AVE_VELOCITY, \ \ - .child_nbr = 10, \ - .ren_child_nbr = 100, \ + .child_percent = 10, \ + .child_render_percent = 100, \ .childrad = 0.2f, \ .childflat = 0.0f, \ .clumppow = 0.0f, \ diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index 397385c0f5b..f3d342e4849 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -226,7 +226,7 @@ typedef struct ParticleSettings { /* children */ int child_flag; char _pad3[4]; - int child_nbr, ren_child_nbr; + int child_percent, child_render_percent; float parents, childsize, childrandsize; float childrad, childflat; /* clumping */ diff --git a/source/blender/makesdna/DNA_pointcache_types.h b/source/blender/makesdna/DNA_pointcache_types.h index b247176f537..1133237199b 100644 --- a/source/blender/makesdna/DNA_pointcache_types.h +++ b/source/blender/makesdna/DNA_pointcache_types.h @@ -131,7 +131,7 @@ enum { PTCACHE_FRAMES_SKIPPED = 1 << 8, PTCACHE_EXTERNAL = 1 << 9, PTCACHE_READ_INFO = 1 << 10, - /** Don't use the filename of the blend-file the data is linked from (write a local cache). */ + /** Don't use the file-path of the blend-file the data is linked from (write a local cache). */ PTCACHE_IGNORE_LIBPATH = 1 << 11, /** * High resolution cache is saved for smoke for backwards compatibility, diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 24c120ae860..d0c23f5d452 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -465,6 +465,7 @@ typedef struct ImageFormatData { #define R_IMF_IMTYPE_XVID 32 #define R_IMF_IMTYPE_THEORA 33 #define R_IMF_IMTYPE_PSD 34 +#define R_IMF_IMTYPE_WEBP 35 #define R_IMF_IMTYPE_INVALID 255 @@ -1989,7 +1990,7 @@ enum { /* sequencer seq_prev_type seq_rend_type */ -/** #RenderData.engine (scene.c) */ +/** #RenderData.engine (scene.cc) */ extern const char *RE_engine_id_BLENDER_EEVEE; extern const char *RE_engine_id_BLENDER_WORKBENCH; extern const char *RE_engine_id_CYCLES; diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index c8209b4d194..d32757cc868 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -540,6 +540,8 @@ enum { AREA_FLAG_STACKED_FULLSCREEN = (1 << 7), /** Update action zones (even if the mouse is not intersecting them). */ AREA_FLAG_ACTIONZONES_UPDATE = (1 << 8), + /** For offscreen areas. */ + AREA_FLAG_OFFSCREEN = (1 << 9), }; #define AREAGRID 4 diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index c3335f7959e..6d7952cb799 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -309,7 +309,6 @@ typedef enum eSpaceOutliner_Flag { typedef enum eSpaceOutliner_Filter { SO_FILTER_SEARCH = (1 << 0), /* Run-time flag. */ SO_FILTER_CLEARED_1 = (1 << 1), - SO_FILTER_NO_LIB_OVERRIDE = SO_FILTER_CLEARED_1, /* re-use */ SO_FILTER_NO_OBJECT = (1 << 2), SO_FILTER_NO_OB_CONTENT = (1 << 3), /* Not only mesh, but modifiers, constraints, ... */ SO_FILTER_NO_CHILDREN = (1 << 4), @@ -345,7 +344,7 @@ typedef enum eSpaceOutliner_Filter { #define SO_FILTER_ANY \ (SO_FILTER_NO_OB_CONTENT | SO_FILTER_NO_CHILDREN | SO_FILTER_OB_TYPE | SO_FILTER_OB_STATE | \ - SO_FILTER_NO_COLLECTION | SO_FILTER_NO_VIEW_LAYERS | SO_FILTER_NO_LIB_OVERRIDE) + SO_FILTER_NO_COLLECTION | SO_FILTER_NO_VIEW_LAYERS) /** #SpaceOutliner.filter_state */ typedef enum eSpaceOutliner_StateFilter { @@ -990,12 +989,6 @@ typedef enum eFileSelectType { FILE_SPECIAL = 9, } eFileSelectType; -/** File-selector op property -> action. */ -typedef enum eFileSel_Action { - FILE_OPENFILE = 0, - FILE_SAVE = 1, -} eFileSel_Action; - /** * #FileSelectParams.flag / `sfile->params->flag`. * \note short flag, also used as 16 lower bits of flags in link/append code @@ -1141,8 +1134,8 @@ typedef struct FileDirEntry { # typedef struct FileDirEntryArr { ListBase entries; - int nbr_entries; - int nbr_entries_filtered; + int entries_num; + int entries_filtered_num; /** FILE_MAX. */ char root[1024]; diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 94b2514d423..99938d711ee 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -649,8 +649,9 @@ typedef struct UserDef_Experimental { char use_extended_asset_browser; char use_override_templates; char use_named_attribute_nodes; + char use_select_nearest_on_first_click; char enable_eevee_next; - char _pad[2]; + char _pad[1]; /** `makesdna` does not allow empty structs. */ } UserDef_Experimental; diff --git a/source/blender/makesdna/intern/CMakeLists.txt b/source/blender/makesdna/intern/CMakeLists.txt index e507831424f..2afaf04a8d7 100644 --- a/source/blender/makesdna/intern/CMakeLists.txt +++ b/source/blender/makesdna/intern/CMakeLists.txt @@ -122,10 +122,10 @@ set(SRC ../DNA_camera_defaults.h ../DNA_collection_defaults.h ../DNA_curve_defaults.h + ../DNA_curves_defaults.h ../DNA_defaults.h ../DNA_fluid_defaults.h ../DNA_gpencil_modifier_defaults.h - ../DNA_curves_defaults.h ../DNA_image_defaults.h ../DNA_lattice_defaults.h ../DNA_light_defaults.h diff --git a/source/blender/makesdna/intern/dna_defaults.c b/source/blender/makesdna/intern/dna_defaults.c index b7f942e2502..197a863db72 100644 --- a/source/blender/makesdna/intern/dna_defaults.c +++ b/source/blender/makesdna/intern/dna_defaults.c @@ -316,6 +316,7 @@ SDNA_DEFAULT_DECL_STRUCT(LengthGpencilModifierData); SDNA_DEFAULT_DECL_STRUCT(DashGpencilModifierData); SDNA_DEFAULT_DECL_STRUCT(DashGpencilModifierSegment); SDNA_DEFAULT_DECL_STRUCT(ShrinkwrapGpencilModifierData); +SDNA_DEFAULT_DECL_STRUCT(EnvelopeGpencilModifierData); #undef SDNA_DEFAULT_DECL_STRUCT @@ -555,6 +556,7 @@ const void *DNA_default_table[SDNA_TYPE_MAX] = { SDNA_DEFAULT_DECL(DashGpencilModifierData), SDNA_DEFAULT_DECL(DashGpencilModifierSegment), SDNA_DEFAULT_DECL(ShrinkwrapGpencilModifierData), + SDNA_DEFAULT_DECL(EnvelopeGpencilModifierData), }; #undef SDNA_DEFAULT_DECL #undef SDNA_DEFAULT_DECL_EX diff --git a/source/blender/makesdna/intern/dna_rename_defs.h b/source/blender/makesdna/intern/dna_rename_defs.h index 7b155df3084..86649357433 100644 --- a/source/blender/makesdna/intern/dna_rename_defs.h +++ b/source/blender/makesdna/intern/dna_rename_defs.h @@ -61,6 +61,7 @@ DNA_STRUCT_RENAME_ELEM(Curve, ext1, extrude) DNA_STRUCT_RENAME_ELEM(Curve, ext2, bevel_radius) DNA_STRUCT_RENAME_ELEM(Curve, len_wchar, len_char32) DNA_STRUCT_RENAME_ELEM(Curve, width, offset) +DNA_STRUCT_RENAME_ELEM(CustomDataExternal, filename, filepath) DNA_STRUCT_RENAME_ELEM(Editing, over_border, overlay_frame_rect) DNA_STRUCT_RENAME_ELEM(Editing, over_cfra, overlay_frame_abs) DNA_STRUCT_RENAME_ELEM(Editing, over_flag, overlay_frame_flag) @@ -73,29 +74,45 @@ DNA_STRUCT_RENAME_ELEM(FluidDomainSettings, guiding_parent, guide_parent) DNA_STRUCT_RENAME_ELEM(FluidDomainSettings, guiding_source, guide_source) DNA_STRUCT_RENAME_ELEM(FluidDomainSettings, guiding_vel_factor, guide_vel_factor) DNA_STRUCT_RENAME_ELEM(FluidEffectorSettings, guiding_mode, guide_mode) +DNA_STRUCT_RENAME_ELEM(HookModifierData, totindex, indexar_num) DNA_STRUCT_RENAME_ELEM(Image, name, filepath) +DNA_STRUCT_RENAME_ELEM(LaplacianDeformModifierData, total_verts, verts_num) DNA_STRUCT_RENAME_ELEM(Library, name, filepath) DNA_STRUCT_RENAME_ELEM(LineartGpencilModifierData, line_types, edge_types) DNA_STRUCT_RENAME_ELEM(LineartGpencilModifierData, transparency_flags, mask_switches) DNA_STRUCT_RENAME_ELEM(LineartGpencilModifierData, transparency_mask, material_mask_bits) +DNA_STRUCT_RENAME_ELEM(MDefCell, totinfluence, influences_num) DNA_STRUCT_RENAME_ELEM(MaskLayer, restrictflag, visibility_flag) DNA_STRUCT_RENAME_ELEM(MaterialLineArt, transparency_mask, material_mask_bits) +DNA_STRUCT_RENAME_ELEM(MeshDeformModifierData, totcagevert, cage_verts_num) +DNA_STRUCT_RENAME_ELEM(MeshDeformModifierData, totinfluence, influences_num) +DNA_STRUCT_RENAME_ELEM(MeshDeformModifierData, totvert, verts_num) DNA_STRUCT_RENAME_ELEM(MovieClip, name, filepath) +DNA_STRUCT_RENAME_ELEM(NodeCryptomatte, num_inputs, inputs_num) DNA_STRUCT_RENAME_ELEM(Object, col, color) DNA_STRUCT_RENAME_ELEM(Object, dup_group, instance_collection) DNA_STRUCT_RENAME_ELEM(Object, dupfacesca, instance_faces_scale) DNA_STRUCT_RENAME_ELEM(Object, restrictflag, visibility_flag) DNA_STRUCT_RENAME_ELEM(Object, size, scale) +DNA_STRUCT_RENAME_ELEM(Object_Runtime, crazyspace_num_verts, crazyspace_verts_num) +DNA_STRUCT_RENAME_ELEM(ParticleSettings, child_nbr, child_percent) DNA_STRUCT_RENAME_ELEM(ParticleSettings, dup_group, instance_collection) DNA_STRUCT_RENAME_ELEM(ParticleSettings, dup_ob, instance_object) DNA_STRUCT_RENAME_ELEM(ParticleSettings, dupliweights, instance_weights) -DNA_STRUCT_RENAME_ELEM(RigidBodyWorld, steps_per_second, substeps_per_frame) +DNA_STRUCT_RENAME_ELEM(ParticleSettings, ren_child_nbr, child_render_percent) DNA_STRUCT_RENAME_ELEM(RenderData, bake_filter, bake_margin) +DNA_STRUCT_RENAME_ELEM(RigidBodyWorld, steps_per_second, substeps_per_frame) +DNA_STRUCT_RENAME_ELEM(SDefBind, numverts, verts_num) +DNA_STRUCT_RENAME_ELEM(SDefVert, numbinds, binds_num) DNA_STRUCT_RENAME_ELEM(SpaceSeq, overlay_type, overlay_frame_type) -DNA_STRUCT_RENAME_ELEM(SurfaceDeformModifierData, numverts, num_bind_verts) +DNA_STRUCT_RENAME_ELEM(SurfaceDeformModifierData, num_mesh_verts, mesh_verts_num) +DNA_STRUCT_RENAME_ELEM(SurfaceDeformModifierData, numpoly, polys_num) +DNA_STRUCT_RENAME_ELEM(SurfaceDeformModifierData, numverts, bind_verts_num) +DNA_STRUCT_RENAME_ELEM(SurfaceModifierData, numverts, verts_num) DNA_STRUCT_RENAME_ELEM(Text, name, filepath) DNA_STRUCT_RENAME_ELEM(ThemeSpace, scrubbing_background, time_scrub_background) DNA_STRUCT_RENAME_ELEM(ThemeSpace, show_back_grad, background_type) +DNA_STRUCT_RENAME_ELEM(UVProjectModifierData, num_projectors, projectors_num) DNA_STRUCT_RENAME_ELEM(UserDef, gp_manhattendist, gp_manhattandist) DNA_STRUCT_RENAME_ELEM(VFont, name, filepath) DNA_STRUCT_RENAME_ELEM(View3D, far, clip_end) diff --git a/source/blender/makesdna/intern/dna_utils.c b/source/blender/makesdna/intern/dna_utils.c index 8c86ef69ebd..bc2584fe57a 100644 --- a/source/blender/makesdna/intern/dna_utils.c +++ b/source/blender/makesdna/intern/dna_utils.c @@ -308,3 +308,21 @@ const char *DNA_struct_rename_legacy_hack_alias_from_static(const char *name) } /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Internal helpers for C++ + * \{ */ + +void _DNA_internal_memcpy(void *dst, const void *src, size_t size); +void _DNA_internal_memcpy(void *dst, const void *src, const size_t size) +{ + memcpy(dst, src, size); +} + +void _DNA_internal_memzero(void *dst, size_t size); +void _DNA_internal_memzero(void *dst, const size_t size) +{ + memset(dst, 0, size); +} + +/** \} */ diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index 0d2f265a9b5..12ec7262906 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -620,6 +620,7 @@ static int preprocess_include(char *maindata, const int maindata_len) int newlen = 0; comment = 0; a = maindata_len; + bool skip_until_closing_brace = false; while (a--) { if (cp[0] == '/' && cp[1] == '*') { @@ -646,6 +647,17 @@ static int preprocess_include(char *maindata, const int maindata_len) a -= 13; cp += 13; } + else if (match_identifier(cp, "DNA_DEFINE_CXX_METHODS")) { + /* single values are skipped already, so decrement 1 less */ + a -= 21; + cp += 21; + skip_until_closing_brace = true; + } + else if (skip_until_closing_brace) { + if (cp[0] == ')') { + skip_until_closing_brace = false; + } + } else { md[0] = cp[0]; md++; diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index 4e3a4aae727..9980545c19d 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -236,6 +236,10 @@ if(WITH_IMAGE_HDR) add_definitions(-DWITH_HDR) endif() +if(WITH_IMAGE_WEBP) + add_definitions(-DWITH_WEBP) +endif() + if(WITH_AUDASPACE) add_definitions(-DWITH_AUDASPACE) diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index a9725da7841..82d90a5c54b 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -137,7 +137,11 @@ const struct IDFilterEnumPropertyItem rna_enum_id_type_filter_items[] = { ICON_OUTLINER_COLLECTION, "Collections", "Show Collection data-blocks"}, - {FILTER_ID_CV, "filter_hair", ICON_CURVES_DATA, "Hairs", "Show/hide Hair data-blocks"}, + {FILTER_ID_CV, + "filter_curves", + ICON_CURVES_DATA, + "Hair Curves", + "Show/hide Curves data-blocks"}, {FILTER_ID_IM, "filter_image", ICON_IMAGE_DATA, "Images", "Show Image data-blocks"}, {FILTER_ID_LA, "filter_light", ICON_LIGHT_DATA, "Lights", "Show Light data-blocks"}, {FILTER_ID_LP, diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index c86a852b0ea..b2b6bdbcffc 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -1355,7 +1355,8 @@ static void rna_def_gpencil_options(BlenderRNA *brna) /* Smoothing factor for new strokes */ prop = RNA_def_property(srna, "pen_smooth_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "draw_smoothfac"); - RNA_def_property_range(prop, 0.0, 2.0f); + RNA_def_property_range(prop, 0.0, 2.0); + RNA_def_property_ui_range(prop, 0.0, 1.0, 10, 3); RNA_def_property_ui_text( prop, "Smooth", @@ -1366,7 +1367,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) /* Iterations of the Smoothing factor */ prop = RNA_def_property(srna, "pen_smooth_steps", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "draw_smoothlvl"); - RNA_def_property_range(prop, 1, 3); + RNA_def_property_range(prop, 0, 100); RNA_def_property_ui_text(prop, "Iterations", "Number of times to smooth newly created strokes"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c index 33c0b29f6d0..81103f4fe49 100644 --- a/source/blender/makesrna/intern/rna_gpencil_modifier.c +++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c @@ -79,6 +79,11 @@ const EnumPropertyItem rna_enum_object_greasepencil_modifier_type_items[] = { ICON_MOD_DASH, "Dot Dash", "Generate dot-dash styled strokes"}, + {eGpencilModifierType_Envelope, + "GP_ENVELOPE", + ICON_MOD_SKIN, + "Envelope", + "Create an envelope shape"}, {eGpencilModifierType_Length, "GP_LENGTH", ICON_MOD_LENGTH, @@ -208,6 +213,25 @@ static const EnumPropertyItem gpencil_length_mode_items[] = { {GP_LENGTH_ABSOLUTE, "ABSOLUTE", 0, "Absolute", "Length in geometry space"}, {0, NULL, 0, NULL, NULL}, }; + +static const EnumPropertyItem gpencil_envelope_mode_items[] = { + {GP_ENVELOPE_DEFORM, + "DEFORM", + 0, + "Deform", + "Deform the stroke to best match the envelope shape"}, + {GP_ENVELOPE_SEGMENTS, + "SEGMENTS", + 0, + "Segments", + "Add segments to create the envelope. Keep the original stroke"}, + {GP_ENVELOPE_FILLS, + "FILLS", + 0, + "Fills", + "Add fill segments to create the envelope. Don't keep the original stroke"}, + {0, NULL, 0, NULL, NULL}, +}; #endif #ifdef RNA_RUNTIME @@ -279,6 +303,8 @@ static StructRNA *rna_GpencilModifier_refine(struct PointerRNA *ptr) return &RNA_LineartGpencilModifier; case eGpencilModifierType_Dash: return &RNA_DashGpencilModifierData; + case eGpencilModifierType_Envelope: + return &RNA_EnvelopeGpencilModifier; /* Default */ case eGpencilModifierType_None: case NUM_GREASEPENCIL_MODIFIER_TYPES: @@ -355,6 +381,7 @@ RNA_GP_MOD_VGROUP_NAME_SET(WeightAngle, target_vgname); RNA_GP_MOD_VGROUP_NAME_SET(WeightAngle, vgname); RNA_GP_MOD_VGROUP_NAME_SET(Lineart, vgname); RNA_GP_MOD_VGROUP_NAME_SET(Shrinkwrap, vgname); +RNA_GP_MOD_VGROUP_NAME_SET(Envelope, vgname); # undef RNA_GP_MOD_VGROUP_NAME_SET @@ -775,6 +802,16 @@ static void rna_ShrinkwrapGpencilModifier_face_cull_set(struct PointerRNA *ptr, swm->shrink_opts = (swm->shrink_opts & ~MOD_SHRINKWRAP_CULL_TARGET_MASK) | value; } +static void rna_EnvelopeGpencilModifier_material_set(PointerRNA *ptr, + PointerRNA value, + struct ReportList *reports) +{ + EnvelopeGpencilModifierData *emd = (EnvelopeGpencilModifierData *)ptr->data; + Material **ma_target = &emd->material; + + rna_GpencilModifier_material_set(ptr, value, ma_target, reports); +} + #else static void rna_def_modifier_gpencilnoise(BlenderRNA *brna) @@ -989,11 +1026,16 @@ static void rna_def_modifier_gpencilsmooth(BlenderRNA *brna) prop = RNA_def_property(srna, "step", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "step"); - RNA_def_property_range(prop, 1, 10); + RNA_def_property_range(prop, 1, 1000); RNA_def_property_ui_text( prop, "Step", "Number of times to apply smooth (high numbers can reduce fps)"); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + prop = RNA_def_property(srna, "use_keep_shape", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SMOOTH_KEEP_SHAPE); + RNA_def_property_ui_text(prop, "Keep Shape", "Smooth the details, but keep the overall shape"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + prop = RNA_def_property(srna, "invert_layers", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SMOOTH_INVERT_LAYER); RNA_def_property_ui_text(prop, "Inverse Layers", "Inverse filter"); @@ -3676,7 +3718,7 @@ static void rna_def_modifier_gpencildash(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); prop = RNA_def_property(srna, "gap", PROP_INT, PROP_NONE); - RNA_def_property_range(prop, 1, INT16_MAX); + RNA_def_property_range(prop, 0, INT16_MAX); RNA_def_property_ui_text(prop, "Gap", "The number of points skipped after this segment"); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); @@ -3701,6 +3743,11 @@ static void rna_def_modifier_gpencildash(BlenderRNA *brna) "Use this index on generated segment. -1 means using the existing material"); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + prop = RNA_def_property(srna, "use_cyclic", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DASH_USE_CYCLIC); + RNA_def_property_ui_text(prop, "Use Cyclic", "Enable cyclic on individual stroke dashes"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + srna = RNA_def_struct(brna, "DashGpencilModifierData", "GpencilModifier"); RNA_def_struct_ui_text(srna, "Dash Modifier", "Create dot-dash effect for strokes"); RNA_def_struct_sdna(srna, "DashGpencilModifierData"); @@ -3752,17 +3799,17 @@ static void rna_def_modifier_gpencildash(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); prop = RNA_def_property(srna, "invert_layers", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LENGTH_INVERT_LAYER); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DASH_INVERT_LAYER); RNA_def_property_ui_text(prop, "Inverse Layers", "Inverse filter"); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); prop = RNA_def_property(srna, "invert_materials", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LENGTH_INVERT_MATERIAL); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DASH_INVERT_MATERIAL); RNA_def_property_ui_text(prop, "Inverse Materials", "Inverse filter"); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); prop = RNA_def_property(srna, "invert_material_pass", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LENGTH_INVERT_PASS); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DASH_INVERT_PASS); RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter"); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); @@ -3773,7 +3820,7 @@ static void rna_def_modifier_gpencildash(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); prop = RNA_def_property(srna, "invert_layer_pass", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LENGTH_INVERT_LAYERPASS); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DASH_INVERT_LAYERPASS); RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter"); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); @@ -3968,6 +4015,112 @@ static void rna_def_modifier_gpencilshrinkwrap(BlenderRNA *brna) RNA_define_lib_overridable(false); } +static void rna_def_modifier_gpencilenvelope(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "EnvelopeGpencilModifier", "GpencilModifier"); + RNA_def_struct_ui_text(srna, "Envelope Modifier", "Envelope stroke effect modifier"); + RNA_def_struct_sdna(srna, "EnvelopeGpencilModifierData"); + RNA_def_struct_ui_icon(srna, ICON_MOD_SKIN); + + RNA_define_lib_overridable(true); + + prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "layername"); + RNA_def_property_ui_text(prop, "Layer", "Layer name"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "material", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_pointer_funcs(prop, + NULL, + "rna_EnvelopeGpencilModifier_material_set", + NULL, + "rna_GpencilModifier_material_poll"); + RNA_def_property_ui_text(prop, "Material", "Material used for filtering effect"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "vgname"); + RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name for modulating the deform"); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_EnvelopeGpencilModifier_vgname_set"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "pass_index"); + RNA_def_property_range(prop, 0, 100); + RNA_def_property_ui_text(prop, "Pass", "Pass index"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "spread", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "spread"); + RNA_def_property_range(prop, 1, INT_MAX); + RNA_def_property_ui_text( + prop, "Spread Length", "The number of points to skip to create straight segments"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "mode"); + RNA_def_property_enum_items(prop, gpencil_envelope_mode_items); + RNA_def_property_ui_text(prop, "Mode", "Algorithm to use for generating the envelope"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "mat_nr", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "mat_nr"); + RNA_def_property_range(prop, -1, INT16_MAX); + RNA_def_property_ui_text(prop, "Material Index", "The material to use for the new strokes"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "thickness", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "thickness"); + RNA_def_property_range(prop, 0, FLT_MAX); + RNA_def_property_ui_range(prop, 0, 1, 10, 3); + RNA_def_property_ui_text(prop, "Thickness", "Multiplier for the thickness of the new strokes"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "strength"); + RNA_def_property_range(prop, 0, FLT_MAX); + RNA_def_property_ui_range(prop, 0, 1, 10, 3); + RNA_def_property_ui_text(prop, "Strength", "Multiplier for the strength of the new strokes"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_layers", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_ENVELOPE_INVERT_LAYER); + RNA_def_property_ui_text(prop, "Inverse Layers", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_materials", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_ENVELOPE_INVERT_MATERIAL); + RNA_def_property_ui_text(prop, "Inverse Materials", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_material_pass", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_ENVELOPE_INVERT_PASS); + RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_vertex", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_ENVELOPE_INVERT_VGROUP); + RNA_def_property_ui_text(prop, "Inverse VertexGroup", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "layer_pass", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "layer_pass"); + RNA_def_property_range(prop, 0, 100); + RNA_def_property_ui_text(prop, "Pass", "Layer pass index"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_layer_pass", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_ENVELOPE_INVERT_LAYERPASS); + RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + RNA_define_lib_overridable(false); +} + void RNA_def_greasepencil_modifier(BlenderRNA *brna) { StructRNA *srna; @@ -4058,6 +4211,7 @@ void RNA_def_greasepencil_modifier(BlenderRNA *brna) rna_def_modifier_gpencillength(brna); rna_def_modifier_gpencildash(brna); rna_def_modifier_gpencilshrinkwrap(brna); + rna_def_modifier_gpencilenvelope(brna); } #endif diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c index 55d365f9827..0b188b2b3db 100644 --- a/source/blender/makesrna/intern/rna_image_api.c +++ b/source/blender/makesrna/intern/rna_image_api.c @@ -102,14 +102,14 @@ static void rna_Image_save(Image *image, Main *bmain, bContext *C, ReportList *r ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, &lock); if (ibuf) { - char filename[FILE_MAX]; - BLI_strncpy(filename, image->filepath, sizeof(filename)); - BLI_path_abs(filename, ID_BLEND_PATH(bmain, &image->id)); + char filepath[FILE_MAX]; + BLI_strncpy(filepath, image->filepath, sizeof(filepath)); + BLI_path_abs(filepath, ID_BLEND_PATH(bmain, &image->id)); /* NOTE: we purposefully ignore packed files here, * developers need to explicitly write them via 'packed_files' */ - if (IMB_saveiff(ibuf, filename, ibuf->flags)) { + if (IMB_saveiff(ibuf, filepath, ibuf->flags)) { image->type = IMA_TYPE_IMAGE; if (image->source == IMA_SRC_GENERATED) { diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 0bea5172d89..bd5960ce7d8 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -688,7 +688,7 @@ static void rna_UVProject_projectors_begin(CollectionPropertyIterator *iter, Poi { UVProjectModifierData *uvp = (UVProjectModifierData *)ptr->data; rna_iterator_array_begin( - iter, (void *)uvp->projectors, sizeof(Object *), uvp->num_projectors, 0, NULL); + iter, (void *)uvp->projectors, sizeof(Object *), uvp->projectors_num, 0, NULL); } static StructRNA *rna_Modifier_refine(struct PointerRNA *ptr) @@ -950,15 +950,15 @@ static int rna_HookModifier_vertex_indices_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION]) { HookModifierData *hmd = ptr->data; - int totindex = hmd->indexar ? hmd->totindex : 0; - return (length[0] = totindex); + int indexar_num = hmd->indexar ? hmd->indexar_num : 0; + return (length[0] = indexar_num); } static void rna_HookModifier_vertex_indices_get(PointerRNA *ptr, int *values) { HookModifierData *hmd = ptr->data; if (hmd->indexar != NULL) { - memcpy(values, hmd->indexar, sizeof(int) * hmd->totindex); + memcpy(values, hmd->indexar, sizeof(int) * hmd->indexar_num); } } @@ -969,7 +969,7 @@ static void rna_HookModifier_vertex_indices_set(HookModifierData *hmd, { if (indices_len == 0) { MEM_SAFE_FREE(hmd->indexar); - hmd->totindex = 0; + hmd->indexar_num = 0; } else { /* Reject negative indices. */ @@ -999,7 +999,7 @@ static void rna_HookModifier_vertex_indices_set(HookModifierData *hmd, /* Success - save the new array. */ MEM_SAFE_FREE(hmd->indexar); hmd->indexar = buffer; - hmd->totindex = indices_len; + hmd->indexar_num = indices_len; } } @@ -1075,7 +1075,7 @@ static void rna_MultiresModifier_filepath_get(PointerRNA *ptr, char *value) Object *ob = (Object *)ptr->owner_id; CustomDataExternal *external = ((Mesh *)ob->data)->ldata.external; - BLI_strncpy(value, (external) ? external->filename : "", sizeof(external->filename)); + BLI_strncpy(value, (external) ? external->filepath : "", sizeof(external->filepath)); } static void rna_MultiresModifier_filepath_set(PointerRNA *ptr, const char *value) @@ -1083,8 +1083,8 @@ static void rna_MultiresModifier_filepath_set(PointerRNA *ptr, const char *value Object *ob = (Object *)ptr->owner_id; CustomDataExternal *external = ((Mesh *)ob->data)->ldata.external; - if (external && !STREQ(external->filename, value)) { - BLI_strncpy(external->filename, value, sizeof(external->filename)); + if (external && !STREQ(external->filepath, value)) { + BLI_strncpy(external->filepath, value, sizeof(external->filepath)); multires_force_external_reload(ob); } } @@ -1094,7 +1094,7 @@ static int rna_MultiresModifier_filepath_length(PointerRNA *ptr) Object *ob = (Object *)ptr->owner_id; CustomDataExternal *external = ((Mesh *)ob->data)->ldata.external; - return strlen((external) ? external->filename : ""); + return strlen((external) ? external->filepath : ""); } static int rna_ShrinkwrapModifier_face_cull_get(PointerRNA *ptr) @@ -1149,8 +1149,8 @@ static void rna_UVProjectModifier_num_projectors_set(PointerRNA *ptr, int value) UVProjectModifierData *md = (UVProjectModifierData *)ptr->data; int a; - md->num_projectors = CLAMPIS(value, 1, MOD_UVPROJECT_MAXPROJECTORS); - for (a = md->num_projectors; a < MOD_UVPROJECT_MAXPROJECTORS; a++) { + md->projectors_num = CLAMPIS(value, 1, MOD_UVPROJECT_MAXPROJECTORS); + for (a = md->projectors_num; a < MOD_UVPROJECT_MAXPROJECTORS; a++) { md->projectors[a] = NULL; } } @@ -3133,7 +3133,7 @@ static void rna_def_modifier_uvproject(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop = RNA_def_property(srna, "projector_count", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "num_projectors"); + RNA_def_property_int_sdna(prop, NULL, "projectors_num"); RNA_def_property_ui_text(prop, "Number of Projectors", "Number of projectors to use"); RNA_def_property_int_funcs(prop, NULL, "rna_UVProjectModifier_num_projectors_set", NULL); RNA_def_property_range(prop, 1, MOD_UVPROJECT_MAXPROJECTORS); @@ -4110,7 +4110,7 @@ static void rna_def_modifier_bevel(BlenderRNA *brna) prop = RNA_def_property(srna, "segments", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "res"); - RNA_def_property_range(prop, 1, 100); + RNA_def_property_range(prop, 1, 1000); RNA_def_property_ui_text(prop, "Segments", "Number of segments for round edges/verts"); RNA_def_property_update(prop, 0, "rna_BevelModifier_update_segments"); diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 2770255802d..03f800d14d1 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -3139,15 +3139,19 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Particle_redo"); /* children */ + + /* NOTE(@campbellbarton): name is not following conventions: `nbr`. + * Could be changed next major version. */ prop = RNA_def_property(srna, "child_nbr", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "child_nbr"); /* Optional if prop names are the same. */ + RNA_def_property_int_sdna( + prop, NULL, "child_percent"); /* Optional if prop names are the same. */ RNA_def_property_range(prop, 0, 100000); RNA_def_property_ui_range(prop, 0, 1000, 1, -1); RNA_def_property_ui_text(prop, "Children Per Parent", "Number of children per parent"); RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop = RNA_def_property(srna, "rendered_child_count", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "ren_child_nbr"); + RNA_def_property_int_sdna(prop, NULL, "child_render_percent"); RNA_def_property_range(prop, 0, 100000); RNA_def_property_ui_range(prop, 0, 10000, 1, -1); RNA_def_property_ui_text( diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 9400e34d193..abaee9ddfc3 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -330,6 +330,13 @@ const EnumPropertyItem rna_enum_curve_fit_method_items[] = { # define R_IMF_ENUM_TIFF #endif +#ifdef WITH_WEBP +# define R_IMF_ENUM_WEBP \ + {R_IMF_IMTYPE_WEBP, "WEBP", ICON_FILE_IMAGE, "WebP", "Output image in WebP format"}, +#else +# define R_IMF_ENUM_WEBP +#endif + #define IMAGE_TYPE_ITEMS_IMAGE_ONLY \ R_IMF_ENUM_BMP \ /* DDS save not supported yet R_IMF_ENUM_DDS */ \ @@ -340,7 +347,7 @@ const EnumPropertyItem rna_enum_curve_fit_method_items[] = { R_IMF_ENUM_TAGA \ R_IMF_ENUM_TAGA_RAW{0, "", 0, " ", NULL}, \ R_IMF_ENUM_CINEON R_IMF_ENUM_DPX R_IMF_ENUM_EXR_MULTILAYER R_IMF_ENUM_EXR R_IMF_ENUM_HDR \ - R_IMF_ENUM_TIFF + R_IMF_ENUM_TIFF R_IMF_ENUM_WEBP #ifdef RNA_RUNTIME static const EnumPropertyItem image_only_type_items[] = { @@ -6213,7 +6220,8 @@ static void rna_def_scene_render_data(BlenderRNA *brna) prop = RNA_def_property(srna, "hair_subdiv", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 0, 3); - RNA_def_property_ui_text(prop, "Additional Subdivision", "Additional subdivision along the hair"); + RNA_def_property_ui_text( + prop, "Additional Subdivision", "Additional subdivision along the hair"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); /* Performance */ diff --git a/source/blender/makesrna/intern/rna_shader_fx.c b/source/blender/makesrna/intern/rna_shader_fx.c index ae7772fcb62..cefa445740d 100644 --- a/source/blender/makesrna/intern/rna_shader_fx.c +++ b/source/blender/makesrna/intern/rna_shader_fx.c @@ -524,7 +524,6 @@ static void rna_def_shader_fx_glow(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "glow_color[3]"); RNA_def_property_range(prop, 0.0, 1.0f); RNA_def_property_ui_text(prop, "Opacity", "Effect Opacity"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update"); prop = RNA_def_property(srna, "select_color", PROP_FLOAT, PROP_COLOR); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 2344aa42838..3839b3ba6a4 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -3773,13 +3773,6 @@ static void rna_def_space_outliner(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Filter by Type", "Data-block type to show"); RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_ID); - prop = RNA_def_property(srna, "use_filter_lib_override", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "filter", SO_FILTER_NO_LIB_OVERRIDE); - RNA_def_property_ui_text(prop, - "Show Library Overrides", - "For libraries with overrides created, show the overridden values"); - RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL); - prop = RNA_def_property(srna, "use_filter_lib_override_system", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "filter", SO_FILTER_SHOW_SYSTEM_OVERRIDES); RNA_def_property_ui_text( diff --git a/source/blender/makesrna/intern/rna_text.c b/source/blender/makesrna/intern/rna_text.c index 3d2df5b7411..e9c67d71ceb 100644 --- a/source/blender/makesrna/intern/rna_text.c +++ b/source/blender/makesrna/intern/rna_text.c @@ -25,7 +25,7 @@ #ifdef RNA_RUNTIME -static void rna_Text_filename_get(PointerRNA *ptr, char *value) +static void rna_Text_filepath_get(PointerRNA *ptr, char *value) { Text *text = (Text *)ptr->data; @@ -37,13 +37,13 @@ static void rna_Text_filename_get(PointerRNA *ptr, char *value) } } -static int rna_Text_filename_length(PointerRNA *ptr) +static int rna_Text_filepath_length(PointerRNA *ptr) { Text *text = (Text *)ptr->data; return (text->filepath) ? strlen(text->filepath) : 0; } -static void rna_Text_filename_set(PointerRNA *ptr, const char *value) +static void rna_Text_filepath_set(PointerRNA *ptr, const char *value) { Text *text = (Text *)ptr->data; @@ -204,7 +204,7 @@ static void rna_def_text(BlenderRNA *brna) prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_NONE); RNA_def_property_string_funcs( - prop, "rna_Text_filename_get", "rna_Text_filename_length", "rna_Text_filename_set"); + prop, "rna_Text_filepath_get", "rna_Text_filepath_length", "rna_Text_filepath_set"); RNA_def_property_ui_text(prop, "File Path", "Filename of the text file"); prop = RNA_def_property(srna, "is_dirty", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index a0d53701e26..06a5df5ad41 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -5278,10 +5278,10 @@ static void rna_def_userdef_edit(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Duplicate GPencil", "Causes grease pencil data to be duplicated with the object"); - prop = RNA_def_property(srna, "use_duplicate_hair", PROP_BOOLEAN, PROP_NONE); + prop = RNA_def_property(srna, "use_duplicate_curves", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "dupflag", USER_DUP_CURVES); RNA_def_property_ui_text( - prop, "Duplicate Hair", "Causes hair data to be duplicated with the object"); + prop, "Duplicate Curves", "Causes curves data to be duplicated with the object"); prop = RNA_def_property(srna, "use_duplicate_pointcloud", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "dupflag", USER_DUP_POINTCLOUD); @@ -6435,6 +6435,12 @@ static void rna_def_userdef_experimental(BlenderRNA *brna) "Named Attribute Nodes", "Enable named attribute nodes in the geometry nodes add menu"); + prop = RNA_def_property(srna, "use_select_nearest_on_first_click", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "use_select_nearest_on_first_click", 1); + RNA_def_property_ui_text(prop, + "Object Select Nearest on First Click", + "When enabled, always select the front-most object on the first click"); + prop = RNA_def_property(srna, "enable_eevee_next", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "enable_eevee_next", 1); RNA_def_property_ui_text(prop, "EEVEE Next", "Enable the new EEVEE codebase, requires restart"); diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c index 5d37ac79fa6..f6e8a26f0e1 100644 --- a/source/blender/modifiers/intern/MOD_armature.c +++ b/source/blender/modifiers/intern/MOD_armature.c @@ -132,7 +132,7 @@ static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { ArmatureModifierData *amd = (ArmatureModifierData *)md; @@ -142,7 +142,7 @@ static void deformVerts(ModifierData *md, ctx->object, vertexCos, NULL, - numVerts, + verts_num, amd->deformflag, amd->vert_coords_prev, amd->defgrp_name, @@ -157,10 +157,10 @@ static void deformVertsEM(ModifierData *md, struct BMEditMesh *em, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { if (mesh != NULL) { - deformVerts(md, ctx, mesh, vertexCos, numVerts); + deformVerts(md, ctx, mesh, vertexCos, verts_num); return; } @@ -172,7 +172,7 @@ static void deformVertsEM(ModifierData *md, ctx->object, vertexCos, NULL, - numVerts, + verts_num, amd->deformflag, amd->vert_coords_prev, amd->defgrp_name, @@ -188,7 +188,7 @@ static void deformMatricesEM(ModifierData *md, Mesh *UNUSED(mesh), float (*vertexCos)[3], float (*defMats)[3][3], - int numVerts) + int verts_num) { ArmatureModifierData *amd = (ArmatureModifierData *)md; @@ -196,7 +196,7 @@ static void deformMatricesEM(ModifierData *md, ctx->object, vertexCos, defMats, - numVerts, + verts_num, amd->deformflag, NULL, amd->defgrp_name, @@ -208,16 +208,17 @@ static void deformMatrices(ModifierData *md, Mesh *mesh, float (*vertexCos)[3], float (*defMats)[3][3], - int numVerts) + int verts_num) { ArmatureModifierData *amd = (ArmatureModifierData *)md; - Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false); + Mesh *mesh_src = MOD_deform_mesh_eval_get( + ctx->object, NULL, mesh, NULL, verts_num, false, false); BKE_armature_deform_coords_with_mesh(amd->object, ctx->object, vertexCos, defMats, - numVerts, + verts_num, amd->deformflag, NULL, amd->defgrp_name, diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index b237f952287..758858c8b1d 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -139,17 +139,17 @@ static void svert_from_mvert(SortVertsElem *sv, /** * Take as inputs two sets of verts, to be processed for detection of doubles and mapping. - * Each set of verts is defined by its start within mverts array and its num_verts; + * Each set of verts is defined by its start within mverts array and its verts_num; * It builds a mapping for all vertices within source, * to vertices within target, or -1 if no double found. - * The int doubles_map[num_verts_source] array must have been allocated by caller. + * The `int doubles_map[verts_source_num]` array must have been allocated by caller. */ static void dm_mvert_map_doubles(int *doubles_map, const MVert *mverts, const int target_start, - const int target_num_verts, + const int target_verts_num, const int source_start, - const int source_num_verts, + const int source_verts_num, const float dist) { const float dist3 = ((float)M_SQRT3 + 0.00005f) * dist; /* Just above sqrt(3) */ @@ -158,12 +158,12 @@ static void dm_mvert_map_doubles(int *doubles_map, SortVertsElem *sve_source, *sve_target, *sve_target_low_bound; bool target_scan_completed; - target_end = target_start + target_num_verts; - source_end = source_start + source_num_verts; + target_end = target_start + target_verts_num; + source_end = source_start + source_verts_num; /* build array of MVerts to be tested for merging */ - sorted_verts_target = MEM_malloc_arrayN(target_num_verts, sizeof(SortVertsElem), __func__); - sorted_verts_source = MEM_malloc_arrayN(source_num_verts, sizeof(SortVertsElem), __func__); + sorted_verts_target = MEM_malloc_arrayN(target_verts_num, sizeof(SortVertsElem), __func__); + sorted_verts_source = MEM_malloc_arrayN(source_verts_num, sizeof(SortVertsElem), __func__); /* Copy target vertices index and cos into SortVertsElem array */ svert_from_mvert(sorted_verts_target, mverts + target_start, target_start, target_end); @@ -172,8 +172,8 @@ static void dm_mvert_map_doubles(int *doubles_map, svert_from_mvert(sorted_verts_source, mverts + source_start, source_start, source_end); /* sort arrays according to sum of vertex coordinates (sumco) */ - qsort(sorted_verts_target, target_num_verts, sizeof(SortVertsElem), svert_sum_cmp); - qsort(sorted_verts_source, source_num_verts, sizeof(SortVertsElem), svert_sum_cmp); + qsort(sorted_verts_target, target_verts_num, sizeof(SortVertsElem), svert_sum_cmp); + qsort(sorted_verts_source, source_verts_num, sizeof(SortVertsElem), svert_sum_cmp); sve_target_low_bound = sorted_verts_target; i_target_low_bound = 0; @@ -181,7 +181,7 @@ static void dm_mvert_map_doubles(int *doubles_map, /* Scan source vertices, in #SortVertsElem sorted array, * all the while maintaining the lower bound of possible doubles in target vertices. */ - for (i_source = 0, sve_source = sorted_verts_source; i_source < source_num_verts; + for (i_source = 0, sve_source = sorted_verts_source; i_source < source_verts_num; i_source++, sve_source++) { int best_target_vertex = -1; float best_dist_sq = dist * dist; @@ -202,13 +202,13 @@ static void dm_mvert_map_doubles(int *doubles_map, /* Skip all target vertices that are more than dist3 lower in terms of sumco */ /* and advance the overall lower bound, applicable to all remaining vertices as well. */ - while ((i_target_low_bound < target_num_verts) && + while ((i_target_low_bound < target_verts_num) && (sve_target_low_bound->sum_co < sve_source_sumco - dist3)) { i_target_low_bound++; sve_target_low_bound++; } /* If end of target list reached, then no more possible doubles */ - if (i_target_low_bound >= target_num_verts) { + if (i_target_low_bound >= target_verts_num) { doubles_map[sve_source->vertex_num] = -1; target_scan_completed = true; continue; @@ -221,7 +221,7 @@ static void dm_mvert_map_doubles(int *doubles_map, /* i_target will scan vertices in the * [v_source_sumco - dist3; v_source_sumco + dist3] range */ - while ((i_target < target_num_verts) && (sve_target->sum_co <= sve_source_sumco + dist3)) { + while ((i_target < target_verts_num) && (sve_target->sum_co <= sve_source_sumco + dist3)) { /* Testing distance for candidate double in target */ /* v_target is within dist3 of v_source in terms of sumco; check real distance */ float dist_sq; @@ -478,7 +478,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, } /* About 67 million vertices max seems a decent limit for now. */ - const size_t max_num_vertices = 1 << 26; + const size_t max_vertices_num = 1 << 26; /* calculate the maximum number of copies which will fit within the * prescribed length */ @@ -496,7 +496,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, * vertices. */ if (((size_t)count * (size_t)chunk_nverts + (size_t)start_cap_nverts + - (size_t)end_cap_nverts) > max_num_vertices) { + (size_t)end_cap_nverts) > max_vertices_num) { count = 1; offset_is_too_small = true; } @@ -518,7 +518,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, * vertices. */ else if (((size_t)count * (size_t)chunk_nverts + (size_t)start_cap_nverts + - (size_t)end_cap_nverts) > max_num_vertices) { + (size_t)end_cap_nverts) > max_vertices_num) { count = 1; BKE_modifier_set_error(ctx->object, &amd->modifier, diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c index cd77abfca50..d7baea7887d 100644 --- a/source/blender/modifiers/intern/MOD_build.c +++ b/source/blender/modifiers/intern/MOD_build.c @@ -58,7 +58,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct Mesh *result; BuildModifierData *bmd = (BuildModifierData *)md; int i, j, k; - int numFaces_dst, numEdges_dst, numLoops_dst = 0; + int faces_dst_num, edges_dst_num, loops_dst_num = 0; int *vertMap, *edgeMap, *faceMap; float frac; MPoly *mpoly_dst; @@ -71,21 +71,21 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct /* maps edge indices in old mesh to indices in new mesh */ GHash *edgeHash2 = BLI_ghash_int_new("build ed apply gh"); - const int numVert_src = mesh->totvert; - const int numEdge_src = mesh->totedge; - const int numPoly_src = mesh->totpoly; + const int vert_src_num = mesh->totvert; + const int edge_src_num = mesh->totedge; + const int poly_src_num = mesh->totpoly; MPoly *mpoly_src = mesh->mpoly; MLoop *mloop_src = mesh->mloop; MEdge *medge_src = mesh->medge; MVert *mvert_src = mesh->mvert; - vertMap = MEM_malloc_arrayN(numVert_src, sizeof(*vertMap), "build modifier vertMap"); - edgeMap = MEM_malloc_arrayN(numEdge_src, sizeof(*edgeMap), "build modifier edgeMap"); - faceMap = MEM_malloc_arrayN(numPoly_src, sizeof(*faceMap), "build modifier faceMap"); + vertMap = MEM_malloc_arrayN(vert_src_num, sizeof(*vertMap), "build modifier vertMap"); + edgeMap = MEM_malloc_arrayN(edge_src_num, sizeof(*edgeMap), "build modifier edgeMap"); + faceMap = MEM_malloc_arrayN(poly_src_num, sizeof(*faceMap), "build modifier faceMap"); - range_vn_i(vertMap, numVert_src, 0); - range_vn_i(edgeMap, numEdge_src, 0); - range_vn_i(faceMap, numPoly_src, 0); + range_vn_i(vertMap, vert_src_num, 0); + range_vn_i(edgeMap, edge_src_num, 0); + range_vn_i(faceMap, poly_src_num, 0); struct Scene *scene = DEG_get_input_scene(ctx->depsgraph); frac = (BKE_scene_ctime_get(scene) - bmd->start) / bmd->length; @@ -94,17 +94,17 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct frac = 1.0f - frac; } - numFaces_dst = numPoly_src * frac; - numEdges_dst = numEdge_src * frac; + faces_dst_num = poly_src_num * frac; + edges_dst_num = edge_src_num * frac; /* if there's at least one face, build based on faces */ - if (numFaces_dst) { + if (faces_dst_num) { MPoly *mpoly, *mp; MLoop *ml, *mloop; uintptr_t hash_num, hash_num_alt; if (bmd->flag & MOD_BUILD_FLAG_RANDOMIZE) { - BLI_array_randomize(faceMap, sizeof(*faceMap), numPoly_src, bmd->seed); + BLI_array_randomize(faceMap, sizeof(*faceMap), poly_src_num, bmd->seed); } /* get the set of all vert indices that will be in the final mesh, @@ -113,7 +113,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct mpoly = mpoly_src; mloop = mloop_src; hash_num = 0; - for (i = 0; i < numFaces_dst; i++) { + for (i = 0; i < faces_dst_num; i++) { mp = mpoly + faceMap[i]; ml = mloop + mp->loopstart; @@ -125,7 +125,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct } } - numLoops_dst += mp->totloop; + loops_dst_num += mp->totloop; } BLI_assert(hash_num == BLI_ghash_len(vertHash)); @@ -134,7 +134,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct */ hash_num = 0; hash_num_alt = 0; - for (i = 0; i < numEdge_src; i++, hash_num_alt++) { + for (i = 0; i < edge_src_num; i++, hash_num_alt++) { MEdge *me = medge_src + i; if (BLI_ghash_haskey(vertHash, POINTER_FROM_INT(me->v1)) && @@ -146,12 +146,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct } BLI_assert(hash_num == BLI_ghash_len(edgeHash)); } - else if (numEdges_dst) { + else if (edges_dst_num) { MEdge *medge, *me; uintptr_t hash_num; if (bmd->flag & MOD_BUILD_FLAG_RANDOMIZE) { - BLI_array_randomize(edgeMap, sizeof(*edgeMap), numEdge_src, bmd->seed); + BLI_array_randomize(edgeMap, sizeof(*edgeMap), edge_src_num, bmd->seed); } /* get the set of all vert indices that will be in the final mesh, @@ -160,7 +160,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct medge = medge_src; hash_num = 0; BLI_assert(hash_num == BLI_ghash_len(vertHash)); - for (i = 0; i < numEdges_dst; i++) { + for (i = 0; i < edges_dst_num; i++) { void **val_p; me = medge + edgeMap[i]; @@ -176,7 +176,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct BLI_assert(hash_num == BLI_ghash_len(vertHash)); /* get the set of edges that will be in the new mesh */ - for (i = 0; i < numEdges_dst; i++) { + for (i = 0; i < edges_dst_num; i++) { j = BLI_ghash_len(edgeHash); BLI_ghash_insert(edgeHash, POINTER_FROM_INT(j), POINTER_FROM_INT(edgeMap[i])); @@ -184,23 +184,23 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct } } else { - int numVerts = numVert_src * frac; + int verts_num = vert_src_num * frac; if (bmd->flag & MOD_BUILD_FLAG_RANDOMIZE) { - BLI_array_randomize(vertMap, sizeof(*vertMap), numVert_src, bmd->seed); + BLI_array_randomize(vertMap, sizeof(*vertMap), vert_src_num, bmd->seed); } /* get the set of all vert indices that will be in the final mesh, * mapped to the new indices */ - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { BLI_ghash_insert(vertHash, POINTER_FROM_INT(vertMap[i]), POINTER_FROM_INT(i)); } } /* now we know the number of verts, edges and faces, we can create the mesh. */ result = BKE_mesh_new_nomain_from_template( - mesh, BLI_ghash_len(vertHash), BLI_ghash_len(edgeHash), 0, numLoops_dst, numFaces_dst); + mesh, BLI_ghash_len(vertHash), BLI_ghash_len(edgeHash), 0, loops_dst_num, faces_dst_num); /* copy the vertices across */ GHASH_ITER (gh_iter, vertHash) { @@ -237,7 +237,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct /* copy the faces across, remapping indices */ k = 0; - for (i = 0; i < numFaces_dst; i++) { + for (i = 0; i < faces_dst_num; i++) { MPoly *source; MPoly *dest; diff --git a/source/blender/modifiers/intern/MOD_cast.c b/source/blender/modifiers/intern/MOD_cast.c index fb395631451..3916551bc90 100644 --- a/source/blender/modifiers/intern/MOD_cast.c +++ b/source/blender/modifiers/intern/MOD_cast.c @@ -96,7 +96,7 @@ static void sphere_do(CastModifierData *cmd, Object *ob, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { MDeformVert *dvert = NULL; const bool invert_vgroup = (cmd->flag & MOD_CAST_INVERT_VGROUP) != 0; @@ -159,17 +159,17 @@ static void sphere_do(CastModifierData *cmd, } if (len <= 0) { - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { len += len_v3v3(center, vertexCos[i]); } - len /= numVerts; + len /= verts_num; if (len == 0.0f) { len = 10.0f; } } - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { float tmp_co[3]; copy_v3_v3(tmp_co, vertexCos[i]); @@ -237,7 +237,7 @@ static void cuboid_do(CastModifierData *cmd, Object *ob, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { MDeformVert *dvert = NULL; int defgrp_index; @@ -312,13 +312,13 @@ static void cuboid_do(CastModifierData *cmd, /* let the center of the ctrl_ob be part of the bound box: */ minmax_v3v3_v3(min, max, center); - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { sub_v3_v3v3(vec, vertexCos[i], center); minmax_v3v3_v3(min, max, vec); } } else { - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { minmax_v3v3_v3(min, max, vertexCos[i]); } } @@ -347,7 +347,7 @@ static void cuboid_do(CastModifierData *cmd, bb[4][2] = bb[5][2] = bb[6][2] = bb[7][2] = max[2]; /* ready to apply the effect, one vertex at a time */ - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { int octant, coord; float d[3], dmax, apex[3], fbb; float tmp_co[3]; @@ -460,21 +460,21 @@ static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { CastModifierData *cmd = (CastModifierData *)md; Mesh *mesh_src = NULL; if (ctx->object->type == OB_MESH && cmd->defgrp_name[0] != '\0') { /* mesh_src is only needed for vgroups. */ - mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false); + mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false, false); } if (cmd->type == MOD_CAST_TYPE_CUBOID) { - cuboid_do(cmd, ctx, ctx->object, mesh_src, vertexCos, numVerts); + cuboid_do(cmd, ctx, ctx->object, mesh_src, vertexCos, verts_num); } else { /* MOD_CAST_TYPE_SPHERE or MOD_CAST_TYPE_CYLINDER */ - sphere_do(cmd, ctx, ctx->object, mesh_src, vertexCos, numVerts); + sphere_do(cmd, ctx, ctx->object, mesh_src, vertexCos, verts_num); } if (!ELEM(mesh_src, NULL, mesh)) { @@ -487,17 +487,18 @@ static void deformVertsEM(ModifierData *md, struct BMEditMesh *editData, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { CastModifierData *cmd = (CastModifierData *)md; Mesh *mesh_src = NULL; if (cmd->defgrp_name[0] != '\0') { - mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false); + mesh_src = MOD_deform_mesh_eval_get( + ctx->object, editData, mesh, NULL, verts_num, false, false); } if (mesh && mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_MDATA) { - BLI_assert(mesh->totvert == numVerts); + BLI_assert(mesh->totvert == verts_num); } /* TODO(Campbell): use edit-mode data only (remove this line). */ @@ -506,10 +507,10 @@ static void deformVertsEM(ModifierData *md, } if (cmd->type == MOD_CAST_TYPE_CUBOID) { - cuboid_do(cmd, ctx, ctx->object, mesh_src, vertexCos, numVerts); + cuboid_do(cmd, ctx, ctx->object, mesh_src, vertexCos, verts_num); } else { /* MOD_CAST_TYPE_SPHERE or MOD_CAST_TYPE_CYLINDER */ - sphere_do(cmd, ctx, ctx->object, mesh_src, vertexCos, numVerts); + sphere_do(cmd, ctx, ctx->object, mesh_src, vertexCos, verts_num); } if (!ELEM(mesh_src, NULL, mesh)) { diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c index 4bc79a9dd45..6389f420588 100644 --- a/source/blender/modifiers/intern/MOD_cloth.c +++ b/source/blender/modifiers/intern/MOD_cloth.c @@ -78,7 +78,7 @@ static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { Mesh *mesh_src; ClothModifierData *clmd = (ClothModifierData *)md; @@ -94,7 +94,7 @@ static void deformVerts(ModifierData *md, } if (mesh == NULL) { - mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, NULL, NULL, numVerts, false, false); + mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, NULL, NULL, verts_num, false, false); } else { /* Not possible to use get_mesh() in this case as we'll modify its vertices @@ -118,7 +118,7 @@ static void deformVerts(ModifierData *md, &mesh_src->vdata, CD_CLOTH_ORCO, CD_CALLOC, NULL, mesh_src->totvert); } - memcpy(layerorco, kb->data, sizeof(float[3]) * numVerts); + memcpy(layerorco, kb->data, sizeof(float[3]) * verts_num); } } diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c index 33a5934d2b0..9791b046e00 100644 --- a/source/blender/modifiers/intern/MOD_collision.c +++ b/source/blender/modifiers/intern/MOD_collision.c @@ -91,7 +91,7 @@ static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { CollisionModifierData *collmd = (CollisionModifierData *)md; Mesh *mesh_src; @@ -109,7 +109,7 @@ static void deformVerts(ModifierData *md, } if (mesh == NULL) { - mesh_src = MOD_deform_mesh_eval_get(ob, NULL, NULL, NULL, numVerts, false, false); + mesh_src = MOD_deform_mesh_eval_get(ob, NULL, NULL, NULL, verts_num, false, false); } else { /* Not possible to use get_mesh() in this case as we'll modify its vertices @@ -268,9 +268,9 @@ static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md) collmd->xnew = newdataadr(fd, collmd->xnew); collmd->mfaces = newdataadr(fd, collmd->mfaces); - collmd->current_x = MEM_calloc_arrayN(collmd->numverts, sizeof(MVert), "current_x"); - collmd->current_xnew = MEM_calloc_arrayN(collmd->numverts, sizeof(MVert), "current_xnew"); - collmd->current_v = MEM_calloc_arrayN(collmd->numverts, sizeof(MVert), "current_v"); + collmd->current_x = MEM_calloc_arrayN(collmd->mvert_num, sizeof(MVert), "current_x"); + collmd->current_xnew = MEM_calloc_arrayN(collmd->mvert_num, sizeof(MVert), "current_xnew"); + collmd->current_v = MEM_calloc_arrayN(collmd->mvert_num, sizeof(MVert), "current_v"); #endif collmd->x = NULL; diff --git a/source/blender/modifiers/intern/MOD_correctivesmooth.c b/source/blender/modifiers/intern/MOD_correctivesmooth.c index b61419eb663..52162eaacc5 100644 --- a/source/blender/modifiers/intern/MOD_correctivesmooth.c +++ b/source/blender/modifiers/intern/MOD_correctivesmooth.c @@ -111,13 +111,13 @@ static void requiredDataMask(Object *UNUSED(ob), /* check individual weights for changes and cache values */ static void mesh_get_weights(MDeformVert *dvert, const int defgrp_index, - const uint numVerts, + const uint verts_num, const bool use_invert_vgroup, float *smooth_weights) { uint i; - for (i = 0; i < numVerts; i++, dvert++) { + for (i = 0; i < verts_num; i++, dvert++) { const float w = BKE_defvert_find_weight(dvert, defgrp_index); if (use_invert_vgroup == false) { @@ -170,25 +170,25 @@ static void mesh_get_boundaries(Mesh *mesh, float *smooth_weights) static void smooth_iter__simple(CorrectiveSmoothModifierData *csmd, Mesh *mesh, float (*vertexCos)[3], - uint numVerts, + uint verts_num, const float *smooth_weights, uint iterations) { const float lambda = csmd->lambda; uint i; - const uint numEdges = (uint)mesh->totedge; + const uint edges_num = (uint)mesh->totedge; const MEdge *edges = mesh->medge; float *vertex_edge_count_div; struct SmoothingData_Simple { float delta[3]; - } *smooth_data = MEM_calloc_arrayN(numVerts, sizeof(*smooth_data), __func__); + } *smooth_data = MEM_calloc_arrayN(verts_num, sizeof(*smooth_data), __func__); - vertex_edge_count_div = MEM_calloc_arrayN(numVerts, sizeof(float), __func__); + vertex_edge_count_div = MEM_calloc_arrayN(verts_num, sizeof(float), __func__); /* calculate as floats to avoid int->float conversion in #smooth_iter */ - for (i = 0; i < numEdges; i++) { + for (i = 0; i < edges_num; i++) { vertex_edge_count_div[edges[i].v1] += 1.0f; vertex_edge_count_div[edges[i].v2] += 1.0f; } @@ -196,14 +196,14 @@ static void smooth_iter__simple(CorrectiveSmoothModifierData *csmd, /* a little confusing, but we can include 'lambda' and smoothing weight * here to avoid multiplying for every iteration */ if (smooth_weights == NULL) { - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { vertex_edge_count_div[i] = lambda * (vertex_edge_count_div[i] ? (1.0f / vertex_edge_count_div[i]) : 1.0f); } } else { - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { vertex_edge_count_div[i] = smooth_weights[i] * lambda * (vertex_edge_count_div[i] ? (1.0f / vertex_edge_count_div[i]) : 1.0f); @@ -214,7 +214,7 @@ static void smooth_iter__simple(CorrectiveSmoothModifierData *csmd, /* Main Smoothing Loop */ while (iterations--) { - for (i = 0; i < numEdges; i++) { + for (i = 0; i < edges_num; i++) { struct SmoothingData_Simple *sd_v1; struct SmoothingData_Simple *sd_v2; float edge_dir[3]; @@ -228,7 +228,7 @@ static void smooth_iter__simple(CorrectiveSmoothModifierData *csmd, sub_v3_v3(sd_v2->delta, edge_dir); } - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { struct SmoothingData_Simple *sd = &smooth_data[i]; madd_v3_v3fl(vertexCos[i], sd->delta, vertex_edge_count_div[i]); /* zero for the next iteration (saves memset on entire array) */ @@ -246,12 +246,12 @@ static void smooth_iter__simple(CorrectiveSmoothModifierData *csmd, static void smooth_iter__length_weight(CorrectiveSmoothModifierData *csmd, Mesh *mesh, float (*vertexCos)[3], - uint numVerts, + uint verts_num, const float *smooth_weights, uint iterations) { const float eps = FLT_EPSILON * 10.0f; - const uint numEdges = (uint)mesh->totedge; + const uint edges_num = (uint)mesh->totedge; /* NOTE: the way this smoothing method works, its approx half as strong as the simple-smooth, * and 2.0 rarely spikes, double the value for consistent behavior. */ const float lambda = csmd->lambda * 2.0f; @@ -262,11 +262,11 @@ static void smooth_iter__length_weight(CorrectiveSmoothModifierData *csmd, struct SmoothingData_Weighted { float delta[3]; float edge_length_sum; - } *smooth_data = MEM_calloc_arrayN(numVerts, sizeof(*smooth_data), __func__); + } *smooth_data = MEM_calloc_arrayN(verts_num, sizeof(*smooth_data), __func__); /* calculate as floats to avoid int->float conversion in #smooth_iter */ - vertex_edge_count = MEM_calloc_arrayN(numVerts, sizeof(float), __func__); - for (i = 0; i < numEdges; i++) { + vertex_edge_count = MEM_calloc_arrayN(verts_num, sizeof(float), __func__); + for (i = 0; i < edges_num; i++) { vertex_edge_count[edges[i].v1] += 1.0f; vertex_edge_count[edges[i].v2] += 1.0f; } @@ -275,7 +275,7 @@ static void smooth_iter__length_weight(CorrectiveSmoothModifierData *csmd, /* Main Smoothing Loop */ while (iterations--) { - for (i = 0; i < numEdges; i++) { + for (i = 0; i < edges_num; i++) { struct SmoothingData_Weighted *sd_v1; struct SmoothingData_Weighted *sd_v2; float edge_dir[3]; @@ -299,7 +299,7 @@ static void smooth_iter__length_weight(CorrectiveSmoothModifierData *csmd, if (smooth_weights == NULL) { /* fast-path */ - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { struct SmoothingData_Weighted *sd = &smooth_data[i]; /* Divide by sum of all neighbor distances (weighted) and amount of neighbors, * (mean average). */ @@ -320,7 +320,7 @@ static void smooth_iter__length_weight(CorrectiveSmoothModifierData *csmd, } } else { - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { struct SmoothingData_Weighted *sd = &smooth_data[i]; const float div = sd->edge_length_sum * vertex_edge_count[i]; if (div > eps) { @@ -340,18 +340,18 @@ static void smooth_iter__length_weight(CorrectiveSmoothModifierData *csmd, static void smooth_iter(CorrectiveSmoothModifierData *csmd, Mesh *mesh, float (*vertexCos)[3], - uint numVerts, + uint verts_num, const float *smooth_weights, uint iterations) { switch (csmd->smooth_type) { case MOD_CORRECTIVESMOOTH_SMOOTH_LENGTH_WEIGHT: - smooth_iter__length_weight(csmd, mesh, vertexCos, numVerts, smooth_weights, iterations); + smooth_iter__length_weight(csmd, mesh, vertexCos, verts_num, smooth_weights, iterations); break; /* case MOD_CORRECTIVESMOOTH_SMOOTH_SIMPLE: */ default: - smooth_iter__simple(csmd, mesh, vertexCos, numVerts, smooth_weights, iterations); + smooth_iter__simple(csmd, mesh, vertexCos, verts_num, smooth_weights, iterations); break; } } @@ -361,23 +361,23 @@ static void smooth_verts(CorrectiveSmoothModifierData *csmd, MDeformVert *dvert, const int defgrp_index, float (*vertexCos)[3], - uint numVerts) + uint verts_num) { float *smooth_weights = NULL; if (dvert || (csmd->flag & MOD_CORRECTIVESMOOTH_PIN_BOUNDARY)) { - smooth_weights = MEM_malloc_arrayN(numVerts, sizeof(float), __func__); + smooth_weights = MEM_malloc_arrayN(verts_num, sizeof(float), __func__); if (dvert) { mesh_get_weights(dvert, defgrp_index, - numVerts, + verts_num, (csmd->flag & MOD_CORRECTIVESMOOTH_INVERT_VGROUP) != 0, smooth_weights); } else { - copy_vn_fl(smooth_weights, (int)numVerts, 1.0f); + copy_vn_fl(smooth_weights, (int)verts_num, 1.0f); } if (csmd->flag & MOD_CORRECTIVESMOOTH_PIN_BOUNDARY) { @@ -385,7 +385,7 @@ static void smooth_verts(CorrectiveSmoothModifierData *csmd, } } - smooth_iter(csmd, mesh, vertexCos, numVerts, smooth_weights, (uint)csmd->repeat); + smooth_iter(csmd, mesh, vertexCos, verts_num, smooth_weights, (uint)csmd->repeat); if (smooth_weights) { MEM_freeN(smooth_weights); @@ -522,29 +522,29 @@ static void calc_deltas(CorrectiveSmoothModifierData *csmd, MDeformVert *dvert, const int defgrp_index, const float (*rest_coords)[3], - uint numVerts) + uint verts_num) { float(*smooth_vertex_coords)[3] = MEM_dupallocN(rest_coords); float(*tangent_spaces)[3][3]; uint i; - tangent_spaces = MEM_calloc_arrayN(numVerts, sizeof(float[3][3]), __func__); + tangent_spaces = MEM_calloc_arrayN(verts_num, sizeof(float[3][3]), __func__); - if (csmd->delta_cache.totverts != numVerts) { + if (csmd->delta_cache.totverts != verts_num) { MEM_SAFE_FREE(csmd->delta_cache.deltas); } /* allocate deltas if they have not yet been allocated, otherwise we will just write over them */ if (!csmd->delta_cache.deltas) { - csmd->delta_cache.totverts = numVerts; - csmd->delta_cache.deltas = MEM_malloc_arrayN(numVerts, sizeof(float[3]), __func__); + csmd->delta_cache.totverts = verts_num; + csmd->delta_cache.deltas = MEM_malloc_arrayN(verts_num, sizeof(float[3]), __func__); } - smooth_verts(csmd, mesh, dvert, defgrp_index, smooth_vertex_coords, numVerts); + smooth_verts(csmd, mesh, dvert, defgrp_index, smooth_vertex_coords, verts_num); calc_tangent_spaces(mesh, smooth_vertex_coords, tangent_spaces); - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { float imat[3][3], delta[3]; #ifdef USE_TANGENT_CALC_INLINE @@ -567,7 +567,7 @@ static void correctivesmooth_modifier_do(ModifierData *md, Object *ob, Mesh *mesh, float (*vertexCos)[3], - uint numVerts, + uint verts_num, struct BMEditMesh *em) { CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md; @@ -591,7 +591,7 @@ static void correctivesmooth_modifier_do(ModifierData *md, if (DEG_is_active(depsgraph)) { BLI_assert(csmd->bind_coords == NULL); csmd->bind_coords = MEM_dupallocN(vertexCos); - csmd->bind_coords_num = numVerts; + csmd->bind_coords_num = verts_num; BLI_assert(csmd->bind_coords != NULL); /* Copy bound data to the original modifier. */ CorrectiveSmoothModifierData *csmd_orig = (CorrectiveSmoothModifierData *) @@ -605,7 +605,7 @@ static void correctivesmooth_modifier_do(ModifierData *md, } if (UNLIKELY(use_only_smooth)) { - smooth_verts(csmd, mesh, dvert, defgrp_index, vertexCos, numVerts); + smooth_verts(csmd, mesh, dvert, defgrp_index, vertexCos, verts_num); return; } @@ -616,9 +616,9 @@ static void correctivesmooth_modifier_do(ModifierData *md, /* If the number of verts has changed, the bind is invalid, so we do nothing */ if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) { - if (csmd->bind_coords_num != numVerts) { + if (csmd->bind_coords_num != verts_num) { BKE_modifier_set_error( - ob, md, "Bind vertex count mismatch: %u to %u", csmd->bind_coords_num, numVerts); + ob, md, "Bind vertex count mismatch: %u to %u", csmd->bind_coords_num, verts_num); goto error; } } @@ -631,16 +631,16 @@ static void correctivesmooth_modifier_do(ModifierData *md, else { uint me_numVerts = (uint)((em) ? em->bm->totvert : ((Mesh *)ob->data)->totvert); - if (me_numVerts != numVerts) { + if (me_numVerts != verts_num) { BKE_modifier_set_error( - ob, md, "Original vertex count mismatch: %u to %u", me_numVerts, numVerts); + ob, md, "Original vertex count mismatch: %u to %u", me_numVerts, verts_num); goto error; } } } /* check to see if our deltas are still valid */ - if (!csmd->delta_cache.deltas || (csmd->delta_cache.totverts != numVerts) || + if (!csmd->delta_cache.deltas || (csmd->delta_cache.totverts != verts_num) || force_delta_cache_update) { const float(*rest_coords)[3]; bool is_rest_coords_alloc = false; @@ -649,7 +649,7 @@ static void correctivesmooth_modifier_do(ModifierData *md, if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) { /* caller needs to do sanity check here */ - csmd->bind_coords_num = numVerts; + csmd->bind_coords_num = verts_num; rest_coords = csmd->bind_coords; } else { @@ -657,7 +657,7 @@ static void correctivesmooth_modifier_do(ModifierData *md, rest_coords = em ? BKE_editmesh_vert_coords_alloc_orco(em, &me_numVerts) : BKE_mesh_vert_coords_alloc(ob->data, &me_numVerts); - BLI_assert((uint)me_numVerts == numVerts); + BLI_assert((uint)me_numVerts == verts_num); is_rest_coords_alloc = true; } @@ -665,7 +665,7 @@ static void correctivesmooth_modifier_do(ModifierData *md, TIMEIT_START(corrective_smooth_deltas); #endif - calc_deltas(csmd, mesh, dvert, defgrp_index, rest_coords, numVerts); + calc_deltas(csmd, mesh, dvert, defgrp_index, rest_coords, verts_num); #ifdef DEBUG_TIME TIMEIT_END(corrective_smooth_deltas); @@ -677,7 +677,7 @@ static void correctivesmooth_modifier_do(ModifierData *md, if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) { /* this could be a check, but at this point it _must_ be valid */ - BLI_assert(csmd->bind_coords_num == numVerts && csmd->delta_cache.deltas); + BLI_assert(csmd->bind_coords_num == verts_num && csmd->delta_cache.deltas); } #ifdef DEBUG_TIME @@ -685,7 +685,7 @@ static void correctivesmooth_modifier_do(ModifierData *md, #endif /* do the actual delta mush */ - smooth_verts(csmd, mesh, dvert, defgrp_index, vertexCos, numVerts); + smooth_verts(csmd, mesh, dvert, defgrp_index, vertexCos, verts_num); { uint i; @@ -693,11 +693,11 @@ static void correctivesmooth_modifier_do(ModifierData *md, float(*tangent_spaces)[3][3]; const float scale = csmd->scale; /* calloc, since values are accumulated */ - tangent_spaces = MEM_calloc_arrayN(numVerts, sizeof(float[3][3]), __func__); + tangent_spaces = MEM_calloc_arrayN(verts_num, sizeof(float[3][3]), __func__); calc_tangent_spaces(mesh, vertexCos, tangent_spaces); - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { float delta[3]; #ifdef USE_TANGENT_CALC_INLINE @@ -727,12 +727,13 @@ static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { - Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false); + Mesh *mesh_src = MOD_deform_mesh_eval_get( + ctx->object, NULL, mesh, NULL, verts_num, false, false); correctivesmooth_modifier_do( - md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (uint)numVerts, NULL); + md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (uint)verts_num, NULL); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); @@ -744,10 +745,10 @@ static void deformVertsEM(ModifierData *md, struct BMEditMesh *editData, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { Mesh *mesh_src = MOD_deform_mesh_eval_get( - ctx->object, editData, mesh, NULL, numVerts, false, false); + ctx->object, editData, mesh, NULL, verts_num, false, false); /* TODO(Campbell): use edit-mode data only (remove this line). */ if (mesh_src != NULL) { @@ -755,7 +756,7 @@ static void deformVertsEM(ModifierData *md, } correctivesmooth_modifier_do( - md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (uint)numVerts, editData); + md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (uint)verts_num, editData); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c index 5b22b933823..a82b999f4dc 100644 --- a/source/blender/modifiers/intern/MOD_curve.c +++ b/source/blender/modifiers/intern/MOD_curve.c @@ -104,14 +104,14 @@ static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { CurveModifierData *cmd = (CurveModifierData *)md; Mesh *mesh_src = NULL; if (ctx->object->type == OB_MESH && cmd->name[0] != '\0') { /* mesh_src is only needed for vgroups. */ - mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false); + mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false, false); } struct MDeformVert *dvert = NULL; @@ -124,7 +124,7 @@ static void deformVerts(ModifierData *md, BKE_curve_deform_coords(cmd->object, ctx->object, vertexCos, - numVerts, + verts_num, dvert, defgrp_index, cmd->flag, @@ -140,10 +140,10 @@ static void deformVertsEM(ModifierData *md, BMEditMesh *em, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { if (mesh != NULL) { - deformVerts(md, ctx, mesh, vertexCos, numVerts); + deformVerts(md, ctx, mesh, vertexCos, verts_num); return; } @@ -162,7 +162,7 @@ static void deformVertsEM(ModifierData *md, BKE_curve_deform_coords_with_editmesh(cmd->object, ctx->object, vertexCos, - numVerts, + verts_num, defgrp_index, cmd->flag, cmd->defaxis - 1, @@ -172,7 +172,7 @@ static void deformVertsEM(ModifierData *md, BKE_curve_deform_coords(cmd->object, ctx->object, vertexCos, - numVerts, + verts_num, NULL, defgrp_index, cmd->flag, diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c index 2f35ffb3e18..ca48d4fedd8 100644 --- a/source/blender/modifiers/intern/MOD_displace.c +++ b/source/blender/modifiers/intern/MOD_displace.c @@ -269,7 +269,7 @@ static void displaceModifier_do(DisplaceModifierData *dmd, const ModifierEvalContext *ctx, Mesh *mesh, float (*vertexCos)[3], - const int numVerts) + const int verts_num) { Object *ob = ctx->object; MVert *mvert; @@ -299,7 +299,7 @@ static void displaceModifier_do(DisplaceModifierData *dmd, Tex *tex_target = dmd->texture; if (tex_target != NULL) { - tex_co = MEM_calloc_arrayN((size_t)numVerts, sizeof(*tex_co), "displaceModifier_do tex_co"); + tex_co = MEM_calloc_arrayN((size_t)verts_num, sizeof(*tex_co), "displaceModifier_do tex_co"); MOD_get_texture_coords((MappingInfoModifierData *)dmd, ctx, ob, mesh, vertexCos, tex_co); MOD_init_texture((MappingInfoModifierData *)dmd, ctx); @@ -319,9 +319,9 @@ static void displaceModifier_do(DisplaceModifierData *dmd, } clnors = CustomData_get_layer(ldata, CD_NORMAL); - vert_clnors = MEM_malloc_arrayN(numVerts, sizeof(*vert_clnors), __func__); + vert_clnors = MEM_malloc_arrayN(verts_num, sizeof(*vert_clnors), __func__); BKE_mesh_normals_loop_to_vertex( - numVerts, mesh->mloop, mesh->totloop, (const float(*)[3])clnors, vert_clnors); + verts_num, mesh->mloop, mesh->totloop, (const float(*)[3])clnors, vert_clnors); } else { direction = MOD_DISP_DIR_NOR; @@ -355,8 +355,8 @@ static void displaceModifier_do(DisplaceModifierData *dmd, } TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); - settings.use_threading = (numVerts > 512); - BLI_task_parallel_range(0, numVerts, &data, displaceModifier_do_task, &settings); + settings.use_threading = (verts_num > 512); + BLI_task_parallel_range(0, verts_num, &data, displaceModifier_do_task, &settings); if (data.pool != NULL) { BKE_image_pool_free(data.pool); @@ -375,11 +375,12 @@ static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { - Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false); + Mesh *mesh_src = MOD_deform_mesh_eval_get( + ctx->object, NULL, mesh, NULL, verts_num, false, false); - displaceModifier_do((DisplaceModifierData *)md, ctx, mesh_src, vertexCos, numVerts); + displaceModifier_do((DisplaceModifierData *)md, ctx, mesh_src, vertexCos, verts_num); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); @@ -391,17 +392,17 @@ static void deformVertsEM(ModifierData *md, struct BMEditMesh *editData, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { Mesh *mesh_src = MOD_deform_mesh_eval_get( - ctx->object, editData, mesh, NULL, numVerts, false, false); + ctx->object, editData, mesh, NULL, verts_num, false, false); /* TODO(Campbell): use edit-mode data only (remove this line). */ if (mesh_src != NULL) { BKE_mesh_wrapper_ensure_mdata(mesh_src); } - displaceModifier_do((DisplaceModifierData *)md, ctx, mesh_src, vertexCos, numVerts); + displaceModifier_do((DisplaceModifierData *)md, ctx, mesh_src, vertexCos, verts_num); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index 33b090b9577..b3bcd181de9 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -279,12 +279,12 @@ static void remap_faces_3_6_9_12(Mesh *mesh, } static void remap_uvs_3_6_9_12( - Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3) + Mesh *mesh, Mesh *split, int layers_num, int i, int cur, int c0, int c1, int c2, int c3) { MTFace *mf, *df1, *df2, *df3; int l; - for (l = 0; l < numlayer; l++) { + for (l = 0; l < layers_num; l++) { mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l); df1 = mf + cur; df2 = df1 + 1; @@ -339,12 +339,12 @@ static void remap_faces_5_10(Mesh *mesh, } static void remap_uvs_5_10( - Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3) + Mesh *mesh, Mesh *split, int layers_num, int i, int cur, int c0, int c1, int c2, int c3) { MTFace *mf, *df1, *df2; int l; - for (l = 0; l < numlayer; l++) { + for (l = 0; l < layers_num; l++) { mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l); df1 = mf + cur; df2 = df1 + 1; @@ -411,12 +411,12 @@ static void remap_faces_15(Mesh *mesh, } static void remap_uvs_15( - Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3) + Mesh *mesh, Mesh *split, int layers_num, int i, int cur, int c0, int c1, int c2, int c3) { MTFace *mf, *df1, *df2, *df3, *df4; int l; - for (l = 0; l < numlayer; l++) { + for (l = 0; l < layers_num; l++) { mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l); df1 = mf + cur; df2 = df1 + 1; @@ -487,12 +487,12 @@ static void remap_faces_7_11_13_14(Mesh *mesh, } static void remap_uvs_7_11_13_14( - Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3) + Mesh *mesh, Mesh *split, int layers_num, int i, int cur, int c0, int c1, int c2, int c3) { MTFace *mf, *df1, *df2, *df3; int l; - for (l = 0; l < numlayer; l++) { + for (l = 0; l < layers_num; l++) { mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l); df1 = mf + cur; df2 = df1 + 1; @@ -547,12 +547,12 @@ static void remap_faces_19_21_22(Mesh *mesh, } static void remap_uvs_19_21_22( - Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2) + Mesh *mesh, Mesh *split, int layers_num, int i, int cur, int c0, int c1, int c2) { MTFace *mf, *df1, *df2; int l; - for (l = 0; l < numlayer; l++) { + for (l = 0; l < layers_num; l++) { mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l); df1 = mf + cur; df2 = df1 + 1; @@ -609,12 +609,12 @@ static void remap_faces_23(Mesh *mesh, } static void remap_uvs_23( - Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2) + Mesh *mesh, Mesh *split, int layers_num, int i, int cur, int c0, int c1, int c2) { MTFace *mf, *df1, *df2; int l; - for (l = 0; l < numlayer; l++) { + for (l = 0; l < layers_num; l++) { mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l); df1 = mf + cur; df2 = df1 + 1; @@ -653,7 +653,7 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh) int *fs, totesplit = 0, totfsplit = 0, curdupface = 0; int i, v1, v2, v3, v4, esplit, v[4] = {0, 0, 0, 0}, /* To quite gcc barking... */ uv[4] = {0, 0, 0, 0}; /* To quite gcc barking... */ - int numlayer; + int layers_num; uint ed_v1, ed_v2; edgehash = BLI_edgehash_new(__func__); @@ -728,7 +728,7 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh) split_m = BKE_mesh_new_nomain_from_template(mesh, totesplit, 0, totface + totfsplit, 0, 0); - numlayer = CustomData_number_of_layers(&split_m->fdata, CD_MTFACE); + layers_num = CustomData_number_of_layers(&split_m->fdata, CD_MTFACE); /* copy new faces & verts (is it really this painful with custom data??) */ for (i = 0; i < totvert; i++) { @@ -814,23 +814,23 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh) case 12: remap_faces_3_6_9_12( mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]); - if (numlayer) { - remap_uvs_3_6_9_12(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]); + if (layers_num) { + remap_uvs_3_6_9_12(mesh, split_m, layers_num, i, curdupface, uv[0], uv[1], uv[2], uv[3]); } break; case 5: case 10: remap_faces_5_10( mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]); - if (numlayer) { - remap_uvs_5_10(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]); + if (layers_num) { + remap_uvs_5_10(mesh, split_m, layers_num, i, curdupface, uv[0], uv[1], uv[2], uv[3]); } break; case 15: remap_faces_15( mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]); - if (numlayer) { - remap_uvs_15(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]); + if (layers_num) { + remap_uvs_15(mesh, split_m, layers_num, i, curdupface, uv[0], uv[1], uv[2], uv[3]); } break; case 7: @@ -839,8 +839,9 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh) case 14: remap_faces_7_11_13_14( mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]); - if (numlayer) { - remap_uvs_7_11_13_14(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]); + if (layers_num) { + remap_uvs_7_11_13_14( + mesh, split_m, layers_num, i, curdupface, uv[0], uv[1], uv[2], uv[3]); } break; case 19: @@ -848,15 +849,15 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh) case 22: remap_faces_19_21_22( mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]); - if (numlayer) { - remap_uvs_19_21_22(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2]); + if (layers_num) { + remap_uvs_19_21_22(mesh, split_m, layers_num, i, curdupface, uv[0], uv[1], uv[2]); } break; case 23: remap_faces_23( mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]); - if (numlayer) { - remap_uvs_23(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2]); + if (layers_num) { + remap_uvs_23(mesh, split_m, layers_num, i, curdupface, uv[0], uv[1], uv[2]); } break; case 0: diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c index 513000e3ad6..1000bbf45d6 100644 --- a/source/blender/modifiers/intern/MOD_hook.c +++ b/source/blender/modifiers/intern/MOD_hook.c @@ -152,14 +152,14 @@ struct HookData_cb { bool invert_vgroup; }; -static BLI_bitmap *hook_index_array_to_bitmap(HookModifierData *hmd, const int numVerts) +static BLI_bitmap *hook_index_array_to_bitmap(HookModifierData *hmd, const int verts_num) { - BLI_bitmap *indexar_used = BLI_BITMAP_NEW(numVerts, __func__); + BLI_bitmap *indexar_used = BLI_BITMAP_NEW(verts_num, __func__); int i; int *index_pt; - for (i = 0, index_pt = hmd->indexar; i < hmd->totindex; i++, index_pt++) { + for (i = 0, index_pt = hmd->indexar; i < hmd->indexar_num; i++, index_pt++) { const int j = *index_pt; - if (j < numVerts) { + if (j < verts_num) { BLI_BITMAP_ENABLE(indexar_used, i); } } @@ -275,7 +275,7 @@ static void deformVerts_do(HookModifierData *hmd, Mesh *mesh, BMEditMesh *em, float (*vertexCos)[3], - int numVerts) + int verts_num) { Object *ob_target = hmd->object; bPoseChannel *pchan = BKE_pose_channel_find_name(ob_target->pose, hmd->subtarget); @@ -365,15 +365,15 @@ static void deformVerts_do(HookModifierData *hmd, const int *origindex_ar; /* if mesh is present and has original index data, use it */ if (mesh && (origindex_ar = CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX))) { - int numVerts_orig = numVerts; + int verts_orig_num = verts_num; if (ob->type == OB_MESH) { const Mesh *me_orig = ob->data; - numVerts_orig = me_orig->totvert; + verts_orig_num = me_orig->totvert; } - BLI_bitmap *indexar_used = hook_index_array_to_bitmap(hmd, numVerts_orig); - for (i = 0; i < numVerts; i++) { + BLI_bitmap *indexar_used = hook_index_array_to_bitmap(hmd, verts_orig_num); + for (i = 0; i < verts_num; i++) { int i_orig = origindex_ar[i]; - BLI_assert(i_orig < numVerts_orig); + BLI_assert(i_orig < verts_orig_num); if (BLI_BITMAP_TEST(indexar_used, i_orig)) { hook_co_apply(&hd, i, dvert ? &dvert[i] : NULL); } @@ -382,8 +382,8 @@ static void deformVerts_do(HookModifierData *hmd, } else { /* missing mesh or ORIGINDEX */ if ((em != NULL) && (hd.defgrp_index != -1)) { - BLI_assert(em->bm->totvert == numVerts); - BLI_bitmap *indexar_used = hook_index_array_to_bitmap(hmd, numVerts); + BLI_assert(em->bm->totvert == verts_num); + BLI_bitmap *indexar_used = hook_index_array_to_bitmap(hmd, verts_num); BMIter iter; BMVert *v; BM_ITER_MESH_INDEX (v, &iter, em->bm, BM_VERTS_OF_MESH, i) { @@ -395,9 +395,9 @@ static void deformVerts_do(HookModifierData *hmd, MEM_freeN(indexar_used); } else { - for (i = 0, index_pt = hmd->indexar; i < hmd->totindex; i++, index_pt++) { + for (i = 0, index_pt = hmd->indexar; i < hmd->indexar_num; i++, index_pt++) { const int j = *index_pt; - if (j < numVerts) { + if (j < verts_num) { hook_co_apply(&hd, j, dvert ? &dvert[j] : NULL); } } @@ -406,7 +406,7 @@ static void deformVerts_do(HookModifierData *hmd, } else if (hd.defgrp_index != -1) { /* vertex group hook */ if (em != NULL) { - BLI_assert(em->bm->totvert == numVerts); + BLI_assert(em->bm->totvert == verts_num); BMIter iter; BMVert *v; BM_ITER_MESH_INDEX (v, &iter, em->bm, BM_VERTS_OF_MESH, i) { @@ -416,7 +416,7 @@ static void deformVerts_do(HookModifierData *hmd, } else { BLI_assert(dvert != NULL); - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { hook_co_apply(&hd, i, &dvert[i]); } } @@ -427,12 +427,13 @@ static void deformVerts(struct ModifierData *md, const struct ModifierEvalContext *ctx, struct Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { HookModifierData *hmd = (HookModifierData *)md; - Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false); + Mesh *mesh_src = MOD_deform_mesh_eval_get( + ctx->object, NULL, mesh, NULL, verts_num, false, false); - deformVerts_do(hmd, ctx, ctx->object, mesh_src, NULL, vertexCos, numVerts); + deformVerts_do(hmd, ctx, ctx->object, mesh_src, NULL, vertexCos, verts_num); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); @@ -444,11 +445,11 @@ static void deformVertsEM(struct ModifierData *md, struct BMEditMesh *editData, struct Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { HookModifierData *hmd = (HookModifierData *)md; - deformVerts_do(hmd, ctx, ctx->object, mesh, mesh ? NULL : editData, vertexCos, numVerts); + deformVerts_do(hmd, ctx, ctx->object, mesh, mesh ? NULL : editData, vertexCos, verts_num); } static void panel_draw(const bContext *UNUSED(C), Panel *panel) @@ -526,7 +527,7 @@ static void blendWrite(BlendWriter *writer, const ModifierData *md) BKE_curvemapping_blend_write(writer, hmd->curfalloff); } - BLO_write_int32_array(writer, hmd->totindex, hmd->indexar); + BLO_write_int32_array(writer, hmd->indexar_num, hmd->indexar); } static void blendRead(BlendDataReader *reader, ModifierData *md) @@ -538,7 +539,7 @@ static void blendRead(BlendDataReader *reader, ModifierData *md) BKE_curvemapping_blend_read(reader, hmd->curfalloff); } - BLO_read_int32_array(reader, hmd->totindex, &hmd->indexar); + BLO_read_int32_array(reader, hmd->indexar_num, &hmd->indexar); } ModifierTypeInfo modifierType_Hook = { diff --git a/source/blender/modifiers/intern/MOD_laplaciandeform.c b/source/blender/modifiers/intern/MOD_laplaciandeform.c index d5f3902379d..239cb7f5a5a 100644 --- a/source/blender/modifiers/intern/MOD_laplaciandeform.c +++ b/source/blender/modifiers/intern/MOD_laplaciandeform.c @@ -58,10 +58,10 @@ enum { typedef struct LaplacianSystem { bool is_matrix_computed; bool has_solution; - int total_verts; - int total_edges; - int total_tris; - int total_anchors; + int verts_num; + int edges_num; + int tris_num; + int anchors_num; int repeat; char anchor_grp_name[64]; /* Vertex Group name */ float (*co)[3]; /* Original vertex coordinates */ @@ -84,20 +84,20 @@ static LaplacianSystem *newLaplacianSystem(void) sys->is_matrix_computed = false; sys->has_solution = false; - sys->total_verts = 0; - sys->total_edges = 0; - sys->total_anchors = 0; - sys->total_tris = 0; + sys->verts_num = 0; + sys->edges_num = 0; + sys->anchors_num = 0; + sys->tris_num = 0; sys->repeat = 1; sys->anchor_grp_name[0] = '\0'; return sys; } -static LaplacianSystem *initLaplacianSystem(int totalVerts, - int totalEdges, - int totalTris, - int totalAnchors, +static LaplacianSystem *initLaplacianSystem(int verts_num, + int edges_num, + int tris_num, + int anchors_num, const char defgrpName[64], int iterations) { @@ -105,18 +105,18 @@ static LaplacianSystem *initLaplacianSystem(int totalVerts, sys->is_matrix_computed = false; sys->has_solution = false; - sys->total_verts = totalVerts; - sys->total_edges = totalEdges; - sys->total_tris = totalTris; - sys->total_anchors = totalAnchors; + sys->verts_num = verts_num; + sys->edges_num = edges_num; + sys->tris_num = tris_num; + sys->anchors_num = anchors_num; sys->repeat = iterations; BLI_strncpy(sys->anchor_grp_name, defgrpName, sizeof(sys->anchor_grp_name)); - sys->co = MEM_malloc_arrayN(totalVerts, sizeof(float[3]), "DeformCoordinates"); - sys->no = MEM_calloc_arrayN(totalVerts, sizeof(float[3]), "DeformNormals"); - sys->delta = MEM_calloc_arrayN(totalVerts, sizeof(float[3]), "DeformDeltas"); - sys->tris = MEM_malloc_arrayN(totalTris, sizeof(int[3]), "DeformFaces"); - sys->index_anchors = MEM_malloc_arrayN((totalAnchors), sizeof(int), "DeformAnchors"); - sys->unit_verts = MEM_calloc_arrayN(totalVerts, sizeof(int), "DeformUnitVerts"); + sys->co = MEM_malloc_arrayN(verts_num, sizeof(float[3]), "DeformCoordinates"); + sys->no = MEM_calloc_arrayN(verts_num, sizeof(float[3]), "DeformNormals"); + sys->delta = MEM_calloc_arrayN(verts_num, sizeof(float[3]), "DeformDeltas"); + sys->tris = MEM_malloc_arrayN(tris_num, sizeof(int[3]), "DeformFaces"); + sys->index_anchors = MEM_malloc_arrayN((anchors_num), sizeof(int), "DeformAnchors"); + sys->unit_verts = MEM_calloc_arrayN(verts_num, sizeof(int), "DeformUnitVerts"); return sys; } @@ -146,7 +146,7 @@ static void createFaceRingMap(const int mvert_tot, MeshElemMap **r_map, int **r_indices) { - int i, j, totalr = 0; + int i, j, indices_num = 0; int *indices, *index_iter; MeshElemMap *map = MEM_calloc_arrayN(mvert_tot, sizeof(MeshElemMap), "DeformRingMap"); const MLoopTri *mlt; @@ -156,10 +156,10 @@ static void createFaceRingMap(const int mvert_tot, for (j = 0; j < 3; j++) { const uint v_index = mloop[mlt->tri[j]].v; map[v_index].count++; - totalr++; + indices_num++; } } - indices = MEM_calloc_arrayN(totalr, sizeof(int), "DeformRingIndex"); + indices = MEM_calloc_arrayN(indices_num, sizeof(int), "DeformRingIndex"); index_iter = indices; for (i = 0; i < mvert_tot; i++) { map[i].indices = index_iter; @@ -184,7 +184,7 @@ static void createVertRingMap(const int mvert_tot, int **r_indices) { MeshElemMap *map = MEM_calloc_arrayN(mvert_tot, sizeof(MeshElemMap), "DeformNeighborsMap"); - int i, vid[2], totalr = 0; + int i, vid[2], indices_num = 0; int *indices, *index_iter; const MEdge *me; @@ -193,9 +193,9 @@ static void createVertRingMap(const int mvert_tot, vid[1] = me->v2; map[vid[0]].count++; map[vid[1]].count++; - totalr += 2; + indices_num += 2; } - indices = MEM_calloc_arrayN(totalr, sizeof(int), "DeformNeighborsIndex"); + indices = MEM_calloc_arrayN(indices_num, sizeof(int), "DeformNeighborsIndex"); index_iter = indices; for (i = 0; i < mvert_tot; i++) { map[i].indices = index_iter; @@ -253,7 +253,7 @@ static void initLaplacianMatrix(LaplacianSystem *sys) int i = 3, j, ti; int idv[3]; - for (ti = 0; ti < sys->total_tris; ti++) { + for (ti = 0; ti < sys->tris_num; ti++) { const uint *vidt = sys->tris[ti]; const float *co[3]; @@ -305,7 +305,7 @@ static void computeImplictRotations(LaplacianSystem *sys) float minj, mjt, qj[3], vj[3]; int i, j, ln; - for (i = 0; i < sys->total_verts; i++) { + for (i = 0; i < sys->verts_num; i++) { normalize_v3(sys->no[i]); vidn = sys->ringv_map[i].indices; ln = sys->ringv_map[i].count; @@ -329,10 +329,10 @@ static void rotateDifferentialCoordinates(LaplacianSystem *sys) float alpha, beta, gamma; float pj[3], ni[3], di[3]; float uij[3], dun[3], e2[3], pi[3], fni[3], vn[3][3]; - int i, j, num_fni, k, fi; + int i, j, fidn_num, k, fi; int *fidn; - for (i = 0; i < sys->total_verts; i++) { + for (i = 0; i < sys->verts_num; i++) { copy_v3_v3(pi, sys->co[i]); copy_v3_v3(ni, sys->no[i]); k = sys->unit_verts[i]; @@ -351,8 +351,8 @@ static void rotateDifferentialCoordinates(LaplacianSystem *sys) pi[1] = EIG_linear_solver_variable_get(sys->context, 1, i); pi[2] = EIG_linear_solver_variable_get(sys->context, 2, i); zero_v3(ni); - num_fni = sys->ringf_map[i].count; - for (fi = 0; fi < num_fni; fi++) { + fidn_num = sys->ringf_map[i].count; + for (fi = 0; fi < fidn_num; fi++) { const uint *vin; fidn = sys->ringf_map[i].indices; vin = sys->tris[fidn[fi]]; @@ -395,8 +395,8 @@ static void rotateDifferentialCoordinates(LaplacianSystem *sys) static void laplacianDeformPreview(LaplacianSystem *sys, float (*vertexCos)[3]) { int vid, i, j, n, na; - n = sys->total_verts; - na = sys->total_anchors; + n = sys->verts_num; + na = sys->anchors_num; if (!sys->is_matrix_computed) { sys->context = EIG_linear_least_squares_solver_new(n + na, n, 3); @@ -447,7 +447,7 @@ static void laplacianDeformPreview(LaplacianSystem *sys, float (*vertexCos)[3]) } } if (sys->has_solution) { - for (vid = 0; vid < sys->total_verts; vid++) { + for (vid = 0; vid < sys->verts_num; vid++) { vertexCos[vid][0] = EIG_linear_solver_variable_get(sys->context, 0, vid); vertexCos[vid][1] = EIG_linear_solver_variable_get(sys->context, 1, vid); vertexCos[vid][2] = EIG_linear_solver_variable_get(sys->context, 2, vid); @@ -493,7 +493,7 @@ static void laplacianDeformPreview(LaplacianSystem *sys, float (*vertexCos)[3]) } } if (sys->has_solution) { - for (vid = 0; vid < sys->total_verts; vid++) { + for (vid = 0; vid < sys->verts_num; vid++) { vertexCos[vid][0] = EIG_linear_solver_variable_get(sys->context, 0, vid); vertexCos[vid][1] = EIG_linear_solver_variable_get(sys->context, 1, vid); vertexCos[vid][2] = EIG_linear_solver_variable_get(sys->context, 2, vid); @@ -520,11 +520,11 @@ static bool isValidVertexGroup(LaplacianDeformModifierData *lmd, Object *ob, Mes } static void initSystem( - LaplacianDeformModifierData *lmd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int numVerts) + LaplacianDeformModifierData *lmd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int verts_num) { int i; int defgrp_index; - int total_anchors; + int anchors_num; float wpaint; MDeformVert *dvert = NULL; MDeformVert *dv = NULL; @@ -532,18 +532,18 @@ static void initSystem( const bool invert_vgroup = (lmd->flag & MOD_LAPLACIANDEFORM_INVERT_VGROUP) != 0; if (isValidVertexGroup(lmd, ob, mesh)) { - int *index_anchors = MEM_malloc_arrayN(numVerts, sizeof(int), __func__); /* over-alloc */ + int *index_anchors = MEM_malloc_arrayN(verts_num, sizeof(int), __func__); /* over-alloc */ const MLoopTri *mlooptri; const MLoop *mloop; STACK_DECLARE(index_anchors); - STACK_INIT(index_anchors, numVerts); + STACK_INIT(index_anchors, verts_num); MOD_get_vgroup(ob, mesh, lmd->anchor_grp_name, &dvert, &defgrp_index); BLI_assert(dvert != NULL); dv = dvert; - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { wpaint = invert_vgroup ? 1.0f - BKE_defvert_find_weight(dv, defgrp_index) : BKE_defvert_find_weight(dv, defgrp_index); dv++; @@ -552,20 +552,20 @@ static void initSystem( } } - total_anchors = STACK_SIZE(index_anchors); - lmd->cache_system = initLaplacianSystem(numVerts, + anchors_num = STACK_SIZE(index_anchors); + lmd->cache_system = initLaplacianSystem(verts_num, mesh->totedge, BKE_mesh_runtime_looptri_len(mesh), - total_anchors, + anchors_num, lmd->anchor_grp_name, lmd->repeat); sys = (LaplacianSystem *)lmd->cache_system; - memcpy(sys->index_anchors, index_anchors, sizeof(int) * total_anchors); - memcpy(sys->co, vertexCos, sizeof(float[3]) * numVerts); + memcpy(sys->index_anchors, index_anchors, sizeof(int) * anchors_num); + memcpy(sys->co, vertexCos, sizeof(float[3]) * verts_num); MEM_freeN(index_anchors); - lmd->vertexco = MEM_malloc_arrayN(numVerts, sizeof(float[3]), "ModDeformCoordinates"); - memcpy(lmd->vertexco, vertexCos, sizeof(float[3]) * numVerts); - lmd->total_verts = numVerts; + lmd->vertexco = MEM_malloc_arrayN(verts_num, sizeof(float[3]), "ModDeformCoordinates"); + memcpy(lmd->vertexco, vertexCos, sizeof(float[3]) * verts_num); + lmd->verts_num = verts_num; createFaceRingMap(mesh->totvert, BKE_mesh_runtime_looptri_ensure(mesh), @@ -579,7 +579,7 @@ static void initSystem( mlooptri = BKE_mesh_runtime_looptri_ensure(mesh); mloop = mesh->mloop; - for (i = 0; i < sys->total_tris; i++) { + for (i = 0; i < sys->tris_num; i++) { sys->tris[i][0] = mloop[mlooptri[i].tri[0]].v; sys->tris[i][1] = mloop[mlooptri[i].tri[1]].v; sys->tris[i][2] = mloop[mlooptri[i].tri[2]].v; @@ -590,21 +590,21 @@ static void initSystem( static int isSystemDifferent(LaplacianDeformModifierData *lmd, Object *ob, Mesh *mesh, - int numVerts) + int verts_num) { int i; int defgrp_index; - int total_anchors = 0; + int anchors_num = 0; float wpaint; MDeformVert *dvert = NULL; MDeformVert *dv = NULL; LaplacianSystem *sys = (LaplacianSystem *)lmd->cache_system; const bool invert_vgroup = (lmd->flag & MOD_LAPLACIANDEFORM_INVERT_VGROUP) != 0; - if (sys->total_verts != numVerts) { + if (sys->verts_num != verts_num) { return LAPDEFORM_SYSTEM_CHANGE_VERTEXES; } - if (sys->total_edges != mesh->totedge) { + if (sys->edges_num != mesh->totedge) { return LAPDEFORM_SYSTEM_CHANGE_EDGES; } if (!STREQ(lmd->anchor_grp_name, sys->anchor_grp_name)) { @@ -615,15 +615,15 @@ static int isSystemDifferent(LaplacianDeformModifierData *lmd, return LAPDEFORM_SYSTEM_CHANGE_NOT_VALID_GROUP; } dv = dvert; - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { wpaint = invert_vgroup ? 1.0f - BKE_defvert_find_weight(dv, defgrp_index) : BKE_defvert_find_weight(dv, defgrp_index); dv++; if (wpaint > 0.0f) { - total_anchors++; + anchors_num++; } } - if (sys->total_anchors != total_anchors) { + if (sys->anchors_num != anchors_num) { return LAPDEFORM_SYSTEM_ONLY_CHANGE_ANCHORS; } @@ -631,7 +631,7 @@ static int isSystemDifferent(LaplacianDeformModifierData *lmd, } static void LaplacianDeformModifier_do( - LaplacianDeformModifierData *lmd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int numVerts) + LaplacianDeformModifierData *lmd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int verts_num) { float(*filevertexCos)[3]; int sysdif; @@ -643,22 +643,22 @@ static void LaplacianDeformModifier_do( deleteLaplacianSystem(sys); lmd->cache_system = NULL; } - lmd->total_verts = 0; + lmd->verts_num = 0; MEM_SAFE_FREE(lmd->vertexco); return; } if (lmd->cache_system) { - sysdif = isSystemDifferent(lmd, ob, mesh, numVerts); + sysdif = isSystemDifferent(lmd, ob, mesh, verts_num); sys = lmd->cache_system; if (sysdif) { if (ELEM(sysdif, LAPDEFORM_SYSTEM_ONLY_CHANGE_ANCHORS, LAPDEFORM_SYSTEM_ONLY_CHANGE_GROUP)) { - filevertexCos = MEM_malloc_arrayN(numVerts, sizeof(float[3]), "TempModDeformCoordinates"); - memcpy(filevertexCos, lmd->vertexco, sizeof(float[3]) * numVerts); + filevertexCos = MEM_malloc_arrayN(verts_num, sizeof(float[3]), "TempModDeformCoordinates"); + memcpy(filevertexCos, lmd->vertexco, sizeof(float[3]) * verts_num); MEM_SAFE_FREE(lmd->vertexco); - lmd->total_verts = 0; + lmd->verts_num = 0; deleteLaplacianSystem(sys); lmd->cache_system = NULL; - initSystem(lmd, ob, mesh, filevertexCos, numVerts); + initSystem(lmd, ob, mesh, filevertexCos, verts_num); sys = lmd->cache_system; /* may have been reallocated */ MEM_SAFE_FREE(filevertexCos); if (sys) { @@ -668,11 +668,11 @@ static void LaplacianDeformModifier_do( else { if (sysdif == LAPDEFORM_SYSTEM_CHANGE_VERTEXES) { BKE_modifier_set_error( - ob, &lmd->modifier, "Vertices changed from %d to %d", lmd->total_verts, numVerts); + ob, &lmd->modifier, "Vertices changed from %d to %d", lmd->verts_num, verts_num); } else if (sysdif == LAPDEFORM_SYSTEM_CHANGE_EDGES) { BKE_modifier_set_error( - ob, &lmd->modifier, "Edges changed from %d to %d", sys->total_edges, mesh->totedge); + ob, &lmd->modifier, "Edges changed from %d to %d", sys->edges_num, mesh->totedge); } else if (sysdif == LAPDEFORM_SYSTEM_CHANGE_NOT_VALID_GROUP) { BKE_modifier_set_error(ob, @@ -695,18 +695,18 @@ static void LaplacianDeformModifier_do( lmd->anchor_grp_name); lmd->flag &= ~MOD_LAPLACIANDEFORM_BIND; } - else if (lmd->total_verts > 0 && lmd->total_verts == numVerts) { - filevertexCos = MEM_malloc_arrayN(numVerts, sizeof(float[3]), "TempDeformCoordinates"); - memcpy(filevertexCos, lmd->vertexco, sizeof(float[3]) * numVerts); + else if (lmd->verts_num > 0 && lmd->verts_num == verts_num) { + filevertexCos = MEM_malloc_arrayN(verts_num, sizeof(float[3]), "TempDeformCoordinates"); + memcpy(filevertexCos, lmd->vertexco, sizeof(float[3]) * verts_num); MEM_SAFE_FREE(lmd->vertexco); - lmd->total_verts = 0; - initSystem(lmd, ob, mesh, filevertexCos, numVerts); + lmd->verts_num = 0; + initSystem(lmd, ob, mesh, filevertexCos, verts_num); sys = lmd->cache_system; MEM_SAFE_FREE(filevertexCos); laplacianDeformPreview(sys, vertexCos); } else { - initSystem(lmd, ob, mesh, vertexCos, numVerts); + initSystem(lmd, ob, mesh, vertexCos, verts_num); sys = lmd->cache_system; laplacianDeformPreview(sys, vertexCos); } @@ -762,12 +762,13 @@ static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { - Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false); + Mesh *mesh_src = MOD_deform_mesh_eval_get( + ctx->object, NULL, mesh, NULL, verts_num, false, false); LaplacianDeformModifier_do( - (LaplacianDeformModifierData *)md, ctx->object, mesh_src, vertexCos, numVerts); + (LaplacianDeformModifierData *)md, ctx->object, mesh_src, vertexCos, verts_num); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); @@ -779,10 +780,10 @@ static void deformVertsEM(ModifierData *md, struct BMEditMesh *editData, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { Mesh *mesh_src = MOD_deform_mesh_eval_get( - ctx->object, editData, mesh, NULL, numVerts, false, false); + ctx->object, editData, mesh, NULL, verts_num, false, false); /* TODO(Campbell): use edit-mode data only (remove this line). */ if (mesh_src != NULL) { @@ -790,7 +791,7 @@ static void deformVertsEM(ModifierData *md, } LaplacianDeformModifier_do( - (LaplacianDeformModifierData *)md, ctx->object, mesh_src, vertexCos, numVerts); + (LaplacianDeformModifierData *)md, ctx->object, mesh_src, vertexCos, verts_num); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); @@ -805,7 +806,7 @@ static void freeData(ModifierData *md) deleteLaplacianSystem(sys); } MEM_SAFE_FREE(lmd->vertexco); - lmd->total_verts = 0; + lmd->verts_num = 0; } static void panel_draw(const bContext *UNUSED(C), Panel *panel) @@ -846,14 +847,14 @@ static void blendWrite(BlendWriter *writer, const ModifierData *md) { LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)md; - BLO_write_float3_array(writer, lmd->total_verts, lmd->vertexco); + BLO_write_float3_array(writer, lmd->verts_num, lmd->vertexco); } static void blendRead(BlendDataReader *reader, ModifierData *md) { LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)md; - BLO_read_float3_array(reader, lmd->total_verts, &lmd->vertexco); + BLO_read_float3_array(reader, lmd->verts_num, &lmd->vertexco); lmd->cache_system = NULL; } diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c index effe2a5af90..11abe9a4d0a 100644 --- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c +++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c @@ -45,12 +45,12 @@ struct BLaplacianSystem { float *ring_areas; /* Total area per ring. */ float *vlengths; /* Total sum of lengths(edges) per vertex. */ float *vweights; /* Total sum of weights per vertex. */ - int numEdges; /* Number of edges. */ - int numLoops; /* Number of edges. */ - int numPolys; /* Number of faces. */ - int numVerts; /* Number of verts. */ - short *numNeFa; /* Number of neighbors faces around vertex. */ - short *numNeEd; /* Number of neighbors Edges around vertex. */ + int edges_num; /* Number of edges. */ + int loops_num; /* Number of edges. */ + int polys_num; /* Number of faces. */ + int verts_num; /* Number of verts. */ + short *ne_fa_num; /* Number of neighbors faces around vertex. */ + short *ne_ed_num; /* Number of neighbors Edges around vertex. */ bool *zerola; /* Is zero area or length. */ /* Pointers to data. */ @@ -71,7 +71,7 @@ static bool is_disabled(const struct Scene *scene, ModifierData *md, bool useRen static float compute_volume(const float center[3], float (*vertexCos)[3], const MPoly *mpoly, - int numPolys, + int polys_num, const MLoop *mloop); static LaplacianSystem *init_laplacian_system(int a_numEdges, int a_numPolys, @@ -89,8 +89,8 @@ static void delete_laplacian_system(LaplacianSystem *sys) { MEM_SAFE_FREE(sys->eweights); MEM_SAFE_FREE(sys->fweights); - MEM_SAFE_FREE(sys->numNeEd); - MEM_SAFE_FREE(sys->numNeFa); + MEM_SAFE_FREE(sys->ne_ed_num); + MEM_SAFE_FREE(sys->ne_fa_num); MEM_SAFE_FREE(sys->ring_areas); MEM_SAFE_FREE(sys->vlengths); MEM_SAFE_FREE(sys->vweights); @@ -108,14 +108,14 @@ static void delete_laplacian_system(LaplacianSystem *sys) static void memset_laplacian_system(LaplacianSystem *sys, int val) { - memset(sys->eweights, val, sizeof(float) * sys->numEdges); - memset(sys->fweights, val, sizeof(float[3]) * sys->numLoops); - memset(sys->numNeEd, val, sizeof(short) * sys->numVerts); - memset(sys->numNeFa, val, sizeof(short) * sys->numVerts); - memset(sys->ring_areas, val, sizeof(float) * sys->numVerts); - memset(sys->vlengths, val, sizeof(float) * sys->numVerts); - memset(sys->vweights, val, sizeof(float) * sys->numVerts); - memset(sys->zerola, val, sizeof(bool) * sys->numVerts); + memset(sys->eweights, val, sizeof(float) * sys->edges_num); + memset(sys->fweights, val, sizeof(float[3]) * sys->loops_num); + memset(sys->ne_ed_num, val, sizeof(short) * sys->verts_num); + memset(sys->ne_fa_num, val, sizeof(short) * sys->verts_num); + memset(sys->ring_areas, val, sizeof(float) * sys->verts_num); + memset(sys->vlengths, val, sizeof(float) * sys->verts_num); + memset(sys->vweights, val, sizeof(float) * sys->verts_num); + memset(sys->zerola, val, sizeof(bool) * sys->verts_num); } static LaplacianSystem *init_laplacian_system(int a_numEdges, @@ -125,19 +125,19 @@ static LaplacianSystem *init_laplacian_system(int a_numEdges, { LaplacianSystem *sys; sys = MEM_callocN(sizeof(LaplacianSystem), "ModLaplSmoothSystem"); - sys->numEdges = a_numEdges; - sys->numPolys = a_numPolys; - sys->numLoops = a_numLoops; - sys->numVerts = a_numVerts; - - sys->eweights = MEM_calloc_arrayN(sys->numEdges, sizeof(float), __func__); - sys->fweights = MEM_calloc_arrayN(sys->numLoops, sizeof(float[3]), __func__); - sys->numNeEd = MEM_calloc_arrayN(sys->numVerts, sizeof(short), __func__); - sys->numNeFa = MEM_calloc_arrayN(sys->numVerts, sizeof(short), __func__); - sys->ring_areas = MEM_calloc_arrayN(sys->numVerts, sizeof(float), __func__); - sys->vlengths = MEM_calloc_arrayN(sys->numVerts, sizeof(float), __func__); - sys->vweights = MEM_calloc_arrayN(sys->numVerts, sizeof(float), __func__); - sys->zerola = MEM_calloc_arrayN(sys->numVerts, sizeof(bool), __func__); + sys->edges_num = a_numEdges; + sys->polys_num = a_numPolys; + sys->loops_num = a_numLoops; + sys->verts_num = a_numVerts; + + sys->eweights = MEM_calloc_arrayN(sys->edges_num, sizeof(float), __func__); + sys->fweights = MEM_calloc_arrayN(sys->loops_num, sizeof(float[3]), __func__); + sys->ne_ed_num = MEM_calloc_arrayN(sys->verts_num, sizeof(short), __func__); + sys->ne_fa_num = MEM_calloc_arrayN(sys->verts_num, sizeof(short), __func__); + sys->ring_areas = MEM_calloc_arrayN(sys->verts_num, sizeof(float), __func__); + sys->vlengths = MEM_calloc_arrayN(sys->verts_num, sizeof(float), __func__); + sys->vweights = MEM_calloc_arrayN(sys->verts_num, sizeof(float), __func__); + sys->zerola = MEM_calloc_arrayN(sys->verts_num, sizeof(bool), __func__); return sys; } @@ -145,13 +145,13 @@ static LaplacianSystem *init_laplacian_system(int a_numEdges, static float compute_volume(const float center[3], float (*vertexCos)[3], const MPoly *mpoly, - int numPolys, + int polys_num, const MLoop *mloop) { int i; float vol = 0.0f; - for (i = 0; i < numPolys; i++) { + for (i = 0; i < polys_num; i++) { const MPoly *mp = &mpoly[i]; const MLoop *l_first = &mloop[mp->loopstart]; const MLoop *l_prev = l_first + 1; @@ -174,7 +174,7 @@ static void volume_preservation(LaplacianSystem *sys, float vini, float vend, sh if (vend != 0.0f) { beta = pow(vini / vend, 1.0f / 3.0f); - for (i = 0; i < sys->numVerts; i++) { + for (i = 0; i < sys->verts_num; i++) { if (flag & MOD_LAPLACIANSMOOTH_X) { sys->vertexCos[i][0] = (sys->vertexCos[i][0] - sys->vert_centroid[0]) * beta + sys->vert_centroid[0]; @@ -199,15 +199,15 @@ static void init_laplacian_matrix(LaplacianSystem *sys) int i; uint idv1, idv2; - for (i = 0; i < sys->numEdges; i++) { + for (i = 0; i < sys->edges_num; i++) { idv1 = sys->medges[i].v1; idv2 = sys->medges[i].v2; v1 = sys->vertexCos[idv1]; v2 = sys->vertexCos[idv2]; - sys->numNeEd[idv1] = sys->numNeEd[idv1] + 1; - sys->numNeEd[idv2] = sys->numNeEd[idv2] + 1; + sys->ne_ed_num[idv1] = sys->ne_ed_num[idv1] + 1; + sys->ne_ed_num[idv2] = sys->ne_ed_num[idv2] + 1; w1 = len_v3v3(v1, v2); if (w1 < sys->min_area) { sys->zerola[idv1] = true; @@ -220,7 +220,7 @@ static void init_laplacian_matrix(LaplacianSystem *sys) sys->eweights[i] = w1; } - for (i = 0; i < sys->numPolys; i++) { + for (i = 0; i < sys->polys_num; i++) { const MPoly *mp = &sys->mpoly[i]; const MLoop *l_next = &sys->mloop[mp->loopstart]; const MLoop *l_term = l_next + mp->totloop; @@ -233,7 +233,7 @@ static void init_laplacian_matrix(LaplacianSystem *sys) const float *v_next = sys->vertexCos[l_next->v]; const uint l_curr_index = l_curr - sys->mloop; - sys->numNeFa[l_curr->v] += 1; + sys->ne_fa_num[l_curr->v] += 1; areaf = area_tri_v3(v_prev, v_curr, v_next); @@ -258,11 +258,12 @@ static void init_laplacian_matrix(LaplacianSystem *sys) sys->vweights[l_prev->v] += w1 + w2; } } - for (i = 0; i < sys->numEdges; i++) { + for (i = 0; i < sys->edges_num; i++) { idv1 = sys->medges[i].v1; idv2 = sys->medges[i].v2; /* if is boundary, apply scale-dependent umbrella operator only with neighbors in boundary */ - if (sys->numNeEd[idv1] != sys->numNeFa[idv1] && sys->numNeEd[idv2] != sys->numNeFa[idv2]) { + if (sys->ne_ed_num[idv1] != sys->ne_fa_num[idv1] && + sys->ne_ed_num[idv2] != sys->ne_fa_num[idv2]) { sys->vlengths[idv1] += sys->eweights[i]; sys->vlengths[idv2] += sys->eweights[i]; } @@ -274,7 +275,7 @@ static void fill_laplacian_matrix(LaplacianSystem *sys) int i; uint idv1, idv2; - for (i = 0; i < sys->numPolys; i++) { + for (i = 0; i < sys->polys_num; i++) { const MPoly *mp = &sys->mpoly[i]; const MLoop *l_next = &sys->mloop[mp->loopstart]; const MLoop *l_term = l_next + mp->totloop; @@ -285,7 +286,8 @@ static void fill_laplacian_matrix(LaplacianSystem *sys) const uint l_curr_index = l_curr - sys->mloop; /* Is ring if number of faces == number of edges around vertex. */ - if (sys->numNeEd[l_curr->v] == sys->numNeFa[l_curr->v] && sys->zerola[l_curr->v] == false) { + if (sys->ne_ed_num[l_curr->v] == sys->ne_fa_num[l_curr->v] && + sys->zerola[l_curr->v] == false) { EIG_linear_solver_matrix_add(sys->context, l_curr->v, l_next->v, @@ -295,7 +297,8 @@ static void fill_laplacian_matrix(LaplacianSystem *sys) l_prev->v, sys->fweights[l_curr_index][1] * sys->vweights[l_curr->v]); } - if (sys->numNeEd[l_next->v] == sys->numNeFa[l_next->v] && sys->zerola[l_next->v] == false) { + if (sys->ne_ed_num[l_next->v] == sys->ne_fa_num[l_next->v] && + sys->zerola[l_next->v] == false) { EIG_linear_solver_matrix_add(sys->context, l_next->v, l_curr->v, @@ -305,7 +308,8 @@ static void fill_laplacian_matrix(LaplacianSystem *sys) l_prev->v, sys->fweights[l_curr_index][0] * sys->vweights[l_next->v]); } - if (sys->numNeEd[l_prev->v] == sys->numNeFa[l_prev->v] && sys->zerola[l_prev->v] == false) { + if (sys->ne_ed_num[l_prev->v] == sys->ne_fa_num[l_prev->v] && + sys->zerola[l_prev->v] == false) { EIG_linear_solver_matrix_add(sys->context, l_prev->v, l_curr->v, @@ -318,12 +322,13 @@ static void fill_laplacian_matrix(LaplacianSystem *sys) } } - for (i = 0; i < sys->numEdges; i++) { + for (i = 0; i < sys->edges_num; i++) { idv1 = sys->medges[i].v1; idv2 = sys->medges[i].v2; /* Is boundary */ - if (sys->numNeEd[idv1] != sys->numNeFa[idv1] && sys->numNeEd[idv2] != sys->numNeFa[idv2] && - sys->zerola[idv1] == false && sys->zerola[idv2] == false) { + if (sys->ne_ed_num[idv1] != sys->ne_fa_num[idv1] && + sys->ne_ed_num[idv2] != sys->ne_fa_num[idv2] && sys->zerola[idv1] == false && + sys->zerola[idv2] == false) { EIG_linear_solver_matrix_add( sys->context, idv1, idv2, sys->eweights[i] * sys->vlengths[idv1]); EIG_linear_solver_matrix_add( @@ -340,12 +345,12 @@ static void validate_solution(LaplacianSystem *sys, short flag, float lambda, fl if (flag & MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME) { vini = compute_volume( - sys->vert_centroid, sys->vertexCos, sys->mpoly, sys->numPolys, sys->mloop); + sys->vert_centroid, sys->vertexCos, sys->mpoly, sys->polys_num, sys->mloop); } - for (i = 0; i < sys->numVerts; i++) { + for (i = 0; i < sys->verts_num; i++) { if (sys->zerola[i] == false) { - lam = sys->numNeEd[i] == sys->numNeFa[i] ? (lambda >= 0.0f ? 1.0f : -1.0f) : - (lambda_border >= 0.0f ? 1.0f : -1.0f); + lam = sys->ne_ed_num[i] == sys->ne_fa_num[i] ? (lambda >= 0.0f ? 1.0f : -1.0f) : + (lambda_border >= 0.0f ? 1.0f : -1.0f); if (flag & MOD_LAPLACIANSMOOTH_X) { sys->vertexCos[i][0] += lam * ((float)EIG_linear_solver_variable_get(sys->context, 0, i) - sys->vertexCos[i][0]); @@ -362,13 +367,13 @@ static void validate_solution(LaplacianSystem *sys, short flag, float lambda, fl } if (flag & MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME) { vend = compute_volume( - sys->vert_centroid, sys->vertexCos, sys->mpoly, sys->numPolys, sys->mloop); + sys->vert_centroid, sys->vertexCos, sys->mpoly, sys->polys_num, sys->mloop); volume_preservation(sys, vini, vend, flag); } } static void laplaciansmoothModifier_do( - LaplacianSmoothModifierData *smd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int numVerts) + LaplacianSmoothModifierData *smd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int verts_num) { LaplacianSystem *sys; MDeformVert *dvert = NULL; @@ -378,7 +383,7 @@ static void laplaciansmoothModifier_do( int defgrp_index; const bool invert_vgroup = (smd->flag & MOD_LAPLACIANSMOOTH_INVERT_VGROUP) != 0; - sys = init_laplacian_system(mesh->totedge, mesh->totpoly, mesh->totloop, numVerts); + sys = init_laplacian_system(mesh->totedge, mesh->totpoly, mesh->totloop, verts_num); if (!sys) { return; } @@ -395,12 +400,12 @@ static void laplaciansmoothModifier_do( sys->vert_centroid[2] = 0.0f; memset_laplacian_system(sys, 0); - sys->context = EIG_linear_least_squares_solver_new(numVerts, numVerts, 3); + sys->context = EIG_linear_least_squares_solver_new(verts_num, verts_num, 3); init_laplacian_matrix(sys); for (iter = 0; iter < smd->repeat; iter++) { - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { EIG_linear_solver_variable_set(sys->context, 0, i, vertexCos[i][0]); EIG_linear_solver_variable_set(sys->context, 1, i, vertexCos[i][1]); EIG_linear_solver_variable_set(sys->context, 2, i, vertexCos[i][2]); @@ -408,12 +413,12 @@ static void laplaciansmoothModifier_do( add_v3_v3(sys->vert_centroid, vertexCos[i]); } } - if (iter == 0 && numVerts > 0) { - mul_v3_fl(sys->vert_centroid, 1.0f / (float)numVerts); + if (iter == 0 && verts_num > 0) { + mul_v3_fl(sys->vert_centroid, 1.0f / (float)verts_num); } dv = dvert; - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { EIG_linear_solver_right_hand_side_add(sys->context, 0, i, vertexCos[i][0]); EIG_linear_solver_right_hand_side_add(sys->context, 1, i, vertexCos[i][1]); EIG_linear_solver_right_hand_side_add(sys->context, 2, i, vertexCos[i][2]); @@ -433,7 +438,7 @@ static void laplaciansmoothModifier_do( sys->vweights[i] = (w == 0.0f) ? 0.0f : -fabsf(smd->lambda) * wpaint / w; w = sys->vlengths[i]; sys->vlengths[i] = (w == 0.0f) ? 0.0f : -fabsf(smd->lambda_border) * wpaint * 2.0f / w; - if (sys->numNeEd[i] == sys->numNeFa[i]) { + if (sys->ne_ed_num[i] == sys->ne_fa_num[i]) { EIG_linear_solver_matrix_add(sys->context, i, i, 1.0f + fabsf(smd->lambda) * wpaint); } else { @@ -447,7 +452,7 @@ static void laplaciansmoothModifier_do( w = sys->vlengths[i]; sys->vlengths[i] = (w == 0.0f) ? 0.0f : -fabsf(smd->lambda_border) * wpaint * 2.0f / w; - if (sys->numNeEd[i] == sys->numNeFa[i]) { + if (sys->ne_ed_num[i] == sys->ne_fa_num[i]) { EIG_linear_solver_matrix_add(sys->context, i, i, @@ -522,18 +527,18 @@ static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { Mesh *mesh_src; - if (numVerts == 0) { + if (verts_num == 0) { return; } - mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false); + mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false, false); laplaciansmoothModifier_do( - (LaplacianSmoothModifierData *)md, ctx->object, mesh_src, vertexCos, numVerts); + (LaplacianSmoothModifierData *)md, ctx->object, mesh_src, vertexCos, verts_num); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); @@ -545,15 +550,15 @@ static void deformVertsEM(ModifierData *md, struct BMEditMesh *editData, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { Mesh *mesh_src; - if (numVerts == 0) { + if (verts_num == 0) { return; } - mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false); + mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, verts_num, false, false); /* TODO(Campbell): use edit-mode data only (remove this line). */ if (mesh_src != NULL) { @@ -561,7 +566,7 @@ static void deformVertsEM(ModifierData *md, } laplaciansmoothModifier_do( - (LaplacianSmoothModifierData *)md, ctx->object, mesh_src, vertexCos, numVerts); + (LaplacianSmoothModifierData *)md, ctx->object, mesh_src, vertexCos, verts_num); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); diff --git a/source/blender/modifiers/intern/MOD_lattice.c b/source/blender/modifiers/intern/MOD_lattice.c index 1017f6cca1a..832372304a0 100644 --- a/source/blender/modifiers/intern/MOD_lattice.c +++ b/source/blender/modifiers/intern/MOD_lattice.c @@ -94,18 +94,18 @@ static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, struct Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { LatticeModifierData *lmd = (LatticeModifierData *)md; struct Mesh *mesh_src = MOD_deform_mesh_eval_get( - ctx->object, NULL, mesh, NULL, numVerts, false, false); + ctx->object, NULL, mesh, NULL, verts_num, false, false); MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */ BKE_lattice_deform_coords_with_mesh(lmd->object, ctx->object, vertexCos, - numVerts, + verts_num, lmd->flag, lmd->name, lmd->strength, @@ -121,10 +121,10 @@ static void deformVertsEM(ModifierData *md, struct BMEditMesh *em, struct Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { if (mesh != NULL) { - deformVerts(md, ctx, mesh, vertexCos, numVerts); + deformVerts(md, ctx, mesh, vertexCos, verts_num); return; } @@ -133,7 +133,7 @@ static void deformVertsEM(ModifierData *md, MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */ BKE_lattice_deform_coords_with_editmesh( - lmd->object, ctx->object, vertexCos, numVerts, lmd->flag, lmd->name, lmd->strength, em); + lmd->object, ctx->object, vertexCos, verts_num, lmd->flag, lmd->name, lmd->strength, em); } static void panel_draw(const bContext *UNUSED(C), Panel *panel) diff --git a/source/blender/modifiers/intern/MOD_mask.cc b/source/blender/modifiers/intern/MOD_mask.cc index 1cb720f4b02..cb26bd1b26b 100644 --- a/source/blender/modifiers/intern/MOD_mask.cc +++ b/source/blender/modifiers/intern/MOD_mask.cc @@ -145,58 +145,58 @@ static void invert_boolean_array(MutableSpan<bool> array) static void compute_masked_vertices(Span<bool> vertex_mask, MutableSpan<int> r_vertex_map, - uint *r_num_masked_vertices) + uint *r_verts_masked_num) { BLI_assert(vertex_mask.size() == r_vertex_map.size()); - uint num_masked_vertices = 0; + uint verts_masked_num = 0; for (uint i_src : r_vertex_map.index_range()) { if (vertex_mask[i_src]) { - r_vertex_map[i_src] = num_masked_vertices; - num_masked_vertices++; + r_vertex_map[i_src] = verts_masked_num; + verts_masked_num++; } else { r_vertex_map[i_src] = -1; } } - *r_num_masked_vertices = num_masked_vertices; + *r_verts_masked_num = verts_masked_num; } static void computed_masked_edges(const Mesh *mesh, Span<bool> vertex_mask, MutableSpan<int> r_edge_map, - uint *r_num_masked_edges) + uint *r_edges_masked_num) { BLI_assert(mesh->totedge == r_edge_map.size()); - uint num_masked_edges = 0; + uint edges_masked_num = 0; for (int i : IndexRange(mesh->totedge)) { const MEdge &edge = mesh->medge[i]; /* only add if both verts will be in new mesh */ if (vertex_mask[edge.v1] && vertex_mask[edge.v2]) { - r_edge_map[i] = num_masked_edges; - num_masked_edges++; + r_edge_map[i] = edges_masked_num; + edges_masked_num++; } else { r_edge_map[i] = -1; } } - *r_num_masked_edges = num_masked_edges; + *r_edges_masked_num = edges_masked_num; } static void computed_masked_edges_smooth(const Mesh *mesh, Span<bool> vertex_mask, MutableSpan<int> r_edge_map, - uint *r_num_masked_edges, - uint *r_num_add_vertices) + uint *r_edges_masked_num, + uint *r_verts_add_num) { BLI_assert(mesh->totedge == r_edge_map.size()); - uint num_masked_edges = 0; - uint num_add_vertices = 0; + uint edges_masked_num = 0; + uint verts_add_num = 0; for (int i : IndexRange(mesh->totedge)) { const MEdge &edge = mesh->medge[i]; @@ -204,36 +204,36 @@ static void computed_masked_edges_smooth(const Mesh *mesh, bool v1 = vertex_mask[edge.v1]; bool v2 = vertex_mask[edge.v2]; if (v1 && v2) { - r_edge_map[i] = num_masked_edges; - num_masked_edges++; + r_edge_map[i] = edges_masked_num; + edges_masked_num++; } else if (v1 != v2) { r_edge_map[i] = -2; - num_add_vertices++; + verts_add_num++; } else { r_edge_map[i] = -1; } } - num_masked_edges += num_add_vertices; - *r_num_masked_edges = num_masked_edges; - *r_num_add_vertices = num_add_vertices; + edges_masked_num += verts_add_num; + *r_edges_masked_num = edges_masked_num; + *r_verts_add_num = verts_add_num; } static void computed_masked_polygons(const Mesh *mesh, Span<bool> vertex_mask, Vector<int> &r_masked_poly_indices, Vector<int> &r_loop_starts, - uint *r_num_masked_polys, - uint *r_num_masked_loops) + uint *r_polys_masked_num, + uint *r_loops_masked_num) { BLI_assert(mesh->totvert == vertex_mask.size()); r_masked_poly_indices.reserve(mesh->totpoly); r_loop_starts.reserve(mesh->totpoly); - uint num_masked_loops = 0; + uint loops_masked_num = 0; for (int i : IndexRange(mesh->totpoly)) { const MPoly &poly_src = mesh->mpoly[i]; @@ -248,35 +248,35 @@ static void computed_masked_polygons(const Mesh *mesh, if (all_verts_in_mask) { r_masked_poly_indices.append_unchecked(i); - r_loop_starts.append_unchecked(num_masked_loops); - num_masked_loops += poly_src.totloop; + r_loop_starts.append_unchecked(loops_masked_num); + loops_masked_num += poly_src.totloop; } } - *r_num_masked_polys = r_masked_poly_indices.size(); - *r_num_masked_loops = num_masked_loops; + *r_polys_masked_num = r_masked_poly_indices.size(); + *r_loops_masked_num = loops_masked_num; } static void compute_interpolated_polygons(const Mesh *mesh, Span<bool> vertex_mask, - uint num_add_vertices, - uint num_masked_loops, + uint verts_add_num, + uint loops_masked_num, Vector<int> &r_masked_poly_indices, Vector<int> &r_loop_starts, - uint *r_num_add_edges, - uint *r_num_add_polys, - uint *r_num_add_loops) + uint *r_edges_add_num, + uint *r_polys_add_num, + uint *r_loops_add_num) { BLI_assert(mesh->totvert == vertex_mask.size()); /* Can't really know ahead of time how much space to use exactly. Estimate limit instead. */ /* NOTE: this reserve can only lift the capacity if there are ngons, which get split. */ - r_masked_poly_indices.reserve(r_masked_poly_indices.size() + num_add_vertices); - r_loop_starts.reserve(r_loop_starts.size() + num_add_vertices); + r_masked_poly_indices.reserve(r_masked_poly_indices.size() + verts_add_num); + r_loop_starts.reserve(r_loop_starts.size() + verts_add_num); - uint num_add_edges = 0; - uint num_add_polys = 0; - uint num_add_loops = 0; + uint edges_add_num = 0; + uint polys_add_num = 0; + uint loops_add_num = 0; for (int i : IndexRange(mesh->totpoly)) { const MPoly &poly_src = mesh->mpoly[i]; @@ -306,10 +306,10 @@ static void compute_interpolated_polygons(const Mesh *mesh, else if (!v_loop_in_mask && v_loop_in_mask_last) { BLI_assert(dst_totloop > 2); r_masked_poly_indices.append(i); - r_loop_starts.append(num_masked_loops + num_add_loops); - num_add_loops += dst_totloop; - num_add_polys++; - num_add_edges++; + r_loop_starts.append(loops_masked_num + loops_add_num); + loops_add_num += dst_totloop; + polys_add_num++; + edges_add_num++; dst_totloop = -1; } else if (v_loop_in_mask && v_loop_in_mask_last) { @@ -322,9 +322,9 @@ static void compute_interpolated_polygons(const Mesh *mesh, } } - *r_num_add_edges = num_add_edges; - *r_num_add_polys = num_add_polys; - *r_num_add_loops = num_add_loops; + *r_edges_add_num = edges_add_num; + *r_polys_add_num = polys_add_num; + *r_loops_add_num = loops_add_num; } static void copy_masked_vertices_to_new_mesh(const Mesh &src_mesh, @@ -363,15 +363,15 @@ static void add_interp_verts_copy_edges_to_new_mesh(const Mesh &src_mesh, MDeformVert *dvert, int defgrp_index, float threshold, - uint num_masked_edges, - uint num_add_verts, + uint edges_masked_num, + uint verts_add_num, MutableSpan<int> r_edge_map) { BLI_assert(src_mesh.totvert == vertex_mask.size()); BLI_assert(src_mesh.totedge == r_edge_map.size()); - uint vert_index = dst_mesh.totvert - num_add_verts; - uint edge_index = num_masked_edges - num_add_verts; + uint vert_index = dst_mesh.totvert - verts_add_num; + uint edge_index = edges_masked_num - verts_add_num; for (int i_src : IndexRange(src_mesh.totedge)) { if (r_edge_map[i_src] != -1) { int i_dst = r_edge_map[i_src]; @@ -416,7 +416,7 @@ static void add_interp_verts_copy_edges_to_new_mesh(const Mesh &src_mesh, } } BLI_assert(vert_index == dst_mesh.totvert); - BLI_assert(edge_index == num_masked_edges); + BLI_assert(edge_index == edges_masked_num); } static void copy_masked_edges_to_new_mesh(const Mesh &src_mesh, @@ -448,9 +448,9 @@ static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh, Span<int> edge_map, Span<int> masked_poly_indices, Span<int> new_loop_starts, - int num_masked_polys) + int polys_masked_num) { - for (const int i_dst : IndexRange(num_masked_polys)) { + for (const int i_dst : IndexRange(polys_masked_num)) { const int i_src = masked_poly_indices[i_dst]; const MPoly &mp_src = src_mesh.mpoly[i_src]; @@ -483,14 +483,14 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh, float threshold, Span<int> masked_poly_indices, Span<int> new_loop_starts, - int num_masked_polys, - int num_add_edges) + int polys_masked_num, + int edges_add_num) { - int edge_index = dst_mesh.totedge - num_add_edges; + int edge_index = dst_mesh.totedge - edges_add_num; int sub_poly_index = 0; int last_i_src = -1; for (const int i_dst : - IndexRange(num_masked_polys, masked_poly_indices.size() - num_masked_polys)) { + IndexRange(polys_masked_num, masked_poly_indices.size() - polys_masked_num)) { const int i_src = masked_poly_indices[i_dst]; if (i_src == last_i_src) { sub_poly_index++; @@ -662,53 +662,52 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx) } Array<int> vertex_map(mesh->totvert); - uint num_masked_vertices; - compute_masked_vertices(vertex_mask, vertex_map, &num_masked_vertices); + uint verts_masked_num; + compute_masked_vertices(vertex_mask, vertex_map, &verts_masked_num); Array<int> edge_map(mesh->totedge); - uint num_masked_edges; - uint num_add_vertices; + uint edges_masked_num; + uint verts_add_num; if (use_interpolation) { - computed_masked_edges_smooth( - mesh, vertex_mask, edge_map, &num_masked_edges, &num_add_vertices); + computed_masked_edges_smooth(mesh, vertex_mask, edge_map, &edges_masked_num, &verts_add_num); } else { - computed_masked_edges(mesh, vertex_mask, edge_map, &num_masked_edges); - num_add_vertices = 0; + computed_masked_edges(mesh, vertex_mask, edge_map, &edges_masked_num); + verts_add_num = 0; } Vector<int> masked_poly_indices; Vector<int> new_loop_starts; - uint num_masked_polys; - uint num_masked_loops; + uint polys_masked_num; + uint loops_masked_num; computed_masked_polygons(mesh, vertex_mask, masked_poly_indices, new_loop_starts, - &num_masked_polys, - &num_masked_loops); + &polys_masked_num, + &loops_masked_num); - uint num_add_edges = 0; - uint num_add_polys = 0; - uint num_add_loops = 0; + uint edges_add_num = 0; + uint polys_add_num = 0; + uint loops_add_num = 0; if (use_interpolation) { compute_interpolated_polygons(mesh, vertex_mask, - num_add_vertices, - num_masked_loops, + verts_add_num, + loops_masked_num, masked_poly_indices, new_loop_starts, - &num_add_edges, - &num_add_polys, - &num_add_loops); + &edges_add_num, + &polys_add_num, + &loops_add_num); } Mesh *result = BKE_mesh_new_nomain_from_template(mesh, - num_masked_vertices + num_add_vertices, - num_masked_edges + num_add_edges, + verts_masked_num + verts_add_num, + edges_masked_num + edges_add_num, 0, - num_masked_loops + num_add_loops, - num_masked_polys + num_add_polys); + loops_masked_num + loops_add_num, + polys_masked_num + polys_add_num); copy_masked_vertices_to_new_mesh(*mesh, *result, vertex_map); if (use_interpolation) { @@ -719,8 +718,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx) dvert, defgrp_index, mmd->threshold, - num_masked_edges, - num_add_vertices, + edges_masked_num, + verts_add_num, edge_map); } else { @@ -732,7 +731,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx) edge_map, masked_poly_indices, new_loop_starts, - num_masked_polys); + polys_masked_num); if (use_interpolation) { add_interpolated_polys_to_new_mesh(*mesh, *result, @@ -744,8 +743,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx) mmd->threshold, masked_poly_indices, new_loop_starts, - num_masked_polys, - num_add_edges); + polys_masked_num, + edges_add_num); } BKE_mesh_calc_edges_loose(result); diff --git a/source/blender/modifiers/intern/MOD_meshcache.c b/source/blender/modifiers/intern/MOD_meshcache.c index 3e022a5951d..e5a62ba96b6 100644 --- a/source/blender/modifiers/intern/MOD_meshcache.c +++ b/source/blender/modifiers/intern/MOD_meshcache.c @@ -77,7 +77,7 @@ static void meshcache_do(MeshCacheModifierData *mcmd, Object *ob, Mesh *mesh, float (*vertexCos_Real)[3], - int numVerts) + int verts_num) { const bool use_factor = mcmd->factor < 1.0f; int influence_group_index; @@ -87,7 +87,7 @@ static void meshcache_do(MeshCacheModifierData *mcmd, float(*vertexCos_Store)[3] = (use_factor || influence_group_index != -1 || (mcmd->deform_mode == MOD_MESHCACHE_DEFORM_INTEGRATE)) ? MEM_malloc_arrayN( - numVerts, sizeof(*vertexCos_Store), __func__) : + verts_num, sizeof(*vertexCos_Store), __func__) : NULL; float(*vertexCos)[3] = vertexCos_Store ? vertexCos_Store : vertexCos_Real; @@ -151,11 +151,11 @@ static void meshcache_do(MeshCacheModifierData *mcmd, switch (mcmd->type) { case MOD_MESHCACHE_TYPE_MDD: ok = MOD_meshcache_read_mdd_times( - filepath, vertexCos, numVerts, mcmd->interp, time, fps, mcmd->time_mode, &err_str); + filepath, vertexCos, verts_num, mcmd->interp, time, fps, mcmd->time_mode, &err_str); break; case MOD_MESHCACHE_TYPE_PC2: ok = MOD_meshcache_read_pc2_times( - filepath, vertexCos, numVerts, mcmd->interp, time, fps, mcmd->time_mode, &err_str); + filepath, vertexCos, verts_num, mcmd->interp, time, fps, mcmd->time_mode, &err_str); break; default: ok = false; @@ -171,7 +171,7 @@ static void meshcache_do(MeshCacheModifierData *mcmd, if (UNLIKELY(ob->type != OB_MESH)) { BKE_modifier_set_error(ob, &mcmd->modifier, "'Integrate' only valid for Mesh objects"); } - else if (UNLIKELY(me->totvert != numVerts)) { + else if (UNLIKELY(me->totvert != verts_num)) { BKE_modifier_set_error(ob, &mcmd->modifier, "'Integrate' original mesh vertex mismatch"); } else if (UNLIKELY(me->totpoly == 0)) { @@ -182,11 +182,11 @@ static void meshcache_do(MeshCacheModifierData *mcmd, int i; float(*vertexCos_Source)[3] = MEM_malloc_arrayN( - numVerts, sizeof(*vertexCos_Source), __func__); - float(*vertexCos_New)[3] = MEM_malloc_arrayN(numVerts, sizeof(*vertexCos_New), __func__); + verts_num, sizeof(*vertexCos_Source), __func__); + float(*vertexCos_New)[3] = MEM_malloc_arrayN(verts_num, sizeof(*vertexCos_New), __func__); MVert *mv = me->mvert; - for (i = 0; i < numVerts; i++, mv++) { + for (i = 0; i < verts_num; i++, mv++) { copy_v3_v3(vertexCos_Source[i], mv->co); } @@ -204,7 +204,7 @@ static void meshcache_do(MeshCacheModifierData *mcmd, ); /* write the corrected locations back into the result */ - memcpy(vertexCos, vertexCos_New, sizeof(*vertexCos) * numVerts); + memcpy(vertexCos, vertexCos_New, sizeof(*vertexCos) * verts_num); MEM_freeN(vertexCos_Source); MEM_freeN(vertexCos_New); @@ -244,7 +244,7 @@ static void meshcache_do(MeshCacheModifierData *mcmd, if (use_matrix) { int i; - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { mul_m3_v3(mat, vertexCos[i]); } } @@ -260,7 +260,7 @@ static void meshcache_do(MeshCacheModifierData *mcmd, mcmd->factor : 0.0f; if (mesh->dvert != NULL) { - for (int i = 0; i < numVerts; i++) { + for (int i = 0; i < verts_num; i++) { /* For each vertex, compute its blending factor between the mesh cache (for `fac = 0`) * and the former position of the vertex (for `fac = 1`). */ const MDeformVert *currentIndexDVert = dvert + i; @@ -275,10 +275,10 @@ static void meshcache_do(MeshCacheModifierData *mcmd, } else if (use_factor) { /* Influence_group_index is -1. */ - interp_vn_vn(*vertexCos_Real, *vertexCos_Store, mcmd->factor, numVerts * 3); + interp_vn_vn(*vertexCos_Real, *vertexCos_Store, mcmd->factor, verts_num * 3); } else { - memcpy(vertexCos_Real, vertexCos_Store, sizeof(*vertexCos_Store) * numVerts); + memcpy(vertexCos_Real, vertexCos_Store, sizeof(*vertexCos_Store) * verts_num); } } @@ -290,7 +290,7 @@ static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md; Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); @@ -299,9 +299,9 @@ static void deformVerts(ModifierData *md, if (ctx->object->type == OB_MESH && mcmd->defgrp_name[0] != '\0') { /* `mesh_src` is only needed for vertex groups. */ - mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false); + mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false, false); } - meshcache_do(mcmd, scene, ctx->object, mesh_src, vertexCos, numVerts); + meshcache_do(mcmd, scene, ctx->object, mesh_src, vertexCos, verts_num); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); @@ -313,7 +313,7 @@ static void deformVertsEM(ModifierData *md, struct BMEditMesh *editData, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md; Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); @@ -322,13 +322,14 @@ static void deformVertsEM(ModifierData *md, if (ctx->object->type == OB_MESH && mcmd->defgrp_name[0] != '\0') { /* `mesh_src` is only needed for vertex groups. */ - mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false); + mesh_src = MOD_deform_mesh_eval_get( + ctx->object, editData, mesh, NULL, verts_num, false, false); } if (mesh_src != NULL) { BKE_mesh_wrapper_ensure_mdata(mesh_src); } - meshcache_do(mcmd, scene, ctx->object, mesh_src, vertexCos, numVerts); + meshcache_do(mcmd, scene, ctx->object, mesh_src, vertexCos, verts_num); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); diff --git a/source/blender/modifiers/intern/MOD_meshcache_mdd.c b/source/blender/modifiers/intern/MOD_meshcache_mdd.c index 66b5f3ff9b2..67a01b1c8d5 100644 --- a/source/blender/modifiers/intern/MOD_meshcache_mdd.c +++ b/source/blender/modifiers/intern/MOD_meshcache_mdd.c @@ -96,22 +96,22 @@ static bool meshcache_read_mdd_range_from_time(FILE *fp, return false; } - size_t num_frames_read = 0; - size_t num_frames_expect = mdd_head.frame_tot; + size_t frames_num_read = 0; + size_t frames_num_expect = mdd_head.frame_tot; errno = 0; for (i = 0; i < mdd_head.frame_tot; i++) { - num_frames_read += fread(&f_time, sizeof(float), 1, fp); + frames_num_read += fread(&f_time, sizeof(float), 1, fp); #ifdef __LITTLE_ENDIAN__ BLI_endian_switch_float(&f_time); #endif if (f_time >= time) { - num_frames_expect = i + 1; + frames_num_expect = i + 1; break; } f_time_prev = f_time; } - if (num_frames_read != num_frames_expect) { + if (frames_num_read != frames_num_expect) { *err_str = errno ? strerror(errno) : "Timestamp read failed"; return false; } @@ -160,14 +160,14 @@ bool MOD_meshcache_read_mdd_index(FILE *fp, return false; } - size_t num_verts_read = 0; + size_t verts_read_num = 0; errno = 0; if (factor >= 1.0f) { #if 1 float *vco = *vertexCos; uint i; for (i = mdd_head.verts_tot; i != 0; i--, vco += 3) { - num_verts_read += fread(vco, sizeof(float[3]), 1, fp); + verts_read_num += fread(vco, sizeof(float[3]), 1, fp); # ifdef __LITTLE_ENDIAN__ BLI_endian_switch_float(vco + 0); @@ -192,7 +192,7 @@ bool MOD_meshcache_read_mdd_index(FILE *fp, uint i; for (i = mdd_head.verts_tot; i != 0; i--, vco += 3) { float tvec[3]; - num_verts_read += fread(tvec, sizeof(float[3]), 1, fp); + verts_read_num += fread(tvec, sizeof(float[3]), 1, fp); #ifdef __LITTLE_ENDIAN__ BLI_endian_switch_float(tvec + 0); @@ -206,7 +206,7 @@ bool MOD_meshcache_read_mdd_index(FILE *fp, } } - if (num_verts_read != mdd_head.verts_tot) { + if (verts_read_num != mdd_head.verts_tot) { *err_str = errno ? strerror(errno) : "Vertex coordinate read failed"; return false; } diff --git a/source/blender/modifiers/intern/MOD_meshcache_pc2.c b/source/blender/modifiers/intern/MOD_meshcache_pc2.c index 54ea27d0085..27fea20bb13 100644 --- a/source/blender/modifiers/intern/MOD_meshcache_pc2.c +++ b/source/blender/modifiers/intern/MOD_meshcache_pc2.c @@ -137,13 +137,13 @@ bool MOD_meshcache_read_pc2_index(FILE *fp, return false; } - size_t num_verts_read = 0; + size_t verts_read_num = 0; errno = 0; if (factor >= 1.0f) { float *vco = *vertexCos; uint i; for (i = pc2_head.verts_tot; i != 0; i--, vco += 3) { - num_verts_read += fread(vco, sizeof(float[3]), 1, fp); + verts_read_num += fread(vco, sizeof(float[3]), 1, fp); #ifdef __BIG_ENDIAN__ BLI_endian_switch_float(vco + 0); @@ -158,7 +158,7 @@ bool MOD_meshcache_read_pc2_index(FILE *fp, uint i; for (i = pc2_head.verts_tot; i != 0; i--, vco += 3) { float tvec[3]; - num_verts_read += fread(tvec, sizeof(float[3]), 1, fp); + verts_read_num += fread(tvec, sizeof(float[3]), 1, fp); #ifdef __BIG_ENDIAN__ BLI_endian_switch_float(tvec + 0); @@ -172,7 +172,7 @@ bool MOD_meshcache_read_pc2_index(FILE *fp, } } - if (num_verts_read != pc2_head.verts_tot) { + if (verts_read_num != pc2_head.verts_tot) { *err_str = errno ? strerror(errno) : "Vertex coordinate read failed"; return false; } diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index f15cdfe0c4e..09e6819a2ae 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -222,7 +222,7 @@ static float meshdeform_dynamic_bind(MeshDeformModifierData *mmd, float (*dco)[3 cell = &mmd->dyngrid[a]; inf = mmd->dyninfluences + cell->offset; - for (j = 0; j < cell->totinfluence; j++, inf++) { + for (j = 0; j < cell->influences_num; j++, inf++) { cageco = dco[inf->vertex]; cageweight = weight * inf->weight; #ifdef BLI_HAVE_SSE2 @@ -324,7 +324,7 @@ static void meshdeformModifier_do(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + const int verts_num) { MeshDeformModifierData *mmd = (MeshDeformModifierData *)md; Object *ob = ctx->object; @@ -333,7 +333,7 @@ static void meshdeformModifier_do(ModifierData *md, MDeformVert *dvert = NULL; float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4]; float(*dco)[3] = NULL, (*bindcagecos)[3]; - int a, totvert, totcagevert, defgrp_index; + int a, cage_verts_num, defgrp_index; MeshdeformUserdata data; static int recursive_bind_sentinel = 0; @@ -375,7 +375,7 @@ static void meshdeformModifier_do(ModifierData *md, } if (!recursive_bind_sentinel) { recursive_bind_sentinel = 1; - mmd->bindfunc(ob, mmd, cagemesh, (float *)vertexCos, numVerts, cagemat); + mmd->bindfunc(ob, mmd, cagemesh, (float *)vertexCos, verts_num, cagemat); recursive_bind_sentinel = 0; } @@ -383,16 +383,15 @@ static void meshdeformModifier_do(ModifierData *md, } /* verify we have compatible weights */ - totvert = numVerts; - totcagevert = BKE_mesh_wrapper_vert_len(cagemesh); + cage_verts_num = BKE_mesh_wrapper_vert_len(cagemesh); - if (mmd->totvert != totvert) { - BKE_modifier_set_error(ob, md, "Vertices changed from %d to %d", mmd->totvert, totvert); + if (mmd->verts_num != verts_num) { + BKE_modifier_set_error(ob, md, "Vertices changed from %d to %d", mmd->verts_num, verts_num); goto finally; } - else if (mmd->totcagevert != totcagevert) { + else if (mmd->cage_verts_num != cage_verts_num) { BKE_modifier_set_error( - ob, md, "Cage vertices changed from %d to %d", mmd->totcagevert, totcagevert); + ob, md, "Cage vertices changed from %d to %d", mmd->cage_verts_num, cage_verts_num); goto finally; } else if (mmd->bindcagecos == NULL) { @@ -403,14 +402,14 @@ static void meshdeformModifier_do(ModifierData *md, /* We allocate 1 element extra to make it possible to * load the values to SSE registers, which are float4. */ - dco = MEM_calloc_arrayN((totcagevert + 1), sizeof(*dco), "MDefDco"); - zero_v3(dco[totcagevert]); + dco = MEM_calloc_arrayN((cage_verts_num + 1), sizeof(*dco), "MDefDco"); + zero_v3(dco[cage_verts_num]); /* setup deformation data */ - BKE_mesh_wrapper_vert_coords_copy(cagemesh, dco, totcagevert); + BKE_mesh_wrapper_vert_coords_copy(cagemesh, dco, cage_verts_num); bindcagecos = (float(*)[3])mmd->bindcagecos; - for (a = 0; a < totcagevert; a++) { + for (a = 0; a < cage_verts_num; a++) { /* Get cage vertex in world-space with binding transform. */ float co[3]; mul_v3_m4v3(co, mmd->bindmat, dco[a]); @@ -433,7 +432,7 @@ static void meshdeformModifier_do(ModifierData *md, TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); settings.min_iter_per_thread = 16; - BLI_task_parallel_range(0, totvert, &data, meshdeform_vert_task, &settings); + BLI_task_parallel_range(0, verts_num, &data, meshdeform_vert_task, &settings); finally: MEM_SAFE_FREE(dco); @@ -443,13 +442,14 @@ static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { - Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false); + Mesh *mesh_src = MOD_deform_mesh_eval_get( + ctx->object, NULL, mesh, NULL, verts_num, false, false); MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */ - meshdeformModifier_do(md, ctx, mesh_src, vertexCos, numVerts); + meshdeformModifier_do(md, ctx, mesh_src, vertexCos, verts_num); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); @@ -461,17 +461,17 @@ static void deformVertsEM(ModifierData *md, struct BMEditMesh *editData, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { Mesh *mesh_src = MOD_deform_mesh_eval_get( - ctx->object, editData, mesh, NULL, numVerts, false, false); + ctx->object, editData, mesh, NULL, verts_num, false, false); /* TODO(Campbell): use edit-mode data only (remove this line). */ if (mesh_src != NULL) { BKE_mesh_wrapper_ensure_mdata(mesh_src); } - meshdeformModifier_do(md, ctx, mesh_src, vertexCos, numVerts); + meshdeformModifier_do(md, ctx, mesh_src, vertexCos, verts_num); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); @@ -484,42 +484,42 @@ void BKE_modifier_mdef_compact_influences(ModifierData *md) { MeshDeformModifierData *mmd = (MeshDeformModifierData *)md; float weight, *weights, totweight; - int totinfluence, totvert, totcagevert, a, b; + int influences_num, verts_num, cage_verts_num, a, b; weights = mmd->bindweights; if (!weights) { return; } - totvert = mmd->totvert; - totcagevert = mmd->totcagevert; + verts_num = mmd->verts_num; + cage_verts_num = mmd->cage_verts_num; /* count number of influences above threshold */ - for (b = 0; b < totvert; b++) { - for (a = 0; a < totcagevert; a++) { - weight = weights[a + b * totcagevert]; + for (b = 0; b < verts_num; b++) { + for (a = 0; a < cage_verts_num; a++) { + weight = weights[a + b * cage_verts_num]; if (weight > MESHDEFORM_MIN_INFLUENCE) { - mmd->totinfluence++; + mmd->influences_num++; } } } /* allocate bind influences */ mmd->bindinfluences = MEM_calloc_arrayN( - mmd->totinfluence, sizeof(MDefInfluence), "MDefBindInfluence"); - mmd->bindoffsets = MEM_calloc_arrayN((totvert + 1), sizeof(int), "MDefBindOffset"); + mmd->influences_num, sizeof(MDefInfluence), "MDefBindInfluence"); + mmd->bindoffsets = MEM_calloc_arrayN((verts_num + 1), sizeof(int), "MDefBindOffset"); /* write influences */ - totinfluence = 0; + influences_num = 0; - for (b = 0; b < totvert; b++) { - mmd->bindoffsets[b] = totinfluence; + for (b = 0; b < verts_num; b++) { + mmd->bindoffsets[b] = influences_num; totweight = 0.0f; /* sum total weight */ - for (a = 0; a < totcagevert; a++) { - weight = weights[a + b * totcagevert]; + for (a = 0; a < cage_verts_num; a++) { + weight = weights[a + b * cage_verts_num]; if (weight > MESHDEFORM_MIN_INFLUENCE) { totweight += weight; @@ -527,18 +527,18 @@ void BKE_modifier_mdef_compact_influences(ModifierData *md) } /* assign weights normalized */ - for (a = 0; a < totcagevert; a++) { - weight = weights[a + b * totcagevert]; + for (a = 0; a < cage_verts_num; a++) { + weight = weights[a + b * cage_verts_num]; if (weight > MESHDEFORM_MIN_INFLUENCE) { - mmd->bindinfluences[totinfluence].weight = weight / totweight; - mmd->bindinfluences[totinfluence].vertex = a; - totinfluence++; + mmd->bindinfluences[influences_num].weight = weight / totweight; + mmd->bindinfluences[influences_num].vertex = a; + influences_num++; } } } - mmd->bindoffsets[b] = totinfluence; + mmd->bindoffsets[b] = influences_num; /* free */ MEM_freeN(mmd->bindweights); @@ -586,12 +586,12 @@ static void blendWrite(BlendWriter *writer, const ModifierData *md) MeshDeformModifierData *mmd = (MeshDeformModifierData *)md; int size = mmd->dyngridsize; - BLO_write_struct_array(writer, MDefInfluence, mmd->totinfluence, mmd->bindinfluences); - BLO_write_int32_array(writer, mmd->totvert + 1, mmd->bindoffsets); - BLO_write_float3_array(writer, mmd->totcagevert, mmd->bindcagecos); + BLO_write_struct_array(writer, MDefInfluence, mmd->influences_num, mmd->bindinfluences); + BLO_write_int32_array(writer, mmd->verts_num + 1, mmd->bindoffsets); + BLO_write_float3_array(writer, mmd->cage_verts_num, mmd->bindcagecos); BLO_write_struct_array(writer, MDefCell, size * size * size, mmd->dyngrid); - BLO_write_struct_array(writer, MDefInfluence, mmd->totinfluence, mmd->dyninfluences); - BLO_write_int32_array(writer, mmd->totvert, mmd->dynverts); + BLO_write_struct_array(writer, MDefInfluence, mmd->influences_num, mmd->dyninfluences); + BLO_write_int32_array(writer, mmd->verts_num, mmd->dynverts); } static void blendRead(BlendDataReader *reader, ModifierData *md) @@ -599,15 +599,15 @@ static void blendRead(BlendDataReader *reader, ModifierData *md) MeshDeformModifierData *mmd = (MeshDeformModifierData *)md; BLO_read_data_address(reader, &mmd->bindinfluences); - BLO_read_int32_array(reader, mmd->totvert + 1, &mmd->bindoffsets); - BLO_read_float3_array(reader, mmd->totcagevert, &mmd->bindcagecos); + BLO_read_int32_array(reader, mmd->verts_num + 1, &mmd->bindoffsets); + BLO_read_float3_array(reader, mmd->cage_verts_num, &mmd->bindcagecos); BLO_read_data_address(reader, &mmd->dyngrid); BLO_read_data_address(reader, &mmd->dyninfluences); - BLO_read_int32_array(reader, mmd->totvert, &mmd->dynverts); + BLO_read_int32_array(reader, mmd->verts_num, &mmd->dynverts); /* Deprecated storage. */ - BLO_read_float_array(reader, mmd->totvert, &mmd->bindweights); - BLO_read_float3_array(reader, mmd->totcagevert, &mmd->bindcos); + BLO_read_float_array(reader, mmd->verts_num, &mmd->bindweights); + BLO_read_float3_array(reader, mmd->cage_verts_num, &mmd->bindcos); } ModifierTypeInfo modifierType_MeshDeform = { diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.cc b/source/blender/modifiers/intern/MOD_meshsequencecache.cc index c30ab622842..cfc5b17f37e 100644 --- a/source/blender/modifiers/intern/MOD_meshsequencecache.cc +++ b/source/blender/modifiers/intern/MOD_meshsequencecache.cc @@ -4,7 +4,7 @@ * \ingroup modifiers */ -#include <string.h> +#include <cstring> #include "BLI_math_vector.h" #include "BLI_string.h" diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c index cc6f23073a3..a4c5ddac5c9 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -281,7 +281,7 @@ static void deformMatrices(ModifierData *md, Mesh *mesh, float (*vertex_cos)[3], float (*deform_matrices)[3][3], - int num_verts) + int verts_num) { #if !defined(WITH_OPENSUBDIV) @@ -313,7 +313,7 @@ static void deformMatrices(ModifierData *md, return; } BKE_subdiv_displacement_attach_from_multires(subdiv, mesh, mmd); - BKE_subdiv_deform_coarse_vertices(subdiv, mesh, vertex_cos, num_verts); + BKE_subdiv_deform_coarse_vertices(subdiv, mesh, vertex_cos, verts_num); if (subdiv != runtime_data->subdiv) { BKE_subdiv_free(subdiv); } diff --git a/source/blender/modifiers/intern/MOD_normal_edit.c b/source/blender/modifiers/intern/MOD_normal_edit.c index 94b35c42247..fe05f48a868 100644 --- a/source/blender/modifiers/intern/MOD_normal_edit.c +++ b/source/blender/modifiers/intern/MOD_normal_edit.c @@ -43,7 +43,7 @@ static void generate_vert_coordinates(Mesh *mesh, Object *ob, Object *ob_center, const float offset[3], - const int num_verts, + const int verts_num, float (*r_cos)[3], float r_size[3]) { @@ -108,7 +108,7 @@ static void generate_vert_coordinates(Mesh *mesh, /* Else, no need to change coordinates! */ if (do_diff) { - int i = num_verts; + int i = verts_num; while (i--) { add_v3_v3(r_cos[i], diff); } @@ -122,11 +122,11 @@ static void mix_normals(const float mix_factor, const bool use_invert_vgroup, const float mix_limit, const short mix_mode, - const int num_verts, + const int verts_num, MLoop *mloop, float (*nos_old)[3], float (*nos_new)[3], - const int num_loops) + const int loops_num) { /* Mix with org normals... */ float *facs = NULL, *wfac; @@ -134,12 +134,12 @@ static void mix_normals(const float mix_factor, int i; if (dvert) { - facs = MEM_malloc_arrayN((size_t)num_loops, sizeof(*facs), __func__); + facs = MEM_malloc_arrayN((size_t)loops_num, sizeof(*facs), __func__); BKE_defvert_extract_vgroup_to_loopweights( - dvert, defgrp_index, num_verts, mloop, num_loops, facs, use_invert_vgroup); + dvert, defgrp_index, verts_num, mloop, loops_num, facs, use_invert_vgroup); } - for (i = num_loops, no_new = nos_new, no_old = nos_old, wfac = facs; i--; + for (i = loops_num, no_new = nos_new, no_old = nos_old, wfac = facs; i--; no_new++, no_old++, wfac++) { const float fac = facs ? *wfac * mix_factor : mix_factor; @@ -177,14 +177,14 @@ static bool polygons_check_flip(MLoop *mloop, CustomData *ldata, MPoly *mpoly, float (*polynors)[3], - const int num_polys) + const int polys_num) { MPoly *mp; MDisps *mdisp = CustomData_get_layer(ldata, CD_MDISPS); int i; bool flipped = false; - for (i = 0, mp = mpoly; i < num_polys; i++, mp++) { + for (i = 0, mp = mpoly; i < polys_num; i++, mp++) { float norsum[3] = {0.0f}; float(*no)[3]; int j; @@ -222,26 +222,26 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd, const int defgrp_index, const bool use_invert_vgroup, MVert *mvert, - const int num_verts, + const int verts_num, MEdge *medge, - const int num_edges, + const int edges_num, MLoop *mloop, - const int num_loops, + const int loops_num, MPoly *mpoly, - const int num_polys) + const int polys_num) { Object *ob_target = enmd->target; const bool do_polynors_fix = (enmd->flag & MOD_NORMALEDIT_NO_POLYNORS_FIX) == 0; int i; - float(*cos)[3] = MEM_malloc_arrayN((size_t)num_verts, sizeof(*cos), __func__); - float(*nos)[3] = MEM_malloc_arrayN((size_t)num_loops, sizeof(*nos), __func__); + float(*cos)[3] = MEM_malloc_arrayN((size_t)verts_num, sizeof(*cos), __func__); + float(*nos)[3] = MEM_malloc_arrayN((size_t)loops_num, sizeof(*nos), __func__); float size[3]; - BLI_bitmap *done_verts = BLI_BITMAP_NEW((size_t)num_verts, __func__); + BLI_bitmap *done_verts = BLI_BITMAP_NEW((size_t)verts_num, __func__); - generate_vert_coordinates(mesh, ob, ob_target, enmd->offset, num_verts, cos, size); + generate_vert_coordinates(mesh, ob, ob_target, enmd->offset, verts_num, cos, size); /** * size gives us our spheroid coefficients `(A, B, C)`. @@ -283,7 +283,7 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd, float(*no)[3]; /* We reuse cos to now store the ellipsoid-normal of the verts! */ - for (i = num_loops, ml = mloop, no = nos; i--; ml++, no++) { + for (i = loops_num, ml = mloop, no = nos; i--; ml++, no++) { const int vidx = ml->v; float *co = cos[vidx]; @@ -313,31 +313,31 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd, use_invert_vgroup, mix_limit, mix_mode, - num_verts, + verts_num, mloop, loopnors, nos, - num_loops); + loops_num); } if (do_polynors_fix && polygons_check_flip( - mloop, nos, &mesh->ldata, mpoly, BKE_mesh_poly_normals_for_write(mesh), num_polys)) { + mloop, nos, &mesh->ldata, mpoly, BKE_mesh_poly_normals_for_write(mesh), polys_num)) { /* We need to recompute vertex normals! */ BKE_mesh_normals_tag_dirty(mesh); } BKE_mesh_normals_loop_custom_set(mvert, BKE_mesh_vertex_normals_ensure(mesh), - num_verts, + verts_num, medge, - num_edges, + edges_num, mloop, nos, - num_loops, + loops_num, mpoly, polynors, - num_polys, + polys_num, clnors); MEM_freeN(cos); @@ -359,20 +359,20 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd, const int defgrp_index, const bool use_invert_vgroup, MVert *mvert, - const int num_verts, + const int verts_num, MEdge *medge, - const int num_edges, + const int edges_num, MLoop *mloop, - const int num_loops, + const int loops_num, MPoly *mpoly, - const int num_polys) + const int polys_num) { Object *ob_target = enmd->target; const bool do_polynors_fix = (enmd->flag & MOD_NORMALEDIT_NO_POLYNORS_FIX) == 0; const bool use_parallel_normals = (enmd->flag & MOD_NORMALEDIT_USE_DIRECTION_PARALLEL) != 0; - float(*nos)[3] = MEM_malloc_arrayN((size_t)num_loops, sizeof(*nos), __func__); + float(*nos)[3] = MEM_malloc_arrayN((size_t)loops_num, sizeof(*nos), __func__); float target_co[3]; int i; @@ -390,20 +390,20 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd, sub_v3_v3v3(no, target_co, enmd->offset); normalize_v3(no); - for (i = num_loops; i--;) { + for (i = loops_num; i--;) { copy_v3_v3(nos[i], no); } } else { - float(*cos)[3] = MEM_malloc_arrayN((size_t)num_verts, sizeof(*cos), __func__); - generate_vert_coordinates(mesh, ob, ob_target, NULL, num_verts, cos, NULL); + float(*cos)[3] = MEM_malloc_arrayN((size_t)verts_num, sizeof(*cos), __func__); + generate_vert_coordinates(mesh, ob, ob_target, NULL, verts_num, cos, NULL); - BLI_bitmap *done_verts = BLI_BITMAP_NEW((size_t)num_verts, __func__); + BLI_bitmap *done_verts = BLI_BITMAP_NEW((size_t)verts_num, __func__); MLoop *ml; float(*no)[3]; /* We reuse cos to now store the 'to target' normal of the verts! */ - for (i = num_loops, no = nos, ml = mloop; i--; no++, ml++) { + for (i = loops_num, no = nos, ml = mloop; i--; no++, ml++) { const int vidx = ml->v; float *co = cos[vidx]; @@ -428,30 +428,30 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd, use_invert_vgroup, mix_limit, mix_mode, - num_verts, + verts_num, mloop, loopnors, nos, - num_loops); + loops_num); } if (do_polynors_fix && polygons_check_flip( - mloop, nos, &mesh->ldata, mpoly, BKE_mesh_poly_normals_for_write(mesh), num_polys)) { + mloop, nos, &mesh->ldata, mpoly, BKE_mesh_poly_normals_for_write(mesh), polys_num)) { BKE_mesh_normals_tag_dirty(mesh); } BKE_mesh_normals_loop_custom_set(mvert, BKE_mesh_vertex_normals_ensure(mesh), - num_verts, + verts_num, medge, - num_edges, + edges_num, mloop, nos, - num_loops, + loops_num, mpoly, polynors, - num_polys, + polys_num, clnors); MEM_freeN(nos); @@ -519,10 +519,10 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, result = mesh; } - const int num_verts = result->totvert; - const int num_edges = result->totedge; - const int num_loops = result->totloop; - const int num_polys = result->totpoly; + const int verts_num = result->totvert; + const int edges_num = result->totedge; + const int loops_num = result->totloop; + const int polys_num = result->totpoly; MVert *mvert = result->mvert; MEdge *medge = result->medge; MLoop *mloop = result->mloop; @@ -541,20 +541,20 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, clnors = CustomData_get_layer(ldata, CD_CUSTOMLOOPNORMAL); if (use_current_clnors) { - clnors = CustomData_duplicate_referenced_layer(ldata, CD_CUSTOMLOOPNORMAL, num_loops); - loopnors = MEM_malloc_arrayN((size_t)num_loops, sizeof(*loopnors), __func__); + clnors = CustomData_duplicate_referenced_layer(ldata, CD_CUSTOMLOOPNORMAL, loops_num); + loopnors = MEM_malloc_arrayN((size_t)loops_num, sizeof(*loopnors), __func__); BKE_mesh_normals_loop_split(mvert, vert_normals, - num_verts, + verts_num, medge, - num_edges, + edges_num, mloop, loopnors, - num_loops, + loops_num, mpoly, poly_normals, - num_polys, + polys_num, true, result->smoothresh, NULL, @@ -563,7 +563,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, } if (clnors == NULL) { - clnors = CustomData_add_layer(ldata, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, num_loops); + clnors = CustomData_add_layer(ldata, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, loops_num); } MOD_get_vgroup(ob, result, enmd->defgrp_name, &dvert, &defgrp_index); @@ -583,13 +583,13 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, defgrp_index, use_invert_vgroup, mvert, - num_verts, + verts_num, medge, - num_edges, + edges_num, mloop, - num_loops, + loops_num, mpoly, - num_polys); + polys_num); } else if (enmd->mode == MOD_NORMALEDIT_MODE_DIRECTIONAL) { normalEditModifier_do_directional(enmd, @@ -606,13 +606,13 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, defgrp_index, use_invert_vgroup, mvert, - num_verts, + verts_num, medge, - num_edges, + edges_num, mloop, - num_loops, + loops_num, mpoly, - num_polys); + polys_num); } MEM_SAFE_FREE(loopnors); diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c index c1423347413..6ded702ceda 100644 --- a/source/blender/modifiers/intern/MOD_ocean.c +++ b/source/blender/modifiers/intern/MOD_ocean.c @@ -249,8 +249,8 @@ static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig, co GenerateOceanGeometryData gogd; - int num_verts; - int num_polys; + int verts_num; + int polys_num; const bool use_threading = resolution > 4; @@ -259,8 +259,8 @@ static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig, co gogd.res_x = gogd.rx * omd->repeat_x; gogd.res_y = gogd.ry * omd->repeat_y; - num_verts = (gogd.res_x + 1) * (gogd.res_y + 1); - num_polys = gogd.res_x * gogd.res_y; + verts_num = (gogd.res_x + 1) * (gogd.res_y + 1); + polys_num = gogd.res_x * gogd.res_y; gogd.sx = omd->size * omd->spatial_size; gogd.sy = omd->size * omd->spatial_size; @@ -270,7 +270,7 @@ static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig, co gogd.sx /= gogd.rx; gogd.sy /= gogd.ry; - result = BKE_mesh_new_nomain(num_verts, 0, 0, num_polys * 4, num_polys); + result = BKE_mesh_new_nomain(verts_num, 0, 0, polys_num * 4, polys_num); BKE_mesh_copy_parameters_for_eval(result, mesh_orig); gogd.mverts = result->mvert; @@ -292,7 +292,7 @@ static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig, co /* add uvs */ if (CustomData_number_of_layers(&result->ldata, CD_MLOOPUV) < MAX_MTFACE) { gogd.mloopuvs = CustomData_add_layer( - &result->ldata, CD_MLOOPUV, CD_CALLOC, NULL, num_polys * 4); + &result->ldata, CD_MLOOPUV, CD_CALLOC, NULL, polys_num * 4); if (gogd.mloopuvs) { /* unlikely to fail */ gogd.ix = 1.0 / gogd.rx; @@ -377,23 +377,23 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes if (omd->flag & MOD_OCEAN_GENERATE_FOAM) { if (CustomData_number_of_layers(&result->ldata, CD_MLOOPCOL) < MAX_MCOL) { - const int num_polys = result->totpoly; - const int num_loops = result->totloop; + const int polys_num = result->totpoly; + const int loops_num = result->totloop; MLoop *mloops = result->mloop; MLoopCol *mloopcols = CustomData_add_layer_named( - &result->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, num_loops, omd->foamlayername); + &result->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, loops_num, omd->foamlayername); MLoopCol *mloopcols_spray = NULL; if (omd->flag & MOD_OCEAN_GENERATE_SPRAY) { mloopcols_spray = CustomData_add_layer_named( - &result->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, num_loops, omd->spraylayername); + &result->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, loops_num, omd->spraylayername); } if (mloopcols) { /* unlikely to fail */ MPoly *mpolys = result->mpoly; MPoly *mp; - for (i = 0, mp = mpolys; i < num_polys; i++, mp++) { + for (i = 0, mp = mpolys; i < polys_num; i++, mp++) { MLoop *ml = &mloops[mp->loopstart]; MLoopCol *mlcol = &mloopcols[mp->loopstart]; @@ -449,9 +449,9 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes /* NOTE: tried to parallelized that one and previous foam loop, * but gives 20% slower results... odd. */ { - const int num_verts = result->totvert; + const int verts_num = result->totvert; - for (i = 0; i < num_verts; i++) { + for (i = 0; i < verts_num; i++) { float *vco = mverts[i].co; const float u = OCEAN_CO(size_co_inv, vco[0]); const float v = OCEAN_CO(size_co_inv, vco[1]); diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c index 6c2651bae1f..7df7ba7c1db 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.c +++ b/source/blender/modifiers/intern/MOD_particlesystem.c @@ -100,7 +100,7 @@ static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { Mesh *mesh_src = mesh; ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; @@ -118,7 +118,8 @@ static void deformVerts(ModifierData *md, } if (mesh_src == NULL) { - mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, NULL, vertexCos, numVerts, false, true); + mesh_src = MOD_deform_mesh_eval_get( + ctx->object, NULL, NULL, vertexCos, verts_num, false, true); if (mesh_src == NULL) { return; } @@ -235,7 +236,7 @@ static void deformVertsEM(ModifierData *md, BMEditMesh *editData, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { const bool do_temp_mesh = (mesh == NULL); if (do_temp_mesh) { @@ -243,7 +244,7 @@ static void deformVertsEM(ModifierData *md, BM_mesh_bm_to_me(NULL, editData->bm, mesh, &((BMeshToMeshParams){0})); } - deformVerts(md, ob, mesh, vertexCos, numVerts); + deformVerts(md, ob, mesh, vertexCos, verts_num); if (derivedData) { BKE_id_free(NULL, mesh); diff --git a/source/blender/modifiers/intern/MOD_shapekey.c b/source/blender/modifiers/intern/MOD_shapekey.c index 5d6be527b2d..6953e89dfc2 100644 --- a/source/blender/modifiers/intern/MOD_shapekey.c +++ b/source/blender/modifiers/intern/MOD_shapekey.c @@ -27,14 +27,14 @@ static void deformVerts(ModifierData *UNUSED(md), const ModifierEvalContext *ctx, Mesh *UNUSED(mesh), float (*vertexCos)[3], - int numVerts) + int verts_num) { Key *key = BKE_key_from_object(ctx->object); if (key && key->block.first) { int deformedVerts_tot; BKE_key_evaluate_object_ex( - ctx->object, &deformedVerts_tot, (float *)vertexCos, sizeof(*vertexCos) * numVerts); + ctx->object, &deformedVerts_tot, (float *)vertexCos, sizeof(*vertexCos) * verts_num); } } @@ -43,7 +43,7 @@ static void deformMatrices(ModifierData *md, Mesh *mesh, float (*vertexCos)[3], float (*defMats)[3][3], - int numVerts) + int verts_num) { Key *key = BKE_key_from_object(ctx->object); KeyBlock *kb = BKE_keyblock_from_object(ctx->object); @@ -51,7 +51,7 @@ static void deformMatrices(ModifierData *md, (void)vertexCos; /* unused */ - if (kb && kb->totelem == numVerts && kb != key->refkey) { + if (kb && kb->totelem == verts_num && kb != key->refkey) { int a; if (ctx->object->shapeflag & OB_SHAPE_LOCK) { @@ -61,12 +61,12 @@ static void deformMatrices(ModifierData *md, scale_m3_fl(scale, kb->curval); } - for (a = 0; a < numVerts; a++) { + for (a = 0; a < verts_num; a++) { copy_m3_m3(defMats[a], scale); } } - deformVerts(md, ctx, mesh, vertexCos, numVerts); + deformVerts(md, ctx, mesh, vertexCos, verts_num); } static void deformVertsEM(ModifierData *md, @@ -74,12 +74,12 @@ static void deformVertsEM(ModifierData *md, struct BMEditMesh *UNUSED(editData), Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { Key *key = BKE_key_from_object(ctx->object); if (key && key->type == KEY_RELATIVE) { - deformVerts(md, ctx, mesh, vertexCos, numVerts); + deformVerts(md, ctx, mesh, vertexCos, verts_num); } } @@ -89,7 +89,7 @@ static void deformMatricesEM(ModifierData *UNUSED(md), Mesh *UNUSED(mesh), float (*vertexCos)[3], float (*defMats)[3][3], - int numVerts) + int verts_num) { Key *key = BKE_key_from_object(ctx->object); KeyBlock *kb = BKE_keyblock_from_object(ctx->object); @@ -97,11 +97,11 @@ static void deformMatricesEM(ModifierData *UNUSED(md), (void)vertexCos; /* unused */ - if (kb && kb->totelem == numVerts && kb != key->refkey) { + if (kb && kb->totelem == verts_num && kb != key->refkey) { int a; scale_m3_fl(scale, kb->curval); - for (a = 0; a < numVerts; a++) { + for (a = 0; a < verts_num; a++) { copy_m3_m3(defMats[a], scale); } } diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c index 21f8f90585d..488df3d6f4c 100644 --- a/source/blender/modifiers/intern/MOD_shrinkwrap.c +++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c @@ -98,7 +98,7 @@ static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { ShrinkwrapModifierData *swmd = (ShrinkwrapModifierData *)md; struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); @@ -108,7 +108,7 @@ static void deformVerts(ModifierData *md, (swmd->shrinkType == MOD_SHRINKWRAP_PROJECT)) { /* mesh_src is needed for vgroups, but also used as ShrinkwrapCalcData.vert when projecting. * Avoid time-consuming mesh conversion for curves when not projecting. */ - mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false); + mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false, false); } struct MDeformVert *dvert = NULL; @@ -116,7 +116,7 @@ static void deformVerts(ModifierData *md, MOD_get_vgroup(ctx->object, mesh_src, swmd->vgroup_name, &dvert, &defgrp_index); shrinkwrapModifier_deform( - swmd, ctx, scene, ctx->object, mesh_src, dvert, defgrp_index, vertexCos, numVerts); + swmd, ctx, scene, ctx->object, mesh_src, dvert, defgrp_index, vertexCos, verts_num); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); @@ -128,14 +128,15 @@ static void deformVertsEM(ModifierData *md, struct BMEditMesh *editData, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { ShrinkwrapModifierData *swmd = (ShrinkwrapModifierData *)md; struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); Mesh *mesh_src = NULL; if ((swmd->vgroup_name[0] != '\0') || (swmd->shrinkType == MOD_SHRINKWRAP_PROJECT)) { - mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false); + mesh_src = MOD_deform_mesh_eval_get( + ctx->object, editData, mesh, NULL, verts_num, false, false); } /* TODO(Campbell): use edit-mode data only (remove this line). */ @@ -150,7 +151,7 @@ static void deformVertsEM(ModifierData *md, } shrinkwrapModifier_deform( - swmd, ctx, scene, ctx->object, mesh_src, dvert, defgrp_index, vertexCos, numVerts); + swmd, ctx, scene, ctx->object, mesh_src, dvert, defgrp_index, vertexCos, verts_num); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c index 4fbef6f54ae..e3c7f1c423b 100644 --- a/source/blender/modifiers/intern/MOD_simpledeform.c +++ b/source/blender/modifiers/intern/MOD_simpledeform.c @@ -288,7 +288,7 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object *ob, struct Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { int i; float smd_limit[2], smd_factor; @@ -355,7 +355,7 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, float lower = FLT_MAX; float upper = -FLT_MAX; - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { float tmp[3]; copy_v3_v3(tmp, vertexCos[i]); @@ -401,7 +401,7 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, /* Do deformation. */ TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); - BLI_task_parallel_range(0, numVerts, (void *)&deform_pool_data, simple_helper, &settings); + BLI_task_parallel_range(0, verts_num, (void *)&deform_pool_data, simple_helper, &settings); } /* SimpleDeform */ @@ -446,17 +446,17 @@ static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, struct Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { SimpleDeformModifierData *sdmd = (SimpleDeformModifierData *)md; Mesh *mesh_src = NULL; if (ctx->object->type == OB_MESH && sdmd->vgroup_name[0] != '\0') { /* mesh_src is only needed for vgroups. */ - mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false); + mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false, false); } - SimpleDeformModifier_do(sdmd, ctx, ctx->object, mesh_src, vertexCos, numVerts); + SimpleDeformModifier_do(sdmd, ctx, ctx->object, mesh_src, vertexCos, verts_num); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); @@ -468,14 +468,15 @@ static void deformVertsEM(ModifierData *md, struct BMEditMesh *editData, struct Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { SimpleDeformModifierData *sdmd = (SimpleDeformModifierData *)md; Mesh *mesh_src = NULL; if (ctx->object->type == OB_MESH && sdmd->vgroup_name[0] != '\0') { /* mesh_src is only needed for vgroups. */ - mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false); + mesh_src = MOD_deform_mesh_eval_get( + ctx->object, editData, mesh, NULL, verts_num, false, false); } /* TODO(Campbell): use edit-mode data only (remove this line). */ @@ -483,7 +484,7 @@ static void deformVertsEM(ModifierData *md, BKE_mesh_wrapper_ensure_mdata(mesh_src); } - SimpleDeformModifier_do(sdmd, ctx, ctx->object, mesh_src, vertexCos, numVerts); + SimpleDeformModifier_do(sdmd, ctx, ctx->object, mesh_src, vertexCos, verts_num); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index e42223e2ad5..b950578ff1b 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -450,18 +450,18 @@ static Frame **collect_hull_frames( { SkinNode *f; Frame **hull_frames; - int nbr, i; + int hull_frames_num, i; (*tothullframe) = emap[v].count; hull_frames = MEM_calloc_arrayN( (*tothullframe), sizeof(Frame *), "hull_from_frames.hull_frames"); - i = 0; - for (nbr = 0; nbr < emap[v].count; nbr++) { - const MEdge *e = &medge[emap[v].indices[nbr]]; + hull_frames_num = 0; + for (i = 0; i < emap[v].count; i++) { + const MEdge *e = &medge[emap[v].indices[i]]; f = &frames[BKE_mesh_edge_other_vert(e, v)]; /* Can't have adjacent branch nodes yet */ if (f->totframe) { - hull_frames[i++] = &f->frames[0]; + hull_frames[hull_frames_num++] = &f->frames[0]; } else { (*tothullframe)--; @@ -649,14 +649,14 @@ static void connection_node_frames(int v, } static SkinNode *build_frames( - const MVert *mvert, int totvert, const MVertSkin *nodes, const MeshElemMap *emap, EMat *emat) + const MVert *mvert, int verts_num, const MVertSkin *nodes, const MeshElemMap *emap, EMat *emat) { SkinNode *skin_nodes; int v; - skin_nodes = MEM_calloc_arrayN(totvert, sizeof(SkinNode), "build_frames.skin_nodes"); + skin_nodes = MEM_calloc_arrayN(verts_num, sizeof(SkinNode), "build_frames.skin_nodes"); - for (v = 0; v < totvert; v++) { + for (v = 0; v < verts_num; v++) { if (emap[v].count <= 1) { end_node_frames(v, skin_nodes, mvert, nodes, emap, emat); } @@ -766,10 +766,10 @@ static void build_emats_stack(BLI_Stack *stack, static EMat *build_edge_mats(const MVertSkin *vs, const MVert *mvert, - int totvert, + const int verts_num, const MEdge *medge, const MeshElemMap *emap, - int totedge, + const int edges_num, bool *has_valid_root) { BLI_Stack *stack; @@ -780,12 +780,12 @@ static EMat *build_edge_mats(const MVertSkin *vs, stack = BLI_stack_new(sizeof(stack_elem), "build_edge_mats.stack"); - visited_e = BLI_BITMAP_NEW(totedge, "build_edge_mats.visited_e"); - emat = MEM_calloc_arrayN(totedge, sizeof(EMat), "build_edge_mats.emat"); + visited_e = BLI_BITMAP_NEW(edges_num, "build_edge_mats.visited_e"); + emat = MEM_calloc_arrayN(edges_num, sizeof(EMat), "build_edge_mats.emat"); /* Edge matrices are built from the root nodes, add all roots with * children to the stack */ - for (v = 0; v < totvert; v++) { + for (v = 0; v < verts_num; v++) { if (vs[v].flag & MVERT_SKIN_ROOT) { if (emap[v].count >= 1) { const MEdge *e = &medge[emap[v].indices[0]]; @@ -800,7 +800,7 @@ static EMat *build_edge_mats(const MVertSkin *vs, *has_valid_root = true; } - else if (totedge == 0) { + else if (edges_num == 0) { /* Vertex-only mesh is valid, mark valid root as well (will display error otherwise). */ *has_valid_root = true; break; @@ -837,7 +837,7 @@ static int calc_edge_subdivisions(const MVert *mvert, float avg_radius; const bool v1_branch = degree[e->v1] > 2; const bool v2_branch = degree[e->v2] > 2; - int num_subdivisions; + int subdivisions_num; /* If either end is a branch node marked 'loose', don't subdivide * the edge (or subdivide just twice if both are branches) */ @@ -854,27 +854,27 @@ static int calc_edge_subdivisions(const MVert *mvert, if (avg_radius != 0.0f) { /* possible (but unlikely) that we overflow INT_MAX */ - float num_subdivisions_fl; + float subdivisions_num_fl; const float edge_len = len_v3v3(mvert[e->v1].co, mvert[e->v2].co); - num_subdivisions_fl = (edge_len / avg_radius); - if (num_subdivisions_fl < NUM_SUBDIVISIONS_MAX) { - num_subdivisions = (int)num_subdivisions_fl; + subdivisions_num_fl = (edge_len / avg_radius); + if (subdivisions_num_fl < NUM_SUBDIVISIONS_MAX) { + subdivisions_num = (int)subdivisions_num_fl; } else { - num_subdivisions = NUM_SUBDIVISIONS_MAX; + subdivisions_num = NUM_SUBDIVISIONS_MAX; } } else { - num_subdivisions = 0; + subdivisions_num = 0; } /* If both ends are branch nodes, two intermediate nodes are * required */ - if (num_subdivisions < 2 && v1_branch && v2_branch) { - num_subdivisions = 2; + if (subdivisions_num < 2 && v1_branch && v2_branch) { + subdivisions_num = 2; } - return num_subdivisions; + return subdivisions_num; #undef NUM_SUBDIVISIONS_MAX } @@ -888,8 +888,8 @@ static Mesh *subdivide_base(Mesh *orig) MVert *origvert, *outvert; MEdge *origedge, *outedge, *e; MDeformVert *origdvert, *outdvert; - int totorigvert, totorigedge; - int totsubd, *degree, *edge_subd; + int orig_vert_num, orig_edge_num; + int subd_num, *degree, *edge_subd; int i, j, k, u, v; float radrat; @@ -897,29 +897,29 @@ static Mesh *subdivide_base(Mesh *orig) origvert = orig->mvert; origedge = orig->medge; origdvert = orig->dvert; - totorigvert = orig->totvert; - totorigedge = orig->totedge; + orig_vert_num = orig->totvert; + orig_edge_num = orig->totedge; /* Get degree of all vertices */ - degree = MEM_calloc_arrayN(totorigvert, sizeof(int), "degree"); - for (i = 0; i < totorigedge; i++) { + degree = MEM_calloc_arrayN(orig_vert_num, sizeof(int), "degree"); + for (i = 0; i < orig_edge_num; i++) { degree[origedge[i].v1]++; degree[origedge[i].v2]++; } /* Per edge, store how many subdivisions are needed */ - edge_subd = MEM_calloc_arrayN((uint)totorigedge, sizeof(int), "edge_subd"); - for (i = 0, totsubd = 0; i < totorigedge; i++) { + edge_subd = MEM_calloc_arrayN((uint)orig_edge_num, sizeof(int), "edge_subd"); + for (i = 0, subd_num = 0; i < orig_edge_num; i++) { edge_subd[i] += calc_edge_subdivisions(origvert, orignode, &origedge[i], degree); BLI_assert(edge_subd[i] >= 0); - totsubd += edge_subd[i]; + subd_num += edge_subd[i]; } MEM_freeN(degree); /* Allocate output mesh */ result = BKE_mesh_new_nomain_from_template( - orig, totorigvert + totsubd, totorigedge + totsubd, 0, 0, 0); + orig, orig_vert_num + subd_num, orig_edge_num + subd_num, 0, 0, 0); outvert = result->mvert; outedge = result->medge; @@ -927,16 +927,16 @@ static Mesh *subdivide_base(Mesh *orig) outdvert = result->dvert; /* Copy original vertex data */ - CustomData_copy_data(&orig->vdata, &result->vdata, 0, 0, totorigvert); + CustomData_copy_data(&orig->vdata, &result->vdata, 0, 0, orig_vert_num); /* Subdivide edges */ - for (i = 0, v = totorigvert; i < totorigedge; i++) { + for (i = 0, v = orig_vert_num; i < orig_edge_num; i++) { struct { /* Vertex group number */ int def_nr; float w1, w2; } *vgroups = NULL, *vg; - int totvgroup = 0; + int vgroups_num = 0; e = &origedge[i]; @@ -950,8 +950,8 @@ static Mesh *subdivide_base(Mesh *orig) vg = NULL; for (k = 0; k < dv2->totweight; k++) { if (dv1->dw[j].def_nr == dv2->dw[k].def_nr) { - vg = &vgroups[totvgroup]; - totvgroup++; + vg = &vgroups[vgroups_num]; + vgroups_num++; break; } } @@ -986,7 +986,7 @@ static Mesh *subdivide_base(Mesh *orig) interp_v3_v3v3(outnode[v].radius, orignode[e->v1].radius, orignode[e->v2].radius, t); /* Interpolate vertex group weights */ - for (k = 0; k < totvgroup; k++) { + for (k = 0; k < vgroups_num; k++) { float weight; vg = &vgroups[k]; @@ -1561,14 +1561,14 @@ static void hull_merge_triangles(SkinOutput *so, const SkinModifierData *smd) } static void skin_merge_close_frame_verts(SkinNode *skin_nodes, - int totvert, + int verts_num, const MeshElemMap *emap, const MEdge *medge) { Frame **hull_frames; int v, tothullframe; - for (v = 0; v < totvert; v++) { + for (v = 0; v < verts_num; v++) { /* Only check branch nodes */ if (!skin_nodes[v].totframe) { hull_frames = collect_hull_frames(v, skin_nodes, emap, medge, &tothullframe); @@ -1578,11 +1578,11 @@ static void skin_merge_close_frame_verts(SkinNode *skin_nodes, } } -static void skin_update_merged_vertices(SkinNode *skin_nodes, int totvert) +static void skin_update_merged_vertices(SkinNode *skin_nodes, int verts_num) { int v; - for (v = 0; v < totvert; v++) { + for (v = 0; v < verts_num; v++) { SkinNode *sn = &skin_nodes[v]; int i, j; @@ -1601,11 +1601,11 @@ static void skin_update_merged_vertices(SkinNode *skin_nodes, int totvert) } } -static void skin_fix_hull_topology(BMesh *bm, SkinNode *skin_nodes, int totvert) +static void skin_fix_hull_topology(BMesh *bm, SkinNode *skin_nodes, int verts_num) { int v; - for (v = 0; v < totvert; v++) { + for (v = 0; v < verts_num; v++) { SkinNode *sn = &skin_nodes[v]; int j; @@ -1626,11 +1626,11 @@ static void skin_fix_hull_topology(BMesh *bm, SkinNode *skin_nodes, int totvert) } } -static void skin_output_end_nodes(SkinOutput *so, SkinNode *skin_nodes, int totvert) +static void skin_output_end_nodes(SkinOutput *so, SkinNode *skin_nodes, int verts_num) { int v; - for (v = 0; v < totvert; v++) { + for (v = 0; v < verts_num; v++) { SkinNode *sn = &skin_nodes[v]; /* Assuming here just two frames */ if (sn->flag & SEAM_FRAME) { @@ -1676,11 +1676,11 @@ static void skin_output_end_nodes(SkinOutput *so, SkinNode *skin_nodes, int totv static void skin_output_connections(SkinOutput *so, SkinNode *skin_nodes, const MEdge *medge, - int totedge) + int edges_num) { int e; - for (e = 0; e < totedge; e++) { + for (e = 0; e < edges_num; e++) { SkinNode *a, *b; a = &skin_nodes[medge[e].v1]; b = &skin_nodes[medge[e].v2]; @@ -1713,7 +1713,7 @@ static void skin_output_connections(SkinOutput *so, static void skin_smooth_hulls(BMesh *bm, SkinNode *skin_nodes, - int totvert, + int verts_num, const SkinModifierData *smd) { BMIter iter, eiter; @@ -1726,7 +1726,7 @@ static void skin_smooth_hulls(BMesh *bm, /* Mark all frame vertices */ BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false); - for (i = 0; i < totvert; i++) { + for (i = 0; i < verts_num; i++) { for (j = 0; j < skin_nodes[i].totframe; j++) { Frame *frame = &skin_nodes[i].frames[j]; @@ -1780,13 +1780,16 @@ static void skin_smooth_hulls(BMesh *bm, } /* Returns true if all hulls are successfully built, false otherwise */ -static bool skin_output_branch_hulls( - SkinOutput *so, SkinNode *skin_nodes, int totvert, const MeshElemMap *emap, const MEdge *medge) +static bool skin_output_branch_hulls(SkinOutput *so, + SkinNode *skin_nodes, + int verts_num, + const MeshElemMap *emap, + const MEdge *medge) { bool result = true; int v; - for (v = 0; v < totvert; v++) { + for (v = 0; v < verts_num; v++) { SkinNode *sn = &skin_nodes[v]; /* Branch node hulls */ @@ -1812,10 +1815,10 @@ typedef enum eSkinErrorFlag { } eSkinErrorFlag; static BMesh *build_skin(SkinNode *skin_nodes, - int totvert, + int verts_num, const MeshElemMap *emap, const MEdge *medge, - int totedge, + int edges_num, const MDeformVert *input_dvert, SkinModifierData *smd, eSkinErrorFlag *r_error) @@ -1841,19 +1844,19 @@ static BMesh *build_skin(SkinNode *skin_nodes, /* Check for mergeable frame corners around hulls before * outputting vertices */ - skin_merge_close_frame_verts(skin_nodes, totvert, emap, medge); + skin_merge_close_frame_verts(skin_nodes, verts_num, emap, medge); /* Write out all frame vertices to the mesh */ - for (v = 0; v < totvert; v++) { + for (v = 0; v < verts_num; v++) { if (skin_nodes[v].totframe) { output_frames(so.bm, &skin_nodes[v], input_dvert ? &input_dvert[v] : NULL); } } /* Update vertex pointers for merged frame corners */ - skin_update_merged_vertices(skin_nodes, totvert); + skin_update_merged_vertices(skin_nodes, verts_num); - if (!skin_output_branch_hulls(&so, skin_nodes, totvert, emap, medge)) { + if (!skin_output_branch_hulls(&so, skin_nodes, verts_num, emap, medge)) { *r_error |= SKIN_ERROR_HULL; } @@ -1871,12 +1874,12 @@ static BMesh *build_skin(SkinNode *skin_nodes, * creating all hull faces, but before creating any other * faces. */ - skin_fix_hull_topology(so.bm, skin_nodes, totvert); + skin_fix_hull_topology(so.bm, skin_nodes, verts_num); - skin_smooth_hulls(so.bm, skin_nodes, totvert, smd); + skin_smooth_hulls(so.bm, skin_nodes, verts_num, smd); - skin_output_end_nodes(&so, skin_nodes, totvert); - skin_output_connections(&so, skin_nodes, medge, totedge); + skin_output_end_nodes(&so, skin_nodes, verts_num); + skin_output_connections(&so, skin_nodes, medge, edges_num); hull_merge_triangles(&so, smd); bmesh_edit_end(so.bm, 0); @@ -1912,7 +1915,7 @@ static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd, eSkinErrorFlag *r_ MVert *mvert; MEdge *medge; MDeformVert *dvert; - int totvert, totedge; + int verts_num, edges_num; bool has_valid_root = false; nodes = CustomData_get_layer(&origmesh->vdata, CD_MVERT_SKIN); @@ -1920,17 +1923,17 @@ static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd, eSkinErrorFlag *r_ mvert = origmesh->mvert; dvert = origmesh->dvert; medge = origmesh->medge; - totvert = origmesh->totvert; - totedge = origmesh->totedge; + verts_num = origmesh->totvert; + edges_num = origmesh->totedge; - BKE_mesh_vert_edge_map_create(&emap, &emapmem, medge, totvert, totedge); + BKE_mesh_vert_edge_map_create(&emap, &emapmem, medge, verts_num, edges_num); - emat = build_edge_mats(nodes, mvert, totvert, medge, emap, totedge, &has_valid_root); - skin_nodes = build_frames(mvert, totvert, nodes, emap, emat); + emat = build_edge_mats(nodes, mvert, verts_num, medge, emap, edges_num, &has_valid_root); + skin_nodes = build_frames(mvert, verts_num, nodes, emap, emat); MEM_freeN(emat); emat = NULL; - bm = build_skin(skin_nodes, totvert, emap, medge, totedge, dvert, smd, r_error); + bm = build_skin(skin_nodes, verts_num, emap, medge, edges_num, dvert, smd, r_error); MEM_freeN(skin_nodes); MEM_freeN(emap); diff --git a/source/blender/modifiers/intern/MOD_smooth.c b/source/blender/modifiers/intern/MOD_smooth.c index 4236147c1f3..5439083d9a7 100644 --- a/source/blender/modifiers/intern/MOD_smooth.c +++ b/source/blender/modifiers/intern/MOD_smooth.c @@ -76,21 +76,21 @@ static void requiredDataMask(Object *UNUSED(ob), } static void smoothModifier_do( - SmoothModifierData *smd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int numVerts) + SmoothModifierData *smd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int verts_num) { if (mesh == NULL) { return; } float(*accumulated_vecs)[3] = MEM_calloc_arrayN( - (size_t)numVerts, sizeof(*accumulated_vecs), __func__); + (size_t)verts_num, sizeof(*accumulated_vecs), __func__); if (!accumulated_vecs) { return; } - uint *num_accumulated_vecs = MEM_calloc_arrayN( - (size_t)numVerts, sizeof(*num_accumulated_vecs), __func__); - if (!num_accumulated_vecs) { + uint *accumulated_vecs_count = MEM_calloc_arrayN( + (size_t)verts_num, sizeof(*accumulated_vecs_count), __func__); + if (!accumulated_vecs_count) { MEM_freeN(accumulated_vecs); return; } @@ -100,7 +100,7 @@ static void smoothModifier_do( const bool invert_vgroup = (smd->flag & MOD_SMOOTH_INVERT_VGROUP) != 0; MEdge *medges = mesh->medge; - const int num_edges = mesh->totedge; + const int edges_num = mesh->totedge; MDeformVert *dvert; int defgrp_index; @@ -108,31 +108,31 @@ static void smoothModifier_do( for (int j = 0; j < smd->repeat; j++) { if (j != 0) { - memset(accumulated_vecs, 0, sizeof(*accumulated_vecs) * (size_t)numVerts); - memset(num_accumulated_vecs, 0, sizeof(*num_accumulated_vecs) * (size_t)numVerts); + memset(accumulated_vecs, 0, sizeof(*accumulated_vecs) * (size_t)verts_num); + memset(accumulated_vecs_count, 0, sizeof(*accumulated_vecs_count) * (size_t)verts_num); } - for (int i = 0; i < num_edges; i++) { + for (int i = 0; i < edges_num; i++) { float fvec[3]; const uint idx1 = medges[i].v1; const uint idx2 = medges[i].v2; mid_v3_v3v3(fvec, vertexCos[idx1], vertexCos[idx2]); - num_accumulated_vecs[idx1]++; + accumulated_vecs_count[idx1]++; add_v3_v3(accumulated_vecs[idx1], fvec); - num_accumulated_vecs[idx2]++; + accumulated_vecs_count[idx2]++; add_v3_v3(accumulated_vecs[idx2], fvec); } const short flag = smd->flag; if (dvert) { MDeformVert *dv = dvert; - for (int i = 0; i < numVerts; i++, dv++) { + for (int i = 0; i < verts_num; i++, dv++) { float *vco_orig = vertexCos[i]; - if (num_accumulated_vecs[i] > 0) { - mul_v3_fl(accumulated_vecs[i], 1.0f / (float)num_accumulated_vecs[i]); + if (accumulated_vecs_count[i] > 0) { + mul_v3_fl(accumulated_vecs[i], 1.0f / (float)accumulated_vecs_count[i]); } float *vco_new = accumulated_vecs[i]; @@ -156,10 +156,10 @@ static void smoothModifier_do( } } else { /* no vertex group */ - for (int i = 0; i < numVerts; i++) { + for (int i = 0; i < verts_num; i++) { float *vco_orig = vertexCos[i]; - if (num_accumulated_vecs[i] > 0) { - mul_v3_fl(accumulated_vecs[i], 1.0f / (float)num_accumulated_vecs[i]); + if (accumulated_vecs_count[i] > 0) { + mul_v3_fl(accumulated_vecs[i], 1.0f / (float)accumulated_vecs_count[i]); } float *vco_new = accumulated_vecs[i]; @@ -177,22 +177,22 @@ static void smoothModifier_do( } MEM_freeN(accumulated_vecs); - MEM_freeN(num_accumulated_vecs); + MEM_freeN(accumulated_vecs_count); } static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { SmoothModifierData *smd = (SmoothModifierData *)md; Mesh *mesh_src = NULL; /* mesh_src is needed for vgroups, and taking edges into account. */ - mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false); + mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false, false); - smoothModifier_do(smd, ctx->object, mesh_src, vertexCos, numVerts); + smoothModifier_do(smd, ctx->object, mesh_src, vertexCos, verts_num); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); @@ -204,18 +204,18 @@ static void deformVertsEM(ModifierData *md, struct BMEditMesh *editData, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { SmoothModifierData *smd = (SmoothModifierData *)md; Mesh *mesh_src = NULL; /* mesh_src is needed for vgroups, and taking edges into account. */ - mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false); + mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, verts_num, false, false); /* TODO(campbell): use edit-mode data only (remove this line). */ BKE_mesh_wrapper_ensure_mdata(mesh_src); - smoothModifier_do(smd, ctx->object, mesh_src, vertexCos, numVerts); + smoothModifier_do(smd, ctx->object, mesh_src, vertexCos, verts_num); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); diff --git a/source/blender/modifiers/intern/MOD_softbody.c b/source/blender/modifiers/intern/MOD_softbody.c index ae90240dd3f..d43e26f25e1 100644 --- a/source/blender/modifiers/intern/MOD_softbody.c +++ b/source/blender/modifiers/intern/MOD_softbody.c @@ -40,11 +40,11 @@ static void deformVerts(ModifierData *UNUSED(md), const ModifierEvalContext *ctx, Mesh *UNUSED(derivedData), float (*vertexCos)[3], - int numVerts) + int verts_num) { Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); sbObjectStep( - ctx->depsgraph, scene, ctx->object, DEG_get_ctime(ctx->depsgraph), vertexCos, numVerts); + ctx->depsgraph, scene, ctx->object, DEG_get_ctime(ctx->depsgraph), vertexCos, verts_num); } static bool dependsOnTime(struct Scene *UNUSED(scene), diff --git a/source/blender/modifiers/intern/MOD_solidify_extrude.c b/source/blender/modifiers/intern/MOD_solidify_extrude.c index fdaf7bd41d1..80af23054e4 100644 --- a/source/blender/modifiers/intern/MOD_solidify_extrude.c +++ b/source/blender/modifiers/intern/MOD_solidify_extrude.c @@ -55,14 +55,14 @@ BLI_INLINE bool edgeref_is_init(const EdgeFaceRef *edge_ref) */ static void mesh_calc_hq_normal(Mesh *mesh, const float (*poly_nors)[3], float (*r_vert_nors)[3]) { - int i, numVerts, numEdges, numPolys; + int i, verts_num, edges_num, polys_num; MPoly *mpoly, *mp; MLoop *mloop, *ml; MEdge *medge, *ed; - numVerts = mesh->totvert; - numEdges = mesh->totedge; - numPolys = mesh->totpoly; + verts_num = mesh->totvert; + edges_num = mesh->totedge; + polys_num = mesh->totpoly; mpoly = mesh->mpoly; medge = mesh->medge; mloop = mesh->mloop; @@ -71,7 +71,7 @@ static void mesh_calc_hq_normal(Mesh *mesh, const float (*poly_nors)[3], float ( /* Doesn't work here! */ #if 0 - mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, numVerts); + mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, verts_num); cddm->mvert = mv; #endif @@ -79,12 +79,12 @@ static void mesh_calc_hq_normal(Mesh *mesh, const float (*poly_nors)[3], float ( { EdgeFaceRef *edge_ref_array = MEM_calloc_arrayN( - (size_t)numEdges, sizeof(EdgeFaceRef), "Edge Connectivity"); + (size_t)edges_num, sizeof(EdgeFaceRef), "Edge Connectivity"); EdgeFaceRef *edge_ref; float edge_normal[3]; /* Add an edge reference if it's not there, pointing back to the face index. */ - for (i = 0; i < numPolys; i++, mp++) { + for (i = 0; i < polys_num; i++, mp++) { int j; ml = mloop + mp->loopstart; @@ -110,7 +110,7 @@ static void mesh_calc_hq_normal(Mesh *mesh, const float (*poly_nors)[3], float ( } } - for (i = 0, ed = medge, edge_ref = edge_ref_array; i < numEdges; i++, ed++, edge_ref++) { + for (i = 0, ed = medge, edge_ref = edge_ref_array; i < edges_num; i++, ed++, edge_ref++) { /* Get the edge vert indices, and edge value (the face indices that use it) */ if (edgeref_is_init(edge_ref) && (edge_ref->p1 != -1)) { @@ -141,7 +141,7 @@ static void mesh_calc_hq_normal(Mesh *mesh, const float (*poly_nors)[3], float ( /* normalize vertex normals and assign */ const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh); - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { if (normalize_v3(r_vert_nors[i]) == 0.0f) { copy_v3_v3(r_vert_nors[i], vert_normals[i]); } @@ -164,10 +164,10 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex MEdge *ed, *medge, *orig_medge; MLoop *ml, *mloop, *orig_mloop; MPoly *mp, *mpoly, *orig_mpoly; - const uint numVerts = (uint)mesh->totvert; - const uint numEdges = (uint)mesh->totedge; - const uint numPolys = (uint)mesh->totpoly; - const uint numLoops = (uint)mesh->totloop; + const uint verts_num = (uint)mesh->totvert; + const uint edges_num = (uint)mesh->totedge; + const uint polys_num = (uint)mesh->totpoly; + const uint loops_num = (uint)mesh->totloop; uint newLoops = 0, newPolys = 0, newEdges = 0, newVerts = 0, rimVerts = 0; /* Only use material offsets if we have 2 or more materials. */ @@ -184,7 +184,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex STACK_DECLARE(new_edge_arr); uint *old_vert_arr = MEM_calloc_arrayN( - numVerts, sizeof(*old_vert_arr), "old_vert_arr in solidify"); + verts_num, sizeof(*old_vert_arr), "old_vert_arr in solidify"); uint *edge_users = NULL; int *edge_order = NULL; @@ -233,33 +233,34 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex poly_nors = BKE_mesh_poly_normals_ensure(mesh); } - STACK_INIT(new_vert_arr, numVerts * 2); - STACK_INIT(new_edge_arr, numEdges * 2); + STACK_INIT(new_vert_arr, verts_num * 2); + STACK_INIT(new_edge_arr, edges_num * 2); if (do_rim) { - BLI_bitmap *orig_mvert_tag = BLI_BITMAP_NEW(numVerts, __func__); + BLI_bitmap *orig_mvert_tag = BLI_BITMAP_NEW(verts_num, __func__); uint eidx; uint i; #define INVALID_UNUSED ((uint)-1) #define INVALID_PAIR ((uint)-2) - new_vert_arr = MEM_malloc_arrayN(numVerts, 2 * sizeof(*new_vert_arr), __func__); - new_edge_arr = MEM_malloc_arrayN(((numEdges * 2) + numVerts), sizeof(*new_edge_arr), __func__); + new_vert_arr = MEM_malloc_arrayN(verts_num, 2 * sizeof(*new_vert_arr), __func__); + new_edge_arr = MEM_malloc_arrayN( + ((edges_num * 2) + verts_num), sizeof(*new_edge_arr), __func__); - edge_users = MEM_malloc_arrayN(numEdges, sizeof(*edge_users), "solid_mod edges"); - edge_order = MEM_malloc_arrayN(numEdges, sizeof(*edge_order), "solid_mod order"); + edge_users = MEM_malloc_arrayN(edges_num, sizeof(*edge_users), "solid_mod edges"); + edge_order = MEM_malloc_arrayN(edges_num, sizeof(*edge_order), "solid_mod order"); /* save doing 2 loops here... */ #if 0 - copy_vn_i(edge_users, numEdges, INVALID_UNUSED); + copy_vn_i(edge_users, edges_num, INVALID_UNUSED); #endif - for (eidx = 0, ed = orig_medge; eidx < numEdges; eidx++, ed++) { + for (eidx = 0, ed = orig_medge; eidx < edges_num; eidx++, ed++) { edge_users[eidx] = INVALID_UNUSED; } - for (i = 0, mp = orig_mpoly; i < numPolys; i++, mp++) { + for (i = 0, mp = orig_mpoly; i < polys_num; i++, mp++) { MLoop *ml_prev; int j; @@ -272,7 +273,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex if (edge_users[eidx] == INVALID_UNUSED) { ed = orig_medge + eidx; BLI_assert(ELEM(ml_prev->v, ed->v1, ed->v2) && ELEM(ml->v, ed->v1, ed->v2)); - edge_users[eidx] = (ml_prev->v > ml->v) == (ed->v1 < ed->v2) ? i : (i + numPolys); + edge_users[eidx] = (ml_prev->v > ml->v) == (ed->v1 < ed->v2) ? i : (i + polys_num); edge_order[eidx] = j; } else { @@ -282,7 +283,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex } } - for (eidx = 0, ed = orig_medge; eidx < numEdges; eidx++, ed++) { + for (eidx = 0, ed = orig_medge; eidx < edges_num; eidx++, ed++) { if (!ELEM(edge_users[eidx], INVALID_UNUSED, INVALID_PAIR)) { BLI_BITMAP_ENABLE(orig_mvert_tag, ed->v1); BLI_BITMAP_ENABLE(orig_mvert_tag, ed->v2); @@ -292,7 +293,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex } } - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { if (BLI_BITMAP_TEST(orig_mvert_tag, i)) { old_vert_arr[i] = STACK_SIZE(new_vert_arr); STACK_PUSH(new_vert_arr, i); @@ -319,16 +320,16 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex } if (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) { - vert_nors = MEM_calloc_arrayN(numVerts, sizeof(float[3]), "mod_solid_vno_hq"); + vert_nors = MEM_calloc_arrayN(verts_num, sizeof(float[3]), "mod_solid_vno_hq"); mesh_calc_hq_normal(mesh, poly_nors, vert_nors); } result = BKE_mesh_new_nomain_from_template(mesh, - (int)((numVerts * stride) + newVerts), - (int)((numEdges * stride) + newEdges + rimVerts), + (int)((verts_num * stride) + newVerts), + (int)((edges_num * stride) + newEdges + rimVerts), 0, - (int)((numLoops * stride) + newLoops), - (int)((numPolys * stride) + newPolys)); + (int)((loops_num * stride) + newLoops), + (int)((polys_num * stride) + newPolys)); mpoly = result->mpoly; mloop = result->mloop; @@ -341,69 +342,69 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex } if (do_shell) { - CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)numVerts); - CustomData_copy_data(&mesh->vdata, &result->vdata, 0, (int)numVerts, (int)numVerts); + CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)verts_num); + CustomData_copy_data(&mesh->vdata, &result->vdata, 0, (int)verts_num, (int)verts_num); - CustomData_copy_data(&mesh->edata, &result->edata, 0, 0, (int)numEdges); - CustomData_copy_data(&mesh->edata, &result->edata, 0, (int)numEdges, (int)numEdges); + CustomData_copy_data(&mesh->edata, &result->edata, 0, 0, (int)edges_num); + CustomData_copy_data(&mesh->edata, &result->edata, 0, (int)edges_num, (int)edges_num); - CustomData_copy_data(&mesh->ldata, &result->ldata, 0, 0, (int)numLoops); + CustomData_copy_data(&mesh->ldata, &result->ldata, 0, 0, (int)loops_num); /* DO NOT copy here the 'copied' part of loop data, we want to reverse loops * (so that winding of copied face get reversed, so that normals get reversed * and point in expected direction...). * If we also copy data here, then this data get overwritten * (and allocated memory becomes memleak). */ - CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, (int)numPolys); - CustomData_copy_data(&mesh->pdata, &result->pdata, 0, (int)numPolys, (int)numPolys); + CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, (int)polys_num); + CustomData_copy_data(&mesh->pdata, &result->pdata, 0, (int)polys_num, (int)polys_num); } else { int i, j; - CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)numVerts); - for (i = 0, j = (int)numVerts; i < numVerts; i++) { + CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)verts_num); + for (i = 0, j = (int)verts_num; i < verts_num; i++) { if (old_vert_arr[i] != INVALID_UNUSED) { CustomData_copy_data(&mesh->vdata, &result->vdata, i, j, 1); j++; } } - CustomData_copy_data(&mesh->edata, &result->edata, 0, 0, (int)numEdges); + CustomData_copy_data(&mesh->edata, &result->edata, 0, 0, (int)edges_num); - for (i = 0, j = (int)numEdges; i < numEdges; i++) { + for (i = 0, j = (int)edges_num; i < edges_num; i++) { if (!ELEM(edge_users[i], INVALID_UNUSED, INVALID_PAIR)) { MEdge *ed_src, *ed_dst; CustomData_copy_data(&mesh->edata, &result->edata, i, j, 1); ed_src = &medge[i]; ed_dst = &medge[j]; - ed_dst->v1 = old_vert_arr[ed_src->v1] + numVerts; - ed_dst->v2 = old_vert_arr[ed_src->v2] + numVerts; + ed_dst->v1 = old_vert_arr[ed_src->v1] + verts_num; + ed_dst->v2 = old_vert_arr[ed_src->v2] + verts_num; j++; } } /* will be created later */ - CustomData_copy_data(&mesh->ldata, &result->ldata, 0, 0, (int)numLoops); - CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, (int)numPolys); + CustomData_copy_data(&mesh->ldata, &result->ldata, 0, 0, (int)loops_num); + CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, (int)polys_num); } /* initializes: (i_end, do_shell_align, mv). */ #define INIT_VERT_ARRAY_OFFSETS(test) \ if (((ofs_new >= ofs_orig) == do_flip) == test) { \ - i_end = numVerts; \ + i_end = verts_num; \ do_shell_align = true; \ mv = mvert; \ } \ else { \ if (do_shell) { \ - i_end = numVerts; \ + i_end = verts_num; \ do_shell_align = true; \ } \ else { \ i_end = newVerts; \ do_shell_align = false; \ } \ - mv = &mvert[numVerts]; \ + mv = &mvert[verts_num]; \ } \ (void)0 @@ -412,7 +413,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex if (do_shell) { uint i; - mp = mpoly + numPolys; + mp = mpoly + polys_num; for (i = 0; i < mesh->totpoly; i++, mp++) { const int loop_end = mp->totloop - 1; MLoop *ml2; @@ -457,14 +458,14 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex mp->loopstart += mesh->totloop; for (j = 0; j < mp->totloop; j++) { - ml2[j].e += numEdges; - ml2[j].v += numVerts; + ml2[j].e += edges_num; + ml2[j].v += verts_num; } } - for (i = 0, ed = medge + numEdges; i < numEdges; i++, ed++) { - ed->v1 += numVerts; - ed->v2 += numVerts; + for (i = 0, ed = medge + edges_num; i < edges_num; i++, ed++) { + ed->v1 += verts_num; + ed->v2 += verts_num; } } @@ -483,9 +484,9 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex float *edge_angs = NULL; if (do_clamp) { - vert_lens = MEM_malloc_arrayN(numVerts, sizeof(float), "vert_lens"); - copy_vn_fl(vert_lens, (int)numVerts, FLT_MAX); - for (uint i = 0; i < numEdges; i++) { + vert_lens = MEM_malloc_arrayN(verts_num, sizeof(float), "vert_lens"); + copy_vn_fl(vert_lens, (int)verts_num, FLT_MAX); + for (uint i = 0; i < edges_num; i++) { const float ed_len_sq = len_squared_v3v3(mvert[medge[i].v1].co, mvert[medge[i].v2].co); vert_lens[medge[i].v1] = min_ff(vert_lens[medge[i].v1], ed_len_sq); vert_lens[medge[i].v2] = min_ff(vert_lens[medge[i].v2], ed_len_sq); @@ -495,23 +496,23 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex if (do_angle_clamp || do_bevel_convex) { uint eidx; if (do_angle_clamp) { - vert_angs = MEM_malloc_arrayN(numVerts, sizeof(float), "vert_angs"); - copy_vn_fl(vert_angs, (int)numVerts, 0.5f * M_PI); + vert_angs = MEM_malloc_arrayN(verts_num, sizeof(float), "vert_angs"); + copy_vn_fl(vert_angs, (int)verts_num, 0.5f * M_PI); } if (do_bevel_convex) { - edge_angs = MEM_malloc_arrayN(numEdges, sizeof(float), "edge_angs"); + edge_angs = MEM_malloc_arrayN(edges_num, sizeof(float), "edge_angs"); if (!do_rim) { - edge_users = MEM_malloc_arrayN(numEdges, sizeof(*edge_users), "solid_mod edges"); + edge_users = MEM_malloc_arrayN(edges_num, sizeof(*edge_users), "solid_mod edges"); } } uint(*edge_user_pairs)[2] = MEM_malloc_arrayN( - numEdges, sizeof(*edge_user_pairs), "edge_user_pairs"); - for (eidx = 0; eidx < numEdges; eidx++) { + edges_num, sizeof(*edge_user_pairs), "edge_user_pairs"); + for (eidx = 0; eidx < edges_num; eidx++) { edge_user_pairs[eidx][0] = INVALID_UNUSED; edge_user_pairs[eidx][1] = INVALID_UNUSED; } mp = orig_mpoly; - for (uint i = 0; i < numPolys; i++, mp++) { + for (uint i = 0; i < polys_num; i++, mp++) { ml = orig_mloop + mp->loopstart; MLoop *ml_prev = ml + (mp->totloop - 1); @@ -533,7 +534,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex } ed = orig_medge; float e[3]; - for (uint i = 0; i < numEdges; i++, ed++) { + for (uint i = 0; i < edges_num; i++, ed++) { if (!ELEM(edge_user_pairs[i][0], INVALID_UNUSED, INVALID_PAIR) && !ELEM(edge_user_pairs[i][1], INVALID_UNUSED, INVALID_PAIR)) { const float *n0 = poly_nors[edge_user_pairs[i][0]]; @@ -658,7 +659,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex } if (do_bevel_convex) { - for (uint i = 0; i < numEdges; i++) { + for (uint i = 0; i < edges_num; i++) { if (edge_users[i] == INVALID_PAIR) { float angle = edge_angs[i]; medge[i].bweight = (char)clamp_i( @@ -668,8 +669,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex 0, 255); if (do_shell) { - medge[i + numEdges].bweight = (char)clamp_i( - (int)medge[i + numEdges].bweight + + medge[i + edges_num].bweight = (char)clamp_i( + (int)medge[i + edges_num].bweight + (int)((angle > M_PI ? clamp_f(bevel_convex, 0.0f, 1.0f) : clamp_f(bevel_convex, -1.0f, 0.0f)) * 255), @@ -697,19 +698,19 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex #endif /* same as EM_solidify() in editmesh_lib.c */ float *vert_angles = MEM_calloc_arrayN( - numVerts, sizeof(float[2]), "mod_solid_pair"); /* 2 in 1 */ - float *vert_accum = vert_angles + numVerts; + verts_num, sizeof(float[2]), "mod_solid_pair"); /* 2 in 1 */ + float *vert_accum = vert_angles + verts_num; uint vidx; uint i; if (vert_nors == NULL) { - vert_nors = MEM_malloc_arrayN(numVerts, sizeof(float[3]), "mod_solid_vno"); - for (i = 0, mv = mvert; i < numVerts; i++, mv++) { + vert_nors = MEM_malloc_arrayN(verts_num, sizeof(float[3]), "mod_solid_vno"); + for (i = 0, mv = mvert; i < verts_num; i++, mv++) { copy_v3_v3(vert_nors[i], mesh_vert_normals[i]); } } - for (i = 0, mp = mpoly; i < numPolys; i++, mp++) { + for (i = 0, mp = mpoly; i < polys_num; i++, mp++) { /* #BKE_mesh_calc_poly_angles logic is inlined here */ float nor_prev[3]; float nor_next[3]; @@ -765,14 +766,14 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex float scalar; if (defgrp_invert) { - for (i = 0; i < numVerts; i++, dv++) { + for (i = 0; i < verts_num; i++, dv++) { scalar = 1.0f - BKE_defvert_find_weight(dv, defgrp_index); scalar = offset_fac_vg + (scalar * offset_fac_vg_inv); vert_angles[i] *= scalar; } } else { - for (i = 0; i < numVerts; i++, dv++) { + for (i = 0; i < verts_num; i++, dv++) { scalar = BKE_defvert_find_weight(dv, defgrp_index); scalar = offset_fac_vg + (scalar * offset_fac_vg_inv); vert_angles[i] *= scalar; @@ -788,22 +789,22 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex if (do_angle_clamp || do_bevel_convex) { uint eidx; if (do_angle_clamp) { - vert_angs = MEM_malloc_arrayN(numVerts, sizeof(float), "vert_angs even"); - copy_vn_fl(vert_angs, (int)numVerts, 0.5f * M_PI); + vert_angs = MEM_malloc_arrayN(verts_num, sizeof(float), "vert_angs even"); + copy_vn_fl(vert_angs, (int)verts_num, 0.5f * M_PI); } if (do_bevel_convex) { - edge_angs = MEM_malloc_arrayN(numEdges, sizeof(float), "edge_angs even"); + edge_angs = MEM_malloc_arrayN(edges_num, sizeof(float), "edge_angs even"); if (!do_rim) { - edge_users = MEM_malloc_arrayN(numEdges, sizeof(*edge_users), "solid_mod edges"); + edge_users = MEM_malloc_arrayN(edges_num, sizeof(*edge_users), "solid_mod edges"); } } uint(*edge_user_pairs)[2] = MEM_malloc_arrayN( - numEdges, sizeof(*edge_user_pairs), "edge_user_pairs"); - for (eidx = 0; eidx < numEdges; eidx++) { + edges_num, sizeof(*edge_user_pairs), "edge_user_pairs"); + for (eidx = 0; eidx < edges_num; eidx++) { edge_user_pairs[eidx][0] = INVALID_UNUSED; edge_user_pairs[eidx][1] = INVALID_UNUSED; } - for (i = 0, mp = orig_mpoly; i < numPolys; i++, mp++) { + for (i = 0, mp = orig_mpoly; i < polys_num; i++, mp++) { ml = orig_mloop + mp->loopstart; MLoop *ml_prev = ml + (mp->totloop - 1); @@ -825,7 +826,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex } ed = orig_medge; float e[3]; - for (i = 0; i < numEdges; i++, ed++) { + for (i = 0; i < edges_num; i++, ed++) { if (!ELEM(edge_user_pairs[i][0], INVALID_UNUSED, INVALID_PAIR) && !ELEM(edge_user_pairs[i][1], INVALID_UNUSED, INVALID_PAIR)) { const float *n0 = poly_nors[edge_user_pairs[i][0]]; @@ -852,16 +853,16 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex const float clamp_fac = 1 + (do_angle_clamp ? fabsf(smd->offset_fac) : 0); const float offset = fabsf(smd->offset) * smd->offset_clamp * clamp_fac; if (offset > FLT_EPSILON) { - float *vert_lens_sq = MEM_malloc_arrayN(numVerts, sizeof(float), "vert_lens_sq"); + float *vert_lens_sq = MEM_malloc_arrayN(verts_num, sizeof(float), "vert_lens_sq"); const float offset_sq = offset * offset; - copy_vn_fl(vert_lens_sq, (int)numVerts, FLT_MAX); - for (i = 0; i < numEdges; i++) { + copy_vn_fl(vert_lens_sq, (int)verts_num, FLT_MAX); + for (i = 0; i < edges_num; i++) { const float ed_len = len_squared_v3v3(mvert[medge[i].v1].co, mvert[medge[i].v2].co); vert_lens_sq[medge[i].v1] = min_ff(vert_lens_sq[medge[i].v1], ed_len); vert_lens_sq[medge[i].v2] = min_ff(vert_lens_sq[medge[i].v2], ed_len); } if (do_angle_clamp) { - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { float cos_ang = cosf(vert_angs[i] * 0.5f); if (cos_ang > 0) { float max_off = sqrtf(vert_lens_sq[i]) * 0.5f / cos_ang; @@ -873,7 +874,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex MEM_freeN(vert_angs); } else { - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { if (vert_lens_sq[i] < offset_sq) { float scalar = sqrtf(vert_lens_sq[i]) / offset; vert_angles[i] *= scalar; @@ -885,7 +886,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex } if (do_bevel_convex) { - for (i = 0; i < numEdges; i++) { + for (i = 0; i < edges_num; i++) { if (edge_users[i] == INVALID_PAIR) { float angle = edge_angs[i]; medge[i].bweight = (char)clamp_i( @@ -895,8 +896,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex 0, 255); if (do_shell) { - medge[i + numEdges].bweight = (char)clamp_i( - (int)medge[i + numEdges].bweight + + medge[i + edges_num].bweight = (char)clamp_i( + (int)medge[i + edges_num].bweight + (int)((angle > M_PI ? clamp_f(bevel_convex, 0, 1) : clamp_f(bevel_convex, -1, 0)) * 255), @@ -959,8 +960,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex else if (do_shell) { uint i; /* flip vertex normals for copied verts */ - mv = mvert + numVerts; - for (i = 0; i < numVerts; i++) { + mv = mvert + verts_num; + for (i = 0; i < verts_num; i++) { negate_v3((float *)mesh_vert_normals[i]); } } @@ -982,14 +983,14 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex for (uint i = 0; i < rimVerts; i++) { BKE_defvert_ensure_index(&result->dvert[new_vert_arr[i]], rim_defgrp_index)->weight = 1.0f; - BKE_defvert_ensure_index(&result->dvert[(do_shell ? new_vert_arr[i] : i) + numVerts], + BKE_defvert_ensure_index(&result->dvert[(do_shell ? new_vert_arr[i] : i) + verts_num], rim_defgrp_index) ->weight = 1.0f; } } if (shell_defgrp_index != -1) { - for (uint i = numVerts; i < result->totvert; i++) { + for (uint i = verts_num; i < result->totvert; i++) { BKE_defvert_ensure_index(&result->dvert[i], shell_defgrp_index)->weight = 1.0f; } } @@ -1014,7 +1015,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex const bool do_side_normals = !BKE_mesh_vertex_normals_are_dirty(result); /* annoying to allocate these since we only need the edge verts, */ float(*edge_vert_nos)[3] = do_side_normals ? - MEM_calloc_arrayN(numVerts, sizeof(float[3]), __func__) : + MEM_calloc_arrayN(verts_num, sizeof(float[3]), __func__) : NULL; float nor[3]; #endif @@ -1032,11 +1033,11 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex /* add faces & edges */ origindex_edge = CustomData_get_layer(&result->edata, CD_ORIGINDEX); - orig_ed = (origindex_edge) ? &origindex_edge[(numEdges * stride) + newEdges] : NULL; - ed = &medge[(numEdges * stride) + newEdges]; /* start after copied edges */ + orig_ed = (origindex_edge) ? &origindex_edge[(edges_num * stride) + newEdges] : NULL; + ed = &medge[(edges_num * stride) + newEdges]; /* start after copied edges */ for (i = 0; i < rimVerts; i++, ed++) { ed->v1 = new_vert_arr[i]; - ed->v2 = (do_shell ? new_vert_arr[i] : i) + numVerts; + ed->v2 = (do_shell ? new_vert_arr[i] : i) + verts_num; ed->flag |= ME_EDGEDRAW | ME_EDGERENDER; if (orig_ed) { @@ -1050,8 +1051,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex } /* faces */ - mp = mpoly + (numPolys * stride); - ml = mloop + (numLoops * stride); + mp = mpoly + (polys_num * stride); + ml = mloop + (loops_num * stride); j = 0; for (i = 0; i < newPolys; i++, mp++) { uint eidx = new_edge_arr[i]; @@ -1059,8 +1060,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex int k1, k2; bool flip; - if (pidx >= numPolys) { - pidx -= numPolys; + if (pidx >= polys_num) { + pidx -= polys_num; flip = true; } else { @@ -1071,8 +1072,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex /* copy most of the face settings */ CustomData_copy_data( - &mesh->pdata, &result->pdata, (int)pidx, (int)((numPolys * stride) + i), 1); - mp->loopstart = (int)(j + (numLoops * stride)); + &mesh->pdata, &result->pdata, (int)pidx, (int)((polys_num * stride) + i), 1); + mp->loopstart = (int)(j + (loops_num * stride)); mp->flag = mpoly[pidx].flag; /* notice we use 'mp->totloop' which is later overwritten, @@ -1087,39 +1088,39 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex mp->totloop = 4; CustomData_copy_data( - &mesh->ldata, &result->ldata, k2, (int)((numLoops * stride) + j + 0), 1); + &mesh->ldata, &result->ldata, k2, (int)((loops_num * stride) + j + 0), 1); CustomData_copy_data( - &mesh->ldata, &result->ldata, k1, (int)((numLoops * stride) + j + 1), 1); + &mesh->ldata, &result->ldata, k1, (int)((loops_num * stride) + j + 1), 1); CustomData_copy_data( - &mesh->ldata, &result->ldata, k1, (int)((numLoops * stride) + j + 2), 1); + &mesh->ldata, &result->ldata, k1, (int)((loops_num * stride) + j + 2), 1); CustomData_copy_data( - &mesh->ldata, &result->ldata, k2, (int)((numLoops * stride) + j + 3), 1); + &mesh->ldata, &result->ldata, k2, (int)((loops_num * stride) + j + 3), 1); if (flip == false) { ml[j].v = ed->v1; ml[j++].e = eidx; ml[j].v = ed->v2; - ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v2] + newEdges; + ml[j++].e = (edges_num * stride) + old_vert_arr[ed->v2] + newEdges; - ml[j].v = (do_shell ? ed->v2 : old_vert_arr[ed->v2]) + numVerts; - ml[j++].e = (do_shell ? eidx : i) + numEdges; + ml[j].v = (do_shell ? ed->v2 : old_vert_arr[ed->v2]) + verts_num; + ml[j++].e = (do_shell ? eidx : i) + edges_num; - ml[j].v = (do_shell ? ed->v1 : old_vert_arr[ed->v1]) + numVerts; - ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v1] + newEdges; + ml[j].v = (do_shell ? ed->v1 : old_vert_arr[ed->v1]) + verts_num; + ml[j++].e = (edges_num * stride) + old_vert_arr[ed->v1] + newEdges; } else { ml[j].v = ed->v2; ml[j++].e = eidx; ml[j].v = ed->v1; - ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v1] + newEdges; + ml[j++].e = (edges_num * stride) + old_vert_arr[ed->v1] + newEdges; - ml[j].v = (do_shell ? ed->v1 : old_vert_arr[ed->v1]) + numVerts; - ml[j++].e = (do_shell ? eidx : i) + numEdges; + ml[j].v = (do_shell ? ed->v1 : old_vert_arr[ed->v1]) + verts_num; + ml[j++].e = (do_shell ? eidx : i) + edges_num; - ml[j].v = (do_shell ? ed->v2 : old_vert_arr[ed->v2]) + numVerts; - ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v2] + newEdges; + ml[j].v = (do_shell ? ed->v2 : old_vert_arr[ed->v2]) + verts_num; + ml[j++].e = (edges_num * stride) + old_vert_arr[ed->v2] + newEdges; } if (origindex_edge) { @@ -1141,7 +1142,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex if (crease_inner) { /* crease += crease_inner; without wrapping */ - char *cr = &(medge[numEdges + (do_shell ? eidx : i)].crease); + char *cr = &(medge[edges_num + (do_shell ? eidx : i)].crease); int tcr = *cr + crease_inner; *cr = tcr > 255 ? 255 : tcr; } @@ -1163,13 +1164,13 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex #ifdef SOLIDIFY_SIDE_NORMALS if (do_side_normals) { const MEdge *ed_orig = medge; - ed = medge + (numEdges * stride); + ed = medge + (edges_num * stride); for (i = 0; i < rimVerts; i++, ed++, ed_orig++) { float nor_cpy[3]; int k; /* NOTE: only the first vertex (lower half of the index) is calculated. */ - BLI_assert(ed->v1 < numVerts); + BLI_assert(ed->v1 < verts_num); normalize_v3_v3(nor_cpy, edge_vert_nos[ed_orig->v1]); for (k = 0; k < 2; k++) { /* loop over both verts of the edge */ diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c index ff25c1afd49..8a84cd0a3bf 100644 --- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c +++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c @@ -141,11 +141,11 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, MEdge *ed, *medge, *orig_medge; MLoop *ml, *mloop, *orig_mloop; MPoly *mp, *mpoly, *orig_mpoly; - const uint numVerts = (uint)mesh->totvert; - const uint numEdges = (uint)mesh->totedge; - const uint numPolys = (uint)mesh->totpoly; + const uint verts_num = (uint)mesh->totvert; + const uint edges_num = (uint)mesh->totedge; + const uint polys_num = (uint)mesh->totpoly; - if (numPolys == 0 && numVerts != 0) { + if (polys_num == 0 && verts_num != 0) { return mesh; } @@ -193,28 +193,28 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, orig_mloop = mesh->mloop; orig_mpoly = mesh->mpoly; - uint numNewVerts = 0; - uint numNewEdges = 0; - uint numNewLoops = 0; - uint numNewPolys = 0; + uint new_verts_num = 0; + uint new_edges_num = 0; + uint new_loops_num = 0; + uint new_polys_num = 0; #define MOD_SOLIDIFY_EMPTY_TAG ((uint)-1) /* Calculate only face normals. Copied because they are modified directly below. */ - float(*poly_nors)[3] = MEM_malloc_arrayN(numPolys, sizeof(float[3]), __func__); - memcpy(poly_nors, BKE_mesh_poly_normals_ensure(mesh), sizeof(float[3]) * numPolys); + float(*poly_nors)[3] = MEM_malloc_arrayN(polys_num, sizeof(float[3]), __func__); + memcpy(poly_nors, BKE_mesh_poly_normals_ensure(mesh), sizeof(float[3]) * polys_num); NewFaceRef *face_sides_arr = MEM_malloc_arrayN( - numPolys * 2, sizeof(*face_sides_arr), "face_sides_arr in solidify"); + polys_num * 2, sizeof(*face_sides_arr), "face_sides_arr in solidify"); bool *null_faces = (smd->nonmanifold_offset_mode == MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_CONSTRAINTS) ? - MEM_calloc_arrayN(numPolys, sizeof(*null_faces), "null_faces in solidify") : + MEM_calloc_arrayN(polys_num, sizeof(*null_faces), "null_faces in solidify") : NULL; uint largest_ngon = 3; /* Calculate face to #NewFaceRef map. */ { mp = orig_mpoly; - for (uint i = 0; i < numPolys; i++, mp++) { + for (uint i = 0; i < polys_num; i++, mp++) { /* Make normals for faces without area (should really be avoided though). */ if (len_squared_v3(poly_nors[i]) < 0.5f) { MEdge *e = orig_medge + orig_mloop[mp->loopstart].e; @@ -244,18 +244,18 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } /* add to final mesh face count */ if (do_shell) { - numNewPolys += 2; - numNewLoops += (uint)mp->totloop * 2; + new_polys_num += 2; + new_loops_num += (uint)mp->totloop * 2; } } } uint *edge_adj_faces_len = MEM_calloc_arrayN( - numEdges, sizeof(*edge_adj_faces_len), "edge_adj_faces_len in solidify"); + edges_num, sizeof(*edge_adj_faces_len), "edge_adj_faces_len in solidify"); /* Count for each edge how many faces it has adjacent. */ { mp = orig_mpoly; - for (uint i = 0; i < numPolys; i++, mp++) { + for (uint i = 0; i < polys_num; i++, mp++) { ml = orig_mloop + mp->loopstart; for (uint j = 0; j < mp->totloop; j++, ml++) { edge_adj_faces_len[ml->e]++; @@ -265,16 +265,16 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, /* Original edge to #NewEdgeRef map. */ NewEdgeRef ***orig_edge_data_arr = MEM_calloc_arrayN( - numEdges, sizeof(*orig_edge_data_arr), "orig_edge_data_arr in solidify"); + edges_num, sizeof(*orig_edge_data_arr), "orig_edge_data_arr in solidify"); /* Original edge length cache. */ float *orig_edge_lengths = MEM_calloc_arrayN( - numEdges, sizeof(*orig_edge_lengths), "orig_edge_lengths in solidify"); + edges_num, sizeof(*orig_edge_lengths), "orig_edge_lengths in solidify"); /* Edge groups for every original vert. */ EdgeGroup **orig_vert_groups_arr = MEM_calloc_arrayN( - numVerts, sizeof(*orig_vert_groups_arr), "orig_vert_groups_arr in solidify"); + verts_num, sizeof(*orig_vert_groups_arr), "orig_vert_groups_arr in solidify"); /* vertex map used to map duplicates. */ - uint *vm = MEM_malloc_arrayN(numVerts, sizeof(*vm), "orig_vert_map in solidify"); - for (uint i = 0; i < numVerts; i++) { + uint *vm = MEM_malloc_arrayN(verts_num, sizeof(*vm), "orig_vert_map in solidify"); + for (uint i = 0; i < verts_num; i++) { vm[i] = i; } @@ -286,12 +286,12 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, /* Vert edge adjacent map. */ OldVertEdgeRef **vert_adj_edges = MEM_calloc_arrayN( - numVerts, sizeof(*vert_adj_edges), "vert_adj_edges in solidify"); + verts_num, sizeof(*vert_adj_edges), "vert_adj_edges in solidify"); /* Original vertex positions (changed for degenerated geometry). */ float(*orig_mvert_co)[3] = MEM_malloc_arrayN( - numVerts, sizeof(*orig_mvert_co), "orig_mvert_co in solidify"); + verts_num, sizeof(*orig_mvert_co), "orig_mvert_co in solidify"); /* Fill in the original vertex positions. */ - for (uint i = 0; i < numVerts; i++) { + for (uint i = 0; i < verts_num; i++) { orig_mvert_co[i][0] = orig_mvert[i].co[0]; orig_mvert_co[i][1] = orig_mvert[i].co[1]; orig_mvert_co[i][2] = orig_mvert[i].co[2]; @@ -300,12 +300,12 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, /* Create edge to #NewEdgeRef map. */ { OldEdgeFaceRef **edge_adj_faces = MEM_calloc_arrayN( - numEdges, sizeof(*edge_adj_faces), "edge_adj_faces in solidify"); + edges_num, sizeof(*edge_adj_faces), "edge_adj_faces in solidify"); /* Create link_faces for edges. */ { mp = orig_mpoly; - for (uint i = 0; i < numPolys; i++, mp++) { + for (uint i = 0; i < polys_num; i++, mp++) { ml = orig_mloop + mp->loopstart; for (uint j = 0; j < mp->totloop; j++, ml++) { const uint edge = ml->e; @@ -342,19 +342,19 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, float edgedir[3] = {0, 0, 0}; uint *vert_adj_edges_len = MEM_calloc_arrayN( - numVerts, sizeof(*vert_adj_edges_len), "vert_adj_edges_len in solidify"); + verts_num, sizeof(*vert_adj_edges_len), "vert_adj_edges_len in solidify"); /* Calculate edge lengths and len vert_adj edges. */ { bool *face_singularity = MEM_calloc_arrayN( - numPolys, sizeof(*face_singularity), "face_sides_arr in solidify"); + polys_num, sizeof(*face_singularity), "face_sides_arr in solidify"); const float merge_tolerance_sqr = smd->merge_tolerance * smd->merge_tolerance; uint *combined_verts = MEM_calloc_arrayN( - numVerts, sizeof(*combined_verts), "combined_verts in solidify"); + verts_num, sizeof(*combined_verts), "combined_verts in solidify"); ed = orig_medge; - for (uint i = 0; i < numEdges; i++, ed++) { + for (uint i = 0; i < edges_num; i++, ed++) { if (edge_adj_faces_len[i] > 0) { uint v1 = vm[ed->v1]; uint v2 = vm[ed->v2]; @@ -373,7 +373,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, /* This check is very slow. It would need the vertex edge links to get * accelerated that are not yet available at this point. */ bool can_merge = true; - for (uint k = 0; k < numEdges && can_merge; k++) { + for (uint k = 0; k < edges_num && can_merge; k++) { if (k != i && edge_adj_faces_len[k] > 0 && (ELEM(vm[orig_medge[k].v1], v1, v2) != ELEM(vm[orig_medge[k].v2], v1, v2))) { for (uint j = 0; j < edge_adj_faces[k]->faces_len && can_merge; j++) { @@ -402,7 +402,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, (combined_verts[v2] + 1) / (float)(combined_verts[v1] + combined_verts[v2] + 2)); add_v3_v3(orig_mvert_co[v1], edgedir); - for (uint j = v2; j < numVerts; j++) { + for (uint j = v2; j < verts_num; j++) { if (vm[j] == v2) { vm[j] = v1; } @@ -412,7 +412,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, combined_verts[v1] += combined_verts[v2] + 1; if (do_shell) { - numNewLoops -= edge_adj_faces_len[i] * 2; + new_loops_num -= edge_adj_faces_len[i] * 2; } edge_adj_faces_len[i] = 0; @@ -430,7 +430,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } /* remove zero faces in a second pass */ ed = orig_medge; - for (uint i = 0; i < numEdges; i++, ed++) { + for (uint i = 0; i < edges_num; i++, ed++) { const uint v1 = vm[ed->v1]; const uint v2 = vm[ed->v2]; if (v1 == v2 && edge_adj_faces[i]) { @@ -449,14 +449,14 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, face_singularity[face] = true; /* remove from final mesh poly count */ if (do_shell) { - numNewPolys -= 2; + new_polys_num -= 2; } } } } if (do_shell) { - numNewLoops -= edge_adj_faces_len[i] * 2; + new_loops_num -= edge_adj_faces_len[i] * 2; } edge_adj_faces_len[i] = 0; @@ -474,7 +474,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, /* Create vert_adj_edges for verts. */ { ed = orig_medge; - for (uint i = 0; i < numEdges; i++, ed++) { + for (uint i = 0; i < edges_num; i++, ed++) { if (edge_adj_faces_len[i] > 0) { const uint vs[2] = {vm[ed->v1], vm[ed->v2]}; uint invalid_edge_index = 0; @@ -545,8 +545,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } /* remove from final face count */ if (do_shell) { - numNewPolys -= 2 * j; - numNewLoops -= 4 * j; + new_polys_num -= 2 * j; + new_loops_num -= 4 * j; } const uint len = i_adj_faces->faces_len + invalid_adj_faces->faces_len - 2 * j; uint *adj_faces = MEM_malloc_arrayN( @@ -595,7 +595,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, ed = orig_medge; /* Iterate over edges and only check the faces around an edge for duplicates * (performance optimization). */ - for (uint i = 0; i < numEdges; i++, ed++) { + for (uint i = 0; i < edges_num; i++, ed++) { if (edge_adj_faces_len[i] > 0) { const OldEdgeFaceRef *adj_faces = edge_adj_faces[i]; uint adj_len = adj_faces->faces_len; @@ -674,7 +674,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } } else if (e_adj_faces->used > 1) { - for (uint n = 0; n < numEdges; n++) { + for (uint n = 0; n < edges_num; n++) { if (edge_adj_faces[n] == e_adj_faces && edge_adj_faces_len[n] > 0) { edge_adj_faces_len[n]--; if (edge_adj_faces_len[n] == 0) { @@ -689,8 +689,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } } if (do_shell) { - numNewPolys -= 2; - numNewLoops -= 2 * (uint)del_loops; + new_polys_num -= 2; + new_loops_num -= 2 * (uint)del_loops; } break; } @@ -704,7 +704,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, /* Create #NewEdgeRef array. */ { ed = orig_medge; - for (uint i = 0; i < numEdges; i++, ed++) { + for (uint i = 0; i < edges_num; i++, ed++) { const uint v1 = vm[ed->v1]; const uint v2 = vm[ed->v2]; if (edge_adj_faces_len[i] > 0) { @@ -807,8 +807,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, (adj_faces_reversed[0] ? 1 : 0); if (do_rim) { /* Only add the loops parallel to the edge for now. */ - numNewLoops += 2; - numNewPolys++; + new_loops_num += 2; + new_polys_num++; } } @@ -864,13 +864,13 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, MEM_freeN(sorted_faces); orig_edge_data_arr[i] = new_edges; if (do_shell || (adj_len == 1 && do_rim)) { - numNewEdges += new_edges_len; + new_edges_num += new_edges_len; } } } } - for (uint i = 0; i < numEdges; i++) { + for (uint i = 0; i < edges_num; i++) { if (edge_adj_faces[i]) { if (edge_adj_faces[i]->used > 1) { edge_adj_faces[i]->used--; @@ -888,7 +888,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, /* Create sorted edge groups for every vert. */ { OldVertEdgeRef **adj_edges_ptr = vert_adj_edges; - for (uint i = 0; i < numVerts; i++, adj_edges_ptr++) { + for (uint i = 0; i < verts_num; i++, adj_edges_ptr++) { if (*adj_edges_ptr != NULL && (*adj_edges_ptr)->edges_len >= 2) { EdgeGroup *edge_groups; @@ -1305,7 +1305,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, uint added = 0; if (do_shell || (do_rim && !g->is_orig_closed)) { BLI_assert(g->new_vert == MOD_SOLIDIFY_EMPTY_TAG); - g->new_vert = numNewVerts++; + g->new_vert = new_verts_num++; if (do_rim || (do_shell && g->split)) { new_verts++; contains_splits += (g->split != 0); @@ -1321,23 +1321,23 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, last_added = added; if (!(g + 1)->valid || g->topo_group != (g + 1)->topo_group) { if (new_verts > 2) { - numNewPolys++; - numNewEdges += new_verts; + new_polys_num++; + new_edges_num += new_verts; open_edges += (uint)(first_added < last_added); open_edges -= (uint)(open_edges && !contains_open_splits); if (do_shell && do_rim) { - numNewLoops += new_verts * 2; + new_loops_num += new_verts * 2; } else if (do_shell) { - numNewLoops += new_verts * 2 - open_edges; + new_loops_num += new_verts * 2 - open_edges; } else { // do_rim - numNewLoops += new_verts * 2 + open_edges - contains_splits; + new_loops_num += new_verts * 2 + open_edges - contains_splits; } } else if (new_verts == 2) { - numNewEdges++; - numNewLoops += 2u - (uint)(!(do_rim && do_shell) && contains_open_splits); + new_edges_num++; + new_loops_num += 2u - (uint)(!(do_rim && do_shell) && contains_open_splits); } new_verts = 0; contains_open_splits = false; @@ -1356,7 +1356,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, /* Free vert_adj_edges memory. */ { uint i = 0; - for (OldVertEdgeRef **p = vert_adj_edges; i < numVerts; i++, p++) { + for (OldVertEdgeRef **p = vert_adj_edges; i < verts_num; i++, p++) { if (*p) { MEM_freeN((*p)->edges); MEM_freeN(*p); @@ -1375,10 +1375,10 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, float *face_weight = NULL; if (do_flat_faces) { - face_weight = MEM_malloc_arrayN(numPolys, sizeof(*face_weight), "face_weight in solidify"); + face_weight = MEM_malloc_arrayN(polys_num, sizeof(*face_weight), "face_weight in solidify"); mp = orig_mpoly; - for (uint i = 0; i < numPolys; i++, mp++) { + for (uint i = 0; i < polys_num; i++, mp++) { float scalar_vgroup = 1.0f; int loopend = mp->loopstart + mp->totloop; ml = orig_mloop + mp->loopstart; @@ -1399,7 +1399,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, mv = orig_mvert; gs_ptr = orig_vert_groups_arr; - for (uint i = 0; i < numVerts; i++, mv++, gs_ptr++) { + for (uint i = 0; i < verts_num; i++, mv++, gs_ptr++) { if (*gs_ptr) { EdgeGroup *g = *gs_ptr; for (uint j = 0; g->valid; j++, g++) { @@ -1912,7 +1912,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, uint singularity_edges_len = 1; singularity_edges = MEM_malloc_arrayN( singularity_edges_len, sizeof(*singularity_edges), "singularity_edges in solidify"); - for (NewEdgeRef ***new_edges = orig_edge_data_arr; i < numEdges; i++, new_edges++) { + for (NewEdgeRef ***new_edges = orig_edge_data_arr; i < edges_num; i++, new_edges++) { if (*new_edges && (do_shell || edge_adj_faces_len[i] == 1) && (**new_edges)->old_edge == i) { for (NewEdgeRef **l = *new_edges; *l; l++) { if ((*l)->link_edge_groups[0]->is_singularity && @@ -1940,12 +1940,12 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, singularity_edges[totsingularity][1] = v2; totsingularity++; if (edge_adj_faces_len[i] == 1 && do_rim) { - numNewLoops -= 2; - numNewPolys--; + new_loops_num -= 2; + new_polys_num--; } } else { - numNewEdges--; + new_edges_num--; } } } @@ -1954,8 +1954,12 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } /* Create Mesh *result with proper capacity. */ - result = BKE_mesh_new_nomain_from_template( - mesh, (int)(numNewVerts), (int)(numNewEdges), 0, (int)(numNewLoops), (int)(numNewPolys)); + result = BKE_mesh_new_nomain_from_template(mesh, + (int)(new_verts_num), + (int)(new_edges_num), + 0, + (int)(new_loops_num), + (int)(new_polys_num)); mpoly = result->mpoly; mloop = result->mloop; @@ -1982,10 +1986,22 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, result->dvert = dvert; } + /* Get vertex crease layer and ensure edge creases are active if vertex creases are found, since + * they will introduce edge creases in the used custom interpolation method. */ + const float *vertex_crease = CustomData_get_layer(&mesh->vdata, CD_CREASE); + if (vertex_crease) { + result->cd_flag |= ME_CDFLAG_EDGE_CREASE; + /* delete all vertex creases in the result if a rim is used. */ + if (do_rim) { + CustomData_free_layers(&result->vdata, CD_CREASE, result->totvert); + result->cd_flag &= (char)(~ME_CDFLAG_VERT_CREASE); + } + } + /* Make_new_verts. */ { gs_ptr = orig_vert_groups_arr; - for (uint i = 0; i < numVerts; i++, gs_ptr++) { + for (uint i = 0; i < verts_num; i++, gs_ptr++) { EdgeGroup *gs = *gs_ptr; if (gs) { EdgeGroup *g = gs; @@ -2006,7 +2022,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, { uint i = 0; edge_index += totsingularity; - for (NewEdgeRef ***new_edges = orig_edge_data_arr; i < numEdges; i++, new_edges++) { + for (NewEdgeRef ***new_edges = orig_edge_data_arr; i < edges_num; i++, new_edges++) { if (*new_edges && (do_shell || edge_adj_faces_len[i] == 1) && (**new_edges)->old_edge == i) { for (NewEdgeRef **l = *new_edges; *l; l++) { if ((*l)->new_edge != MOD_SOLIDIFY_EMPTY_TAG) { @@ -2077,7 +2093,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, * } */ gs_ptr = orig_vert_groups_arr; - for (uint i = 0; i < numVerts; i++, gs_ptr++) { + for (uint i = 0; i < verts_num; i++, gs_ptr++) { EdgeGroup *gs = *gs_ptr; /* check if the vertex is present (may be dissolved because of proximity) */ if (gs) { @@ -2098,13 +2114,14 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, { gs_ptr = orig_vert_groups_arr; mv = orig_mvert; - for (uint i = 0; i < numVerts; i++, gs_ptr++, mv++) { + for (uint i = 0; i < verts_num; i++, gs_ptr++, mv++) { EdgeGroup *gs = *gs_ptr; if (gs) { EdgeGroup *g = gs; EdgeGroup *g2 = gs; EdgeGroup *last_g = NULL; EdgeGroup *first_g = NULL; + char mv_crease = vertex_crease ? (char)(vertex_crease[i] * 255.0f) : 0; /* Data calculation cache. */ char max_crease; char last_max_crease = 0; @@ -2174,7 +2191,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, medge[edge_index].v2 = g->new_vert; medge[edge_index].flag = ME_EDGEDRAW | ME_EDGERENDER | ((last_flag | flag) & (ME_SEAM | ME_SHARP)); - medge[edge_index].crease = min_cc(last_max_crease, max_crease); + medge[edge_index].crease = max_cc(mv_crease, min_cc(last_max_crease, max_crease)); medge[edge_index++].bweight = max_cc(mv->bweight, min_cc(last_max_bweight, max_bweight)); } @@ -2202,7 +2219,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, medge[edge_index].v2 = first_g->new_vert; medge[edge_index].flag = ME_EDGEDRAW | ME_EDGERENDER | ((last_flag | first_flag) & (ME_SEAM | ME_SHARP)); - medge[edge_index].crease = min_cc(last_max_crease, first_max_crease); + medge[edge_index].crease = max_cc(mv_crease, + min_cc(last_max_crease, first_max_crease)); medge[edge_index++].bweight = max_cc(mv->bweight, min_cc(last_max_bweight, first_max_bweight)); @@ -2303,7 +2321,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, /* Make boundary faces. */ if (do_rim) { - for (uint i = 0; i < numEdges; i++) { + for (uint i = 0; i < edges_num; i++) { if (edge_adj_faces_len[i] == 1 && orig_edge_data_arr[i] && (*orig_edge_data_arr[i])->old_edge == i) { NewEdgeRef **new_edges = orig_edge_data_arr[i]; @@ -2459,7 +2477,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, largest_ngon * 2, sizeof(*face_verts), "face_verts in solidify"); uint *face_edges = MEM_malloc_arrayN( largest_ngon * 2, sizeof(*face_edges), "face_edges in solidify"); - for (uint i = 0; i < numPolys * 2; i++, fr++) { + for (uint i = 0; i < polys_num * 2; i++, fr++) { const uint loopstart = (uint)fr->face->loopstart; uint totloop = (uint)fr->face->totloop; uint valid_edges = 0; @@ -2547,37 +2565,37 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, MEM_freeN(face_verts); MEM_freeN(face_edges); } - if (edge_index != numNewEdges) { + if (edge_index != new_edges_num) { BKE_modifier_set_error(ctx->object, md, "Internal Error: edges array wrong size: %u instead of %u", - numNewEdges, + new_edges_num, edge_index); } - if (poly_index != numNewPolys) { + if (poly_index != new_polys_num) { BKE_modifier_set_error(ctx->object, md, "Internal Error: polys array wrong size: %u instead of %u", - numNewPolys, + new_polys_num, poly_index); } - if (loop_index != numNewLoops) { + if (loop_index != new_loops_num) { BKE_modifier_set_error(ctx->object, md, "Internal Error: loops array wrong size: %u instead of %u", - numNewLoops, + new_loops_num, loop_index); } - BLI_assert(edge_index == numNewEdges); - BLI_assert(poly_index == numNewPolys); - BLI_assert(loop_index == numNewLoops); + BLI_assert(edge_index == new_edges_num); + BLI_assert(poly_index == new_polys_num); + BLI_assert(loop_index == new_loops_num); /* Free remaining memory */ { MEM_freeN(vm); MEM_freeN(edge_adj_faces_len); uint i = 0; - for (EdgeGroup **p = orig_vert_groups_arr; i < numVerts; i++, p++) { + for (EdgeGroup **p = orig_vert_groups_arr; i < verts_num; i++, p++) { if (*p) { for (EdgeGroup *eg = *p; eg->valid; eg++) { MEM_freeN(eg->edges); @@ -2586,8 +2604,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } } MEM_freeN(orig_vert_groups_arr); - i = numEdges; - for (NewEdgeRef ***p = orig_edge_data_arr + (numEdges - 1); i > 0; i--, p--) { + i = edges_num; + for (NewEdgeRef ***p = orig_edge_data_arr + (edges_num - 1); i > 0; i--, p--) { if (*p && (**p)->old_edge == i - 1) { for (NewEdgeRef **l = *p; *l; l++) { MEM_freeN(*l); @@ -2598,7 +2616,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, MEM_freeN(orig_edge_data_arr); MEM_freeN(orig_edge_lengths); i = 0; - for (NewFaceRef *p = face_sides_arr; i < numPolys * 2; i++, p++) { + for (NewFaceRef *p = face_sides_arr; i < polys_num * 2; i++, p++) { MEM_freeN(p->link_edges); } MEM_freeN(face_sides_arr); diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index 973009236ec..249d09e5d2e 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -283,7 +283,7 @@ static void deformMatrices(ModifierData *md, Mesh *mesh, float (*vertex_cos)[3], float (*deform_matrices)[3][3], - int num_verts) + int verts_num) { #if !defined(WITH_OPENSUBDIV) BKE_modifier_set_error(ctx->object, md, "Disabled, built without OpenSubdiv"); @@ -307,7 +307,7 @@ static void deformMatrices(ModifierData *md, /* Happens on bad topology, but also on empty input mesh. */ return; } - BKE_subdiv_deform_coarse_vertices(subdiv, mesh, vertex_cos, num_verts); + BKE_subdiv_deform_coarse_vertices(subdiv, mesh, vertex_cos, verts_num); if (subdiv != runtime_data->subdiv) { BKE_subdiv_free(subdiv); } diff --git a/source/blender/modifiers/intern/MOD_surface.c b/source/blender/modifiers/intern/MOD_surface.c index 4ca2e67c334..f3811d98cd1 100644 --- a/source/blender/modifiers/intern/MOD_surface.c +++ b/source/blender/modifiers/intern/MOD_surface.c @@ -94,7 +94,7 @@ static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { SurfaceModifierData *surmd = (SurfaceModifierData *)md; const int cfra = (int)DEG_get_ctime(ctx->depsgraph); @@ -116,7 +116,7 @@ static void deformVerts(ModifierData *md, surmd->mesh = (Mesh *)BKE_id_copy_ex(NULL, (ID *)mesh, NULL, LIB_ID_COPY_LOCALIZE); } else { - surmd->mesh = MOD_deform_mesh_eval_get(ctx->object, NULL, NULL, NULL, numVerts, false, false); + surmd->mesh = MOD_deform_mesh_eval_get(ctx->object, NULL, NULL, NULL, verts_num, false, false); } if (!ctx->object->pd) { @@ -125,7 +125,7 @@ static void deformVerts(ModifierData *md, } if (surmd->mesh) { - uint numverts = 0, i = 0; + uint mesh_verts_num = 0, i = 0; int init = 0; float *vec; MVert *x, *v; @@ -133,9 +133,9 @@ static void deformVerts(ModifierData *md, BKE_mesh_vert_coords_apply(surmd->mesh, vertexCos); BKE_mesh_calc_normals(surmd->mesh); - numverts = surmd->mesh->totvert; + mesh_verts_num = surmd->mesh->totvert; - if (numverts != surmd->numverts || surmd->x == NULL || surmd->v == NULL || + if (mesh_verts_num != surmd->verts_num || surmd->x == NULL || surmd->v == NULL || cfra != surmd->cfra + 1) { if (surmd->x) { MEM_freeN(surmd->x); @@ -146,16 +146,16 @@ static void deformVerts(ModifierData *md, surmd->v = NULL; } - surmd->x = MEM_calloc_arrayN(numverts, sizeof(MVert), "MVert"); - surmd->v = MEM_calloc_arrayN(numverts, sizeof(MVert), "MVert"); + surmd->x = MEM_calloc_arrayN(mesh_verts_num, sizeof(MVert), "MVert"); + surmd->v = MEM_calloc_arrayN(mesh_verts_num, sizeof(MVert), "MVert"); - surmd->numverts = numverts; + surmd->verts_num = mesh_verts_num; init = 1; } /* convert to global coordinates and calculate velocity */ - for (i = 0, x = surmd->x, v = surmd->v; i < numverts; i++, x++, v++) { + for (i = 0, x = surmd->x, v = surmd->v; i < mesh_verts_num; i++, x++, v++) { vec = surmd->mesh->mvert[i].co; mul_m4_v3(ctx->object->obmat, vec); @@ -210,7 +210,7 @@ static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md) surmd->bvhtree = NULL; surmd->x = NULL; surmd->v = NULL; - surmd->numverts = 0; + surmd->verts_num = 0; } ModifierTypeInfo modifierType_Surface = { diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c index 6926893e188..a80918b8d2b 100644 --- a/source/blender/modifiers/intern/MOD_surfacedeform.c +++ b/source/blender/modifiers/intern/MOD_surfacedeform.c @@ -135,7 +135,7 @@ typedef struct SDefBindPoly { /** Index of the input polygon. */ uint index; /** Number of vertices in this face. */ - uint numverts; + uint verts_num; /** * This polygons loop-start. * \note that we could look this up from the polygon. @@ -152,8 +152,8 @@ typedef struct SDefBindPoly { typedef struct SDefBindWeightData { SDefBindPoly *bind_polys; - uint numpoly; - uint numbinds; + uint polys_num; + uint binds_num; } SDefBindWeightData; typedef struct SDefDeformData { @@ -209,9 +209,9 @@ static void freeData(ModifierData *md) SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md; if (smd->verts) { - for (int i = 0; i < smd->num_bind_verts; i++) { + for (int i = 0; i < smd->bind_verts_num; i++) { if (smd->verts[i].binds) { - for (int j = 0; j < smd->verts[i].numbinds; j++) { + for (int j = 0; j < smd->verts[i].binds_num; j++) { MEM_SAFE_FREE(smd->verts[i].binds[j].vert_inds); MEM_SAFE_FREE(smd->verts[i].binds[j].vert_weights); } @@ -234,11 +234,11 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla if (smd->verts) { tsmd->verts = MEM_dupallocN(smd->verts); - for (int i = 0; i < smd->num_bind_verts; i++) { + for (int i = 0; i < smd->bind_verts_num; i++) { if (smd->verts[i].binds) { tsmd->verts[i].binds = MEM_dupallocN(smd->verts[i].binds); - for (int j = 0; j < smd->verts[i].numbinds; j++) { + for (int j = 0; j < smd->verts[i].binds_num; j++) { if (smd->verts[i].binds[j].vert_inds) { tsmd->verts[i].binds[j].vert_inds = MEM_dupallocN(smd->verts[i].binds[j].vert_inds); } @@ -283,8 +283,8 @@ static void freeAdjacencyMap(SDefAdjacencyArray *const vert_edges, static int buildAdjacencyMap(const MPoly *poly, const MEdge *edge, const MLoop *const mloop, - const uint numpoly, - const uint numedges, + const uint polys_num, + const uint edges_num, SDefAdjacencyArray *const vert_edges, SDefAdjacency *adj, SDefEdgePolys *const edge_polys) @@ -292,7 +292,7 @@ static int buildAdjacencyMap(const MPoly *poly, const MLoop *loop; /* Find polygons adjacent to edges. */ - for (int i = 0; i < numpoly; i++, poly++) { + for (int i = 0; i < polys_num; i++, poly++) { loop = &mloop[poly->loopstart]; for (int j = 0; j < poly->totloop; j++, loop++) { @@ -312,7 +312,7 @@ static int buildAdjacencyMap(const MPoly *poly, } /* Find edges adjacent to vertices */ - for (int i = 0; i < numedges; i++, edge++) { + for (int i = 0; i < edges_num; i++, edge++) { adj->next = vert_edges[edge->v1].first; adj->index = i; vert_edges[edge->v1].first = adj; @@ -457,7 +457,7 @@ static void freeBindData(SDefBindWeightData *const bwdata) SDefBindPoly *bpoly = bwdata->bind_polys; if (bwdata->bind_polys) { - for (int i = 0; i < bwdata->numpoly; bpoly++, i++) { + for (int i = 0; i < bwdata->polys_num; bpoly++, i++) { MEM_SAFE_FREE(bpoly->coords); MEM_SAFE_FREE(bpoly->coords_v2); } @@ -498,9 +498,9 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, return NULL; } - bwdata->numpoly = data->vert_edges[nearest].num / 2; + bwdata->polys_num = data->vert_edges[nearest].num / 2; - bpoly = MEM_calloc_arrayN(bwdata->numpoly, sizeof(*bpoly), "SDefBindPoly"); + bpoly = MEM_calloc_arrayN(bwdata->polys_num, sizeof(*bpoly), "SDefBindPoly"); if (bpoly == NULL) { freeBindData(bwdata); data->success = MOD_SDEF_BIND_RESULT_MEM_ERR; @@ -518,7 +518,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, { bpoly = bwdata->bind_polys; - for (int j = 0; j < bwdata->numpoly; bpoly++, j++) { + for (int j = 0; j < bwdata->polys_num; bpoly++, j++) { /* If coords isn't allocated, we have reached the first uninitialized `bpoly`. */ if ((bpoly->index == edge_polys[edge_ind].polys[i]) || (!bpoly->coords)) { break; @@ -541,7 +541,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, poly = &data->mpoly[bpoly->index]; loop = &data->mloop[poly->loopstart]; - bpoly->numverts = poly->totloop; + bpoly->verts_num = poly->totloop; bpoly->loopstart = poly->loopstart; bpoly->coords = MEM_malloc_arrayN( @@ -719,7 +719,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, } } - avg_point_dist /= bwdata->numpoly; + avg_point_dist /= bwdata->polys_num; /* If weights 1 and 2 are not infinite, loop over all adjacent edges again, * and build adjacency dependent angle data (depends on all polygons having been computed) */ @@ -736,7 +736,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, /* Find bind polys corresponding to the edge's adjacent polys */ bpoly = bwdata->bind_polys; - for (int i = 0, j = 0; (i < bwdata->numpoly) && (j < epolys->num); bpoly++, i++) { + for (int i = 0, j = 0; (i < bwdata->polys_num) && (j < epolys->num); bpoly++, i++) { if (ELEM(bpoly->index, epolys->polys[0], epolys->polys[1])) { bpolys[j] = bpoly; @@ -776,7 +776,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, if (!inf_weight_flags) { bpoly = bwdata->bind_polys; - for (int i = 0; i < bwdata->numpoly; bpoly++, i++) { + for (int i = 0; i < bwdata->polys_num; bpoly++, i++) { float corner_angle_weights[2]; float scale_weight, sqr, inv_sqr; @@ -856,7 +856,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, else if (!(inf_weight_flags & MOD_SDEF_INFINITE_WEIGHT_DIST)) { bpoly = bwdata->bind_polys; - for (int i = 0; i < bwdata->numpoly; bpoly++, i++) { + for (int i = 0; i < bwdata->polys_num; bpoly++, i++) { /* Scale the point distance weight by average point distance, and introduce falloff */ bpoly->weight_dist /= avg_point_dist; bpoly->weight_dist = powf(bpoly->weight_dist, data->falloff); @@ -871,7 +871,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, /* Final loop, to compute actual weights */ bpoly = bwdata->bind_polys; - for (int i = 0; i < bwdata->numpoly; bpoly++, i++) { + for (int i = 0; i < bwdata->polys_num; bpoly++, i++) { /* Weight computation from components */ if (inf_weight_flags & MOD_SDEF_INFINITE_WEIGHT_DIST) { bpoly->weight = bpoly->weight_dist < FLT_EPSILON ? 1.0f : 0.0f; @@ -898,7 +898,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, bpoly = bwdata->bind_polys; - for (int i = 0; i < bwdata->numpoly; bpoly++, i++) { + for (int i = 0; i < bwdata->polys_num; bpoly++, i++) { bpoly->weight /= tot_weight; /* Evaluate if this poly is relevant to bind */ @@ -907,15 +907,15 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, * should be negligible... */ if (bpoly->weight >= FLT_EPSILON) { if (bpoly->inside) { - bwdata->numbinds += 1; + bwdata->binds_num += 1; } else { if (bpoly->dominant_angle_weight < FLT_EPSILON || 1.0f - bpoly->dominant_angle_weight < FLT_EPSILON) { - bwdata->numbinds += 1; + bwdata->binds_num += 1; } else { - bwdata->numbinds += 2; + bwdata->binds_num += 2; } } } @@ -958,7 +958,7 @@ static void bindVert(void *__restrict userdata, if (data->success != MOD_SDEF_BIND_RESULT_SUCCESS) { sdvert->binds = NULL; - sdvert->numbinds = 0; + sdvert->binds_num = 0; return; } @@ -975,7 +975,7 @@ static void bindVert(void *__restrict userdata, if (weight <= 0) { sdvert->binds = NULL; - sdvert->numbinds = 0; + sdvert->binds_num = 0; return; } } @@ -985,53 +985,53 @@ static void bindVert(void *__restrict userdata, if (bwdata == NULL) { sdvert->binds = NULL; - sdvert->numbinds = 0; + sdvert->binds_num = 0; return; } - sdvert->binds = MEM_calloc_arrayN(bwdata->numbinds, sizeof(*sdvert->binds), "SDefVertBindData"); + sdvert->binds = MEM_calloc_arrayN(bwdata->binds_num, sizeof(*sdvert->binds), "SDefVertBindData"); if (sdvert->binds == NULL) { data->success = MOD_SDEF_BIND_RESULT_MEM_ERR; - sdvert->numbinds = 0; + sdvert->binds_num = 0; return; } - sdvert->numbinds = bwdata->numbinds; + sdvert->binds_num = bwdata->binds_num; sdbind = sdvert->binds; bpoly = bwdata->bind_polys; - for (int i = 0; i < bwdata->numbinds; bpoly++) { + for (int i = 0; i < bwdata->binds_num; bpoly++) { if (bpoly->weight >= FLT_EPSILON) { if (bpoly->inside) { const MLoop *loop = &data->mloop[bpoly->loopstart]; sdbind->influence = bpoly->weight; - sdbind->numverts = bpoly->numverts; + sdbind->verts_num = bpoly->verts_num; sdbind->mode = MOD_SDEF_MODE_NGON; sdbind->vert_weights = MEM_malloc_arrayN( - bpoly->numverts, sizeof(*sdbind->vert_weights), "SDefNgonVertWeights"); + bpoly->verts_num, sizeof(*sdbind->vert_weights), "SDefNgonVertWeights"); if (sdbind->vert_weights == NULL) { data->success = MOD_SDEF_BIND_RESULT_MEM_ERR; return; } sdbind->vert_inds = MEM_malloc_arrayN( - bpoly->numverts, sizeof(*sdbind->vert_inds), "SDefNgonVertInds"); + bpoly->verts_num, sizeof(*sdbind->vert_inds), "SDefNgonVertInds"); if (sdbind->vert_inds == NULL) { data->success = MOD_SDEF_BIND_RESULT_MEM_ERR; return; } interp_weights_poly_v2( - sdbind->vert_weights, bpoly->coords_v2, bpoly->numverts, bpoly->point_v2); + sdbind->vert_weights, bpoly->coords_v2, bpoly->verts_num, bpoly->point_v2); /* Re-project vert based on weights and original poly verts, * to reintroduce poly non-planarity */ zero_v3(point_co_proj); - for (int j = 0; j < bpoly->numverts; j++, loop++) { + for (int j = 0; j < bpoly->verts_num; j++, loop++) { madd_v3_v3fl(point_co_proj, bpoly->coords[j], sdbind->vert_weights[j]); sdbind->vert_inds[j] = loop->v; } @@ -1048,7 +1048,7 @@ static void bindVert(void *__restrict userdata, if (1.0f - bpoly->dominant_angle_weight >= FLT_EPSILON) { sdbind->influence = bpoly->weight * (1.0f - bpoly->dominant_angle_weight); - sdbind->numverts = bpoly->numverts; + sdbind->verts_num = bpoly->verts_num; sdbind->mode = MOD_SDEF_MODE_CENTROID; sdbind->vert_weights = MEM_malloc_arrayN( @@ -1059,7 +1059,7 @@ static void bindVert(void *__restrict userdata, } sdbind->vert_inds = MEM_malloc_arrayN( - bpoly->numverts, sizeof(*sdbind->vert_inds), "SDefCentVertInds"); + bpoly->verts_num, sizeof(*sdbind->vert_inds), "SDefCentVertInds"); if (sdbind->vert_inds == NULL) { data->success = MOD_SDEF_BIND_RESULT_MEM_ERR; return; @@ -1068,7 +1068,7 @@ static void bindVert(void *__restrict userdata, sortPolyVertsEdge(sdbind->vert_inds, &data->mloop[bpoly->loopstart], bpoly->edge_inds[bpoly->dominant_edge], - bpoly->numverts); + bpoly->verts_num); copy_v3_v3(v1, data->targetCos[sdbind->vert_inds[0]]); copy_v3_v3(v2, data->targetCos[sdbind->vert_inds[1]]); @@ -1095,7 +1095,7 @@ static void bindVert(void *__restrict userdata, if (bpoly->dominant_angle_weight >= FLT_EPSILON) { sdbind->influence = bpoly->weight * bpoly->dominant_angle_weight; - sdbind->numverts = bpoly->numverts; + sdbind->verts_num = bpoly->verts_num; sdbind->mode = MOD_SDEF_MODE_LOOPTRI; sdbind->vert_weights = MEM_malloc_arrayN( @@ -1106,7 +1106,7 @@ static void bindVert(void *__restrict userdata, } sdbind->vert_inds = MEM_malloc_arrayN( - bpoly->numverts, sizeof(*sdbind->vert_inds), "SDefTriVertInds"); + bpoly->verts_num, sizeof(*sdbind->vert_inds), "SDefTriVertInds"); if (sdbind->vert_inds == NULL) { data->success = MOD_SDEF_BIND_RESULT_MEM_ERR; return; @@ -1115,7 +1115,7 @@ static void bindVert(void *__restrict userdata, sortPolyVertsTri(sdbind->vert_inds, &data->mloop[bpoly->loopstart], bpoly->edge_vert_inds[0], - bpoly->numverts); + bpoly->verts_num); copy_v3_v3(v1, data->targetCos[sdbind->vert_inds[0]]); copy_v3_v3(v2, data->targetCos[sdbind->vert_inds[1]]); @@ -1149,25 +1149,25 @@ static void bindVert(void *__restrict userdata, /* Remove vertices without bind data from the bind array. */ static void compactSparseBinds(SurfaceDeformModifierData *smd) { - smd->num_bind_verts = 0; + smd->bind_verts_num = 0; - for (uint i = 0; i < smd->num_mesh_verts; i++) { - if (smd->verts[i].numbinds > 0) { - smd->verts[smd->num_bind_verts++] = smd->verts[i]; + for (uint i = 0; i < smd->mesh_verts_num; i++) { + if (smd->verts[i].binds_num > 0) { + smd->verts[smd->bind_verts_num++] = smd->verts[i]; } } smd->verts = MEM_reallocN_id( - smd->verts, sizeof(*smd->verts) * smd->num_bind_verts, "SDefBindVerts (sparse)"); + smd->verts, sizeof(*smd->verts) * smd->bind_verts_num, "SDefBindVerts (sparse)"); } static bool surfacedeformBind(Object *ob, SurfaceDeformModifierData *smd_orig, SurfaceDeformModifierData *smd_eval, float (*vertexCos)[3], - uint numverts, - uint tnumpoly, - uint tnumverts, + uint verts_num, + uint tpolys_num, + uint tverts_num, Mesh *target, Mesh *mesh) { @@ -1176,26 +1176,26 @@ static bool surfacedeformBind(Object *ob, const MPoly *mpoly = target->mpoly; const MEdge *medge = target->medge; const MLoop *mloop = target->mloop; - uint tnumedges = target->totedge; + uint tedges_num = target->totedge; int adj_result; SDefAdjacencyArray *vert_edges; SDefAdjacency *adj_array; SDefEdgePolys *edge_polys; - vert_edges = MEM_calloc_arrayN(tnumverts, sizeof(*vert_edges), "SDefVertEdgeMap"); + vert_edges = MEM_calloc_arrayN(tverts_num, sizeof(*vert_edges), "SDefVertEdgeMap"); if (vert_edges == NULL) { BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory"); return false; } - adj_array = MEM_malloc_arrayN(tnumedges, 2 * sizeof(*adj_array), "SDefVertEdge"); + adj_array = MEM_malloc_arrayN(tedges_num, 2 * sizeof(*adj_array), "SDefVertEdge"); if (adj_array == NULL) { BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory"); MEM_freeN(vert_edges); return false; } - edge_polys = MEM_calloc_arrayN(tnumedges, sizeof(*edge_polys), "SDefEdgeFaceMap"); + edge_polys = MEM_calloc_arrayN(tedges_num, sizeof(*edge_polys), "SDefEdgeFaceMap"); if (edge_polys == NULL) { BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory"); MEM_freeN(vert_edges); @@ -1203,7 +1203,7 @@ static bool surfacedeformBind(Object *ob, return false; } - smd_orig->verts = MEM_malloc_arrayN(numverts, sizeof(*smd_orig->verts), "SDefBindVerts"); + smd_orig->verts = MEM_malloc_arrayN(verts_num, sizeof(*smd_orig->verts), "SDefBindVerts"); if (smd_orig->verts == NULL) { BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory"); freeAdjacencyMap(vert_edges, adj_array, edge_polys); @@ -1220,7 +1220,7 @@ static bool surfacedeformBind(Object *ob, } adj_result = buildAdjacencyMap( - mpoly, medge, mloop, tnumpoly, tnumedges, vert_edges, adj_array, edge_polys); + mpoly, medge, mloop, tpolys_num, tedges_num, vert_edges, adj_array, edge_polys); if (adj_result == MOD_SDEF_BIND_RESULT_NONMANY_ERR) { BKE_modifier_set_error( @@ -1232,8 +1232,8 @@ static bool surfacedeformBind(Object *ob, return false; } - smd_orig->num_mesh_verts = numverts; - smd_orig->numpoly = tnumpoly; + smd_orig->mesh_verts_num = verts_num; + smd_orig->polys_num = tpolys_num; int defgrp_index; MDeformVert *dvert; @@ -1249,7 +1249,7 @@ static bool surfacedeformBind(Object *ob, .medge = medge, .mloop = mloop, .looptri = BKE_mesh_runtime_looptri_ensure(target), - .targetCos = MEM_malloc_arrayN(tnumverts, sizeof(float[3]), "SDefTargetBindVertArray"), + .targetCos = MEM_malloc_arrayN(tverts_num, sizeof(float[3]), "SDefTargetBindVertArray"), .bind_verts = smd_orig->verts, .vertexCos = vertexCos, .falloff = smd_orig->falloff, @@ -1268,14 +1268,14 @@ static bool surfacedeformBind(Object *ob, invert_m4_m4(data.imat, smd_orig->mat); - for (int i = 0; i < tnumverts; i++) { + for (int i = 0; i < tverts_num; i++) { mul_v3_m4v3(data.targetCos[i], smd_orig->mat, mvert[i].co); } TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); - settings.use_threading = (numverts > 10000); - BLI_task_parallel_range(0, numverts, &data, bindVert, &settings); + settings.use_threading = (verts_num > 10000); + BLI_task_parallel_range(0, verts_num, &data, bindVert, &settings); MEM_freeN(data.targetCos); @@ -1283,7 +1283,7 @@ static bool surfacedeformBind(Object *ob, compactSparseBinds(smd_orig); } else { - smd_orig->num_bind_verts = numverts; + smd_orig->bind_verts_num = verts_num; } if (data.success == MOD_SDEF_BIND_RESULT_MEM_ERR) { @@ -1311,7 +1311,7 @@ static bool surfacedeformBind(Object *ob, BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Target contains invalid polygons"); freeData((ModifierData *)smd_orig); } - else if (smd_orig->num_bind_verts == 0 || !smd_orig->verts) { + else if (smd_orig->bind_verts_num == 0 || !smd_orig->verts) { data.success = MOD_SDEF_BIND_RESULT_GENERIC_ERR; BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "No vertices were bound"); freeData((ModifierData *)smd_orig); @@ -1329,7 +1329,7 @@ static void deformVert(void *__restrict userdata, { const SDefDeformData *const data = (SDefDeformData *)userdata; const SDefBind *sdbind = data->bind_verts[index].binds; - const int num_binds = data->bind_verts[index].numbinds; + const int sdbind_num = data->bind_verts[index].binds_num; const unsigned int vertex_idx = data->bind_verts[index].vertex_idx; float *const vertexCos = data->vertexCos[vertex_idx]; float norm[3], temp[3], offset[3]; @@ -1355,8 +1355,8 @@ static void deformVert(void *__restrict userdata, /* Allocate a `coords_buffer` that fits all the temp-data. */ int max_verts = 0; - for (int j = 0; j < num_binds; j++) { - max_verts = MAX2(max_verts, sdbind[j].numverts); + for (int j = 0; j < sdbind_num; j++) { + max_verts = MAX2(max_verts, sdbind[j].verts_num); } const bool big_buffer = max_verts > 256; @@ -1369,12 +1369,12 @@ static void deformVert(void *__restrict userdata, coords_buffer = BLI_array_alloca(coords_buffer, max_verts); } - for (int j = 0; j < num_binds; j++, sdbind++) { - for (int k = 0; k < sdbind->numverts; k++) { + for (int j = 0; j < sdbind_num; j++, sdbind++) { + for (int k = 0; k < sdbind->verts_num; k++) { copy_v3_v3(coords_buffer[k], data->targetCos[sdbind->vert_inds[k]]); } - normal_poly_v3(norm, coords_buffer, sdbind->numverts); + normal_poly_v3(norm, coords_buffer, sdbind->verts_num); zero_v3(temp); switch (sdbind->mode) { @@ -1388,7 +1388,7 @@ static void deformVert(void *__restrict userdata, /* ---------- ngon mode ---------- */ case MOD_SDEF_MODE_NGON: { - for (int k = 0; k < sdbind->numverts; k++) { + for (int k = 0; k < sdbind->verts_num; k++) { madd_v3_v3fl(temp, coords_buffer[k], sdbind->vert_weights[k]); } break; @@ -1397,7 +1397,7 @@ static void deformVert(void *__restrict userdata, /* ---------- centroid mode ---------- */ case MOD_SDEF_MODE_CENTROID: { float cent[3]; - mid_v3_v3_array(cent, coords_buffer, sdbind->numverts); + mid_v3_v3_array(cent, coords_buffer, sdbind->verts_num); madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[0]], sdbind->vert_weights[0]); madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[1]], sdbind->vert_weights[1]); @@ -1425,13 +1425,13 @@ static void deformVert(void *__restrict userdata, static void surfacedeformModifier_do(ModifierData *md, const ModifierEvalContext *ctx, float (*vertexCos)[3], - uint numverts, + uint verts_num, Object *ob, Mesh *mesh) { SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md; Mesh *target; - uint tnumverts, tnumpoly; + uint tverts_num, tpolys_num; /* Exit function if bind flag is not set (free bind data if any). */ if (!(smd->flags & MOD_SDEF_BIND)) { @@ -1453,8 +1453,8 @@ static void surfacedeformModifier_do(ModifierData *md, return; } - tnumverts = BKE_mesh_wrapper_vert_len(target); - tnumpoly = BKE_mesh_wrapper_poly_len(target); + tverts_num = BKE_mesh_wrapper_vert_len(target); + tpolys_num = BKE_mesh_wrapper_poly_len(target); /* If not bound, execute bind. */ if (smd->verts == NULL) { @@ -1474,7 +1474,7 @@ static void surfacedeformModifier_do(ModifierData *md, BKE_mesh_wrapper_ensure_mdata(target); if (!surfacedeformBind( - ob, smd_orig, smd, vertexCos, numverts, tnumpoly, tnumverts, target, mesh)) { + ob, smd_orig, smd, vertexCos, verts_num, tpolys_num, tverts_num, target, mesh)) { smd->flags &= ~MOD_SDEF_BIND; } /* Early abort, this is binding 'call', no need to perform whole evaluation. */ @@ -1482,14 +1482,14 @@ static void surfacedeformModifier_do(ModifierData *md, } /* Poly count checks */ - if (smd->num_mesh_verts != numverts) { + if (smd->mesh_verts_num != verts_num) { BKE_modifier_set_error( - ob, md, "Vertices changed from %u to %u", smd->num_mesh_verts, numverts); + ob, md, "Vertices changed from %u to %u", smd->mesh_verts_num, verts_num); return; } - if (smd->numpoly != tnumpoly) { + if (smd->polys_num != tpolys_num) { BKE_modifier_set_error( - ob, md, "Target polygons changed from %u to %u", smd->numpoly, tnumpoly); + ob, md, "Target polygons changed from %u to %u", smd->polys_num, tpolys_num); return; } @@ -1507,7 +1507,7 @@ static void surfacedeformModifier_do(ModifierData *md, /* Actual vertex location update starts here */ SDefDeformData data = { .bind_verts = smd->verts, - .targetCos = MEM_malloc_arrayN(tnumverts, sizeof(float[3]), "SDefTargetVertArray"), + .targetCos = MEM_malloc_arrayN(tverts_num, sizeof(float[3]), "SDefTargetVertArray"), .vertexCos = vertexCos, .dvert = dvert, .defgrp_index = defgrp_index, @@ -1516,12 +1516,12 @@ static void surfacedeformModifier_do(ModifierData *md, }; if (data.targetCos != NULL) { - BKE_mesh_wrapper_vert_coords_copy_with_mat4(target, data.targetCos, tnumverts, smd->mat); + BKE_mesh_wrapper_vert_coords_copy_with_mat4(target, data.targetCos, tverts_num, smd->mat); TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); - settings.use_threading = (smd->num_bind_verts > 10000); - BLI_task_parallel_range(0, smd->num_bind_verts, &data, deformVert, &settings); + settings.use_threading = (smd->bind_verts_num > 10000); + BLI_task_parallel_range(0, smd->bind_verts_num, &data, deformVert, &settings); MEM_freeN(data.targetCos); } @@ -1531,17 +1531,17 @@ static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md; Mesh *mesh_src = NULL; if (smd->defgrp_name[0] != '\0') { /* Only need to use mesh_src when a vgroup is used. */ - mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false); + mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false, false); } - surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object, mesh_src); + surfacedeformModifier_do(md, ctx, vertexCos, verts_num, ctx->object, mesh_src); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); @@ -1553,17 +1553,17 @@ static void deformVertsEM(ModifierData *md, struct BMEditMesh *em, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md; Mesh *mesh_src = NULL; if (smd->defgrp_name[0] != '\0') { /* Only need to use mesh_src when a vgroup is used. */ - mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, numVerts, false, false); + mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, verts_num, false, false); } - surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object, mesh_src); + surfacedeformModifier_do(md, ctx, vertexCos, verts_num, ctx->object, mesh_src); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); @@ -1633,23 +1633,23 @@ static void blendWrite(BlendWriter *writer, const ModifierData *md) { const SurfaceDeformModifierData *smd = (const SurfaceDeformModifierData *)md; - BLO_write_struct_array(writer, SDefVert, smd->num_bind_verts, smd->verts); + BLO_write_struct_array(writer, SDefVert, smd->bind_verts_num, smd->verts); if (smd->verts) { - for (int i = 0; i < smd->num_bind_verts; i++) { - BLO_write_struct_array(writer, SDefBind, smd->verts[i].numbinds, smd->verts[i].binds); + for (int i = 0; i < smd->bind_verts_num; i++) { + BLO_write_struct_array(writer, SDefBind, smd->verts[i].binds_num, smd->verts[i].binds); if (smd->verts[i].binds) { - for (int j = 0; j < smd->verts[i].numbinds; j++) { + for (int j = 0; j < smd->verts[i].binds_num; j++) { BLO_write_uint32_array( - writer, smd->verts[i].binds[j].numverts, smd->verts[i].binds[j].vert_inds); + writer, smd->verts[i].binds[j].verts_num, smd->verts[i].binds[j].vert_inds); if (ELEM(smd->verts[i].binds[j].mode, MOD_SDEF_MODE_CENTROID, MOD_SDEF_MODE_LOOPTRI)) { BLO_write_float3_array(writer, 1, smd->verts[i].binds[j].vert_weights); } else { BLO_write_float_array( - writer, smd->verts[i].binds[j].numverts, smd->verts[i].binds[j].vert_weights); + writer, smd->verts[i].binds[j].verts_num, smd->verts[i].binds[j].vert_weights); } } } @@ -1664,20 +1664,20 @@ static void blendRead(BlendDataReader *reader, ModifierData *md) BLO_read_data_address(reader, &smd->verts); if (smd->verts) { - for (int i = 0; i < smd->num_bind_verts; i++) { + for (int i = 0; i < smd->bind_verts_num; i++) { BLO_read_data_address(reader, &smd->verts[i].binds); if (smd->verts[i].binds) { - for (int j = 0; j < smd->verts[i].numbinds; j++) { + for (int j = 0; j < smd->verts[i].binds_num; j++) { BLO_read_uint32_array( - reader, smd->verts[i].binds[j].numverts, &smd->verts[i].binds[j].vert_inds); + reader, smd->verts[i].binds[j].verts_num, &smd->verts[i].binds[j].vert_inds); if (ELEM(smd->verts[i].binds[j].mode, MOD_SDEF_MODE_CENTROID, MOD_SDEF_MODE_LOOPTRI)) { BLO_read_float3_array(reader, 1, &smd->verts[i].binds[j].vert_weights); } else { BLO_read_float_array( - reader, smd->verts[i].binds[j].numverts, &smd->verts[i].binds[j].vert_weights); + reader, smd->verts[i].binds[j].verts_num, &smd->verts[i].binds[j].vert_weights); } } } diff --git a/source/blender/modifiers/intern/MOD_triangulate.c b/source/blender/modifiers/intern/MOD_triangulate.c index e560a859735..d7e57c1f6e5 100644 --- a/source/blender/modifiers/intern/MOD_triangulate.c +++ b/source/blender/modifiers/intern/MOD_triangulate.c @@ -43,7 +43,7 @@ static Mesh *triangulate_mesh(Mesh *mesh, { Mesh *result; BMesh *bm; - int total_edges, i; + int edges_num, i; MEdge *me; CustomData_MeshMasks cd_mask_extra = { .vmask = CD_MASK_ORIGINDEX, .emask = CD_MASK_ORIGINDEX, .pmask = CD_MASK_ORIGINDEX}; @@ -81,11 +81,11 @@ static Mesh *triangulate_mesh(Mesh *mesh, CustomData_set_layer_flag(&result->ldata, CD_NORMAL, CD_FLAG_TEMPORARY); } - total_edges = result->totedge; + edges_num = result->totedge; me = result->medge; /* force drawing of all edges (seems to be omitted in CDDM_from_bmesh) */ - for (i = 0; i < total_edges; i++, me++) { + for (i = 0; i < edges_num; i++, me++) { me->flag |= ME_EDGEDRAW | ME_EDGERENDER; } diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c index a8c52108cc0..a58e8e23147 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -63,7 +63,7 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd, float (*cos)[3], float (*r_texco)[3]) { - const int numVerts = mesh->totvert; + const int verts_num = mesh->totvert; int i; int texmapping = dmd->texmapping; float mapref_imat[4][4]; @@ -97,8 +97,8 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd, MPoly *mpoly = mesh->mpoly; MPoly *mp; MLoop *mloop = mesh->mloop; - BLI_bitmap *done = BLI_BITMAP_NEW(numVerts, __func__); - const int numPolys = mesh->totpoly; + BLI_bitmap *done = BLI_BITMAP_NEW(verts_num, __func__); + const int polys_num = mesh->totpoly; char uvname[MAX_CUSTOMDATA_LAYER_NAME]; MLoopUV *mloop_uv; @@ -106,7 +106,7 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd, mloop_uv = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, uvname); /* verts are given the UV from the first face that uses them */ - for (i = 0, mp = mpoly; i < numPolys; i++, mp++) { + for (i = 0, mp = mpoly; i < polys_num; i++, mp++) { uint fidx = mp->totloop - 1; do { @@ -132,7 +132,7 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd, } MVert *mv = mesh->mvert; - for (i = 0; i < numVerts; i++, mv++, r_texco++) { + for (i = 0; i < verts_num; i++, mv++, r_texco++) { switch (texmapping) { case MOD_DISP_MAP_LOCAL: copy_v3_v3(*r_texco, cos != NULL ? *cos : mv->co); @@ -169,7 +169,7 @@ Mesh *MOD_deform_mesh_eval_get(Object *ob, struct BMEditMesh *em, Mesh *mesh, const float (*vertexCos)[3], - const int num_verts, + const int verts_num, const bool use_normals, const bool use_orco) { @@ -212,7 +212,7 @@ Mesh *MOD_deform_mesh_eval_get(Object *ob, /* Currently, that may not be the case every time * (texts e.g. tend to give issues, * also when deforming curve points instead of generated curve geometry... ). */ - if (mesh != NULL && mesh->totvert != num_verts) { + if (mesh != NULL && mesh->totvert != verts_num) { BKE_id_free(NULL, mesh); mesh = NULL; } @@ -227,7 +227,7 @@ Mesh *MOD_deform_mesh_eval_get(Object *ob, } if (mesh && mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_MDATA) { - BLI_assert(mesh->totvert == num_verts); + BLI_assert(mesh->totvert == verts_num); } return mesh; diff --git a/source/blender/modifiers/intern/MOD_util.h b/source/blender/modifiers/intern/MOD_util.h index 4578d2c4862..aef254b1103 100644 --- a/source/blender/modifiers/intern/MOD_util.h +++ b/source/blender/modifiers/intern/MOD_util.h @@ -37,7 +37,7 @@ struct Mesh *MOD_deform_mesh_eval_get(struct Object *ob, struct BMEditMesh *em, struct Mesh *mesh, const float (*vertexCos)[3], - int num_verts, + int verts_num, bool use_normals, bool use_orco); diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c index 642aac17efd..d4d7ecef283 100644 --- a/source/blender/modifiers/intern/MOD_uvproject.c +++ b/source/blender/modifiers/intern/MOD_uvproject.c @@ -72,7 +72,7 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte { UVProjectModifierData *umd = (UVProjectModifierData *)md; bool do_add_own_transform = false; - for (int i = 0; i < umd->num_projectors; i++) { + for (int i = 0; i < umd->projectors_num; i++) { if (umd->projectors[i] != NULL) { DEG_add_object_relation( ctx->node, umd->projectors[i], DEG_OB_COMP_TRANSFORM, "UV Project Modifier"); @@ -98,11 +98,11 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, { float(*coords)[3], (*co)[3]; MLoopUV *mloop_uv; - int i, numVerts, numPolys, numLoops; + int i, verts_num, polys_num, loops_num; MPoly *mpoly, *mp; MLoop *mloop; Projector projectors[MOD_UVPROJECT_MAXPROJECTORS]; - int num_projectors = 0; + int projectors_num = 0; char uvname[MAX_CUSTOMDATA_LAYER_NAME]; float aspx = umd->aspectx ? umd->aspectx : 1.0f; float aspy = umd->aspecty ? umd->aspecty : 1.0f; @@ -110,13 +110,13 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, float scay = umd->scaley ? umd->scaley : 1.0f; int free_uci = 0; - for (i = 0; i < umd->num_projectors; i++) { + for (i = 0; i < umd->projectors_num; i++) { if (umd->projectors[i] != NULL) { - projectors[num_projectors++].ob = umd->projectors[i]; + projectors[projectors_num++].ob = umd->projectors[i]; } } - if (num_projectors == 0) { + if (projectors_num == 0) { return mesh; } @@ -131,7 +131,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, umd->uvlayer_name, uvname); /* calculate a projection matrix and normal for each projector */ - for (i = 0; i < num_projectors; i++) { + for (i = 0; i < projectors_num; i++) { float tmpmat[4][4]; float offsetmat[4][4]; Camera *cam = NULL; @@ -184,23 +184,23 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, mul_mat3_m4_v3(projectors[i].ob->obmat, projectors[i].normal); } - numPolys = mesh->totpoly; - numLoops = mesh->totloop; + polys_num = mesh->totpoly; + loops_num = mesh->totloop; /* make sure we are not modifying the original UV map */ mloop_uv = CustomData_duplicate_referenced_layer_named( - &mesh->ldata, CD_MLOOPUV, uvname, numLoops); + &mesh->ldata, CD_MLOOPUV, uvname, loops_num); - coords = BKE_mesh_vert_coords_alloc(mesh, &numVerts); + coords = BKE_mesh_vert_coords_alloc(mesh, &verts_num); /* Convert coords to world-space. */ - for (i = 0, co = coords; i < numVerts; i++, co++) { + for (i = 0, co = coords; i < verts_num; i++, co++) { mul_m4_v3(ob->obmat, *co); } /* if only one projector, project coords to UVs */ - if (num_projectors == 1 && projectors[0].uci == NULL) { - for (i = 0, co = coords; i < numVerts; i++, co++) { + if (projectors_num == 1 && projectors[0].uci == NULL) { + for (i = 0, co = coords; i < verts_num; i++, co++) { mul_project_m4_v3(projectors[0].projmat, *co); } } @@ -209,8 +209,8 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, mloop = mesh->mloop; /* apply coords as UVs */ - for (i = 0, mp = mpoly; i < numPolys; i++, mp++) { - if (num_projectors == 1) { + for (i = 0, mp = mpoly; i < polys_num; i++, mp++) { + if (projectors_num == 1) { if (projectors[0].uci) { uint fidx = mp->totloop - 1; do { @@ -246,7 +246,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, best_dot = dot_v3v3(projectors[0].normal, face_no); best_projector = &projectors[0]; - for (j = 1; j < num_projectors; j++) { + for (j = 1; j < projectors_num; j++) { float tmp_dot = dot_v3v3(projectors[j].normal, face_no); if (tmp_dot > best_dot) { best_dot = tmp_dot; @@ -277,7 +277,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, if (free_uci) { int j; - for (j = 0; j < num_projectors; j++) { + for (j = 0; j < projectors_num; j++) { if (projectors[j].uci) { MEM_freeN(projectors[j].uci); } diff --git a/source/blender/modifiers/intern/MOD_uvwarp.c b/source/blender/modifiers/intern/MOD_uvwarp.c index 0574b1897de..a15efdaa381 100644 --- a/source/blender/modifiers/intern/MOD_uvwarp.c +++ b/source/blender/modifiers/intern/MOD_uvwarp.c @@ -130,7 +130,7 @@ static void uv_warp_compute(void *__restrict userdata, static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { UVWarpModifierData *umd = (UVWarpModifierData *)md; - int numPolys, numLoops; + int polys_num, loops_num; MPoly *mpoly; MLoop *mloop; MLoopUV *mloopuv; @@ -196,14 +196,14 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* make sure we're using an existing layer */ CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, umd->uvlayer_name, uvname); - numPolys = mesh->totpoly; - numLoops = mesh->totloop; + polys_num = mesh->totpoly; + loops_num = mesh->totloop; mpoly = mesh->mpoly; mloop = mesh->mloop; /* make sure we are not modifying the original UV map */ mloopuv = CustomData_duplicate_referenced_layer_named( - &mesh->ldata, CD_MLOOPUV, uvname, numLoops); + &mesh->ldata, CD_MLOOPUV, uvname, loops_num); MOD_get_vgroup(ctx->object, mesh, umd->vgroup_name, &dvert, &defgrp_index); UVWarpData data = { @@ -217,8 +217,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * }; TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); - settings.use_threading = (numPolys > 1000); - BLI_task_parallel_range(0, numPolys, &data, uv_warp_compute, &settings); + settings.use_threading = (polys_num > 1000); + BLI_task_parallel_range(0, polys_num, &data, uv_warp_compute, &settings); mesh->runtime.is_original = false; diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c index 045b8e16736..8042172f204 100644 --- a/source/blender/modifiers/intern/MOD_warp.c +++ b/source/blender/modifiers/intern/MOD_warp.c @@ -181,7 +181,7 @@ static void warpModifier_do(WarpModifierData *wmd, const ModifierEvalContext *ctx, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { Object *ob = ctx->object; float obinv[4][4]; @@ -245,13 +245,13 @@ static void warpModifier_do(WarpModifierData *wmd, Tex *tex_target = wmd->texture; if (mesh != NULL && tex_target != NULL) { - tex_co = MEM_malloc_arrayN(numVerts, sizeof(*tex_co), "warpModifier_do tex_co"); + tex_co = MEM_malloc_arrayN(verts_num, sizeof(*tex_co), "warpModifier_do tex_co"); MOD_get_texture_coords((MappingInfoModifierData *)wmd, ctx, ob, mesh, vertexCos, tex_co); MOD_init_texture((MappingInfoModifierData *)wmd, ctx); } - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { float *co = vertexCos[i]; if (wmd->falloff_type == eWarp_Falloff_None || @@ -344,17 +344,17 @@ static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { WarpModifierData *wmd = (WarpModifierData *)md; Mesh *mesh_src = NULL; if (wmd->defgrp_name[0] != '\0' || wmd->texture != NULL) { /* mesh_src is only needed for vgroups and textures. */ - mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false); + mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false, false); } - warpModifier_do(wmd, ctx, mesh_src, vertexCos, numVerts); + warpModifier_do(wmd, ctx, mesh_src, vertexCos, verts_num); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); @@ -366,14 +366,14 @@ static void deformVertsEM(ModifierData *md, struct BMEditMesh *em, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { WarpModifierData *wmd = (WarpModifierData *)md; Mesh *mesh_src = NULL; if (wmd->defgrp_name[0] != '\0' || wmd->texture != NULL) { /* mesh_src is only needed for vgroups and textures. */ - mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, numVerts, false, false); + mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, verts_num, false, false); } /* TODO(Campbell): use edit-mode data only (remove this line). */ @@ -381,7 +381,7 @@ static void deformVertsEM(ModifierData *md, BKE_mesh_wrapper_ensure_mdata(mesh_src); } - warpModifier_do(wmd, ctx, mesh_src, vertexCos, numVerts); + warpModifier_do(wmd, ctx, mesh_src, vertexCos, verts_num); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.c index 9518cc253e7..4da2d67b8a6 100644 --- a/source/blender/modifiers/intern/MOD_wave.c +++ b/source/blender/modifiers/intern/MOD_wave.c @@ -133,7 +133,7 @@ static void waveModifier_do(WaveModifierData *md, Object *ob, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { WaveModifierData *wmd = (WaveModifierData *)md; MVert *mvert = NULL; @@ -188,7 +188,7 @@ static void waveModifier_do(WaveModifierData *md, Tex *tex_target = wmd->texture; if (mesh != NULL && tex_target != NULL) { - tex_co = MEM_malloc_arrayN(numVerts, sizeof(*tex_co), "waveModifier_do tex_co"); + tex_co = MEM_malloc_arrayN(verts_num, sizeof(*tex_co), "waveModifier_do tex_co"); MOD_get_texture_coords((MappingInfoModifierData *)wmd, ctx, ob, mesh, vertexCos, tex_co); MOD_init_texture((MappingInfoModifierData *)wmd, ctx); @@ -199,7 +199,7 @@ static void waveModifier_do(WaveModifierData *md, float falloff_inv = falloff != 0.0f ? 1.0f / falloff : 1.0f; int i; - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { float *co = vertexCos[i]; float x = co[0] - wmd->startx; float y = co[1] - wmd->starty; @@ -299,19 +299,20 @@ static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { WaveModifierData *wmd = (WaveModifierData *)md; Mesh *mesh_src = NULL; if (wmd->flag & MOD_WAVE_NORM) { - mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, vertexCos, numVerts, true, false); + mesh_src = MOD_deform_mesh_eval_get( + ctx->object, NULL, mesh, vertexCos, verts_num, true, false); } else if (wmd->texture != NULL || wmd->defgrp_name[0] != '\0') { - mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false); + mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false, false); } - waveModifier_do(wmd, ctx, ctx->object, mesh_src, vertexCos, numVerts); + waveModifier_do(wmd, ctx, ctx->object, mesh_src, vertexCos, verts_num); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); @@ -323,17 +324,18 @@ static void deformVertsEM(ModifierData *md, struct BMEditMesh *editData, Mesh *mesh, float (*vertexCos)[3], - int numVerts) + int verts_num) { WaveModifierData *wmd = (WaveModifierData *)md; Mesh *mesh_src = NULL; if (wmd->flag & MOD_WAVE_NORM) { mesh_src = MOD_deform_mesh_eval_get( - ctx->object, editData, mesh, vertexCos, numVerts, true, false); + ctx->object, editData, mesh, vertexCos, verts_num, true, false); } else if (wmd->texture != NULL || wmd->defgrp_name[0] != '\0') { - mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false); + mesh_src = MOD_deform_mesh_eval_get( + ctx->object, editData, mesh, NULL, verts_num, false, false); } /* TODO(Campbell): use edit-mode data only (remove this line). */ @@ -341,7 +343,7 @@ static void deformVertsEM(ModifierData *md, BKE_mesh_wrapper_ensure_mdata(mesh_src); } - waveModifier_do(wmd, ctx, ctx->object, mesh_src, vertexCos, numVerts); + waveModifier_do(wmd, ctx, ctx->object, mesh_src, vertexCos, verts_num); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.c b/source/blender/modifiers/intern/MOD_weighted_normal.c index 873372a35b8..c79dbdb0b1a 100644 --- a/source/blender/modifiers/intern/MOD_weighted_normal.c +++ b/source/blender/modifiers/intern/MOD_weighted_normal.c @@ -58,7 +58,7 @@ static int modepair_cmp_by_val_inverse(const void *p1, const void *p2) typedef struct WeightedNormalDataAggregateItem { float normal[3]; - int num_loops; /* Count number of loops using this item so far. */ + int loops_num; /* Count number of loops using this item so far. */ float curr_val; /* Current max val for this item. */ int curr_strength; /* Current max strength encountered for this item. */ } WeightedNormalDataAggregateItem; @@ -66,10 +66,10 @@ typedef struct WeightedNormalDataAggregateItem { #define NUM_CACHED_INVERSE_POWERS_OF_WEIGHT 128 typedef struct WeightedNormalData { - const int numVerts; - const int numEdges; - const int numLoops; - const int numPolys; + const int verts_num; + const int edges_num; + const int loops_num; + const int polys_num; MVert *mvert; const float (*vert_normals)[3]; @@ -116,7 +116,7 @@ static bool check_item_poly_strength(WeightedNormalData *wn_data, if (mp_strength > item_data->curr_strength) { item_data->curr_strength = mp_strength; item_data->curr_val = 0.0f; - item_data->num_loops = 0; + item_data->loops_num = 0; zero_v3(item_data->normal); } @@ -160,20 +160,20 @@ static void aggregate_item_normal(WeightedNormalModifierData *wnmd, } if (!compare_ff(item_data->curr_val, curr_val, wnmd->thresh)) { /* item's curr_val and present value differ more than threshold, update. */ - item_data->num_loops++; + item_data->loops_num++; item_data->curr_val = curr_val; } /* Exponentially divided weight for each normal * (since a few values will be used by most cases, we cache those). */ - const int num_loops = item_data->num_loops; - if (num_loops < NUM_CACHED_INVERSE_POWERS_OF_WEIGHT && - cached_inverse_powers_of_weight[num_loops] == 0.0f) { - cached_inverse_powers_of_weight[num_loops] = 1.0f / powf(weight, num_loops); + const int loops_num = item_data->loops_num; + if (loops_num < NUM_CACHED_INVERSE_POWERS_OF_WEIGHT && + cached_inverse_powers_of_weight[loops_num] == 0.0f) { + cached_inverse_powers_of_weight[loops_num] = 1.0f / powf(weight, loops_num); } - const float inverted_n_weight = num_loops < NUM_CACHED_INVERSE_POWERS_OF_WEIGHT ? - cached_inverse_powers_of_weight[num_loops] : - 1.0f / powf(weight, num_loops); + const float inverted_n_weight = loops_num < NUM_CACHED_INVERSE_POWERS_OF_WEIGHT ? + cached_inverse_powers_of_weight[loops_num] : + 1.0f / powf(weight, loops_num); madd_v3_v3fl(item_data->normal, polynors[mp_index], curr_val * inverted_n_weight); } @@ -181,10 +181,10 @@ static void aggregate_item_normal(WeightedNormalModifierData *wnmd, static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, WeightedNormalData *wn_data) { - const int numVerts = wn_data->numVerts; - const int numEdges = wn_data->numEdges; - const int numLoops = wn_data->numLoops; - const int numPolys = wn_data->numPolys; + const int verts_num = wn_data->verts_num; + const int edges_num = wn_data->edges_num; + const int loops_num = wn_data->loops_num; + const int polys_num = wn_data->polys_num; MVert *mvert = wn_data->mvert; MEdge *medge = wn_data->medge; @@ -214,39 +214,39 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, float(*loop_normals)[3] = NULL; WeightedNormalDataAggregateItem *items_data = NULL; - int num_items = 0; + int items_num = 0; if (keep_sharp) { - BLI_bitmap *done_loops = BLI_BITMAP_NEW(numLoops, __func__); + BLI_bitmap *done_loops = BLI_BITMAP_NEW(loops_num, __func__); /* This will give us loop normal spaces, * we do not actually care about computed loop_normals for now... */ - loop_normals = MEM_calloc_arrayN((size_t)numLoops, sizeof(*loop_normals), __func__); + loop_normals = MEM_calloc_arrayN((size_t)loops_num, sizeof(*loop_normals), __func__); BKE_mesh_normals_loop_split(mvert, wn_data->vert_normals, - numVerts, + verts_num, medge, - numEdges, + edges_num, mloop, loop_normals, - numLoops, + loops_num, mpoly, polynors, - numPolys, + polys_num, true, split_angle, &lnors_spacearr, has_clnors ? clnors : NULL, loop_to_poly); - num_items = lnors_spacearr.num_spaces; - items_data = MEM_calloc_arrayN((size_t)num_items, sizeof(*items_data), __func__); + items_num = lnors_spacearr.spaces_num; + items_data = MEM_calloc_arrayN((size_t)items_num, sizeof(*items_data), __func__); /* In this first loop, we assign each WeightedNormalDataAggregateItem * to its smooth fan of loops (aka lnor space). */ MPoly *mp; int mp_index; int item_index; - for (mp = mpoly, mp_index = 0, item_index = 0; mp_index < numPolys; mp++, mp_index++) { + for (mp = mpoly, mp_index = 0, item_index = 0; mp_index < polys_num; mp++, mp_index++) { int ml_index = mp->loopstart; const int ml_end_index = ml_index + mp->totloop; @@ -255,7 +255,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, /* Smooth fan of this loop has already been processed, skip it. */ continue; } - BLI_assert(item_index < num_items); + BLI_assert(item_index < items_num); WeightedNormalDataAggregateItem *itdt = &items_data[item_index]; itdt->curr_strength = FACE_STRENGTH_WEAK; @@ -280,10 +280,10 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, MEM_freeN(done_loops); } else { - num_items = numVerts; - items_data = MEM_calloc_arrayN((size_t)num_items, sizeof(*items_data), __func__); + items_num = verts_num; + items_data = MEM_calloc_arrayN((size_t)items_num, sizeof(*items_data), __func__); if (use_face_influence) { - for (int item_index = 0; item_index < num_items; item_index++) { + for (int item_index = 0; item_index < items_num; item_index++) { items_data[item_index].curr_strength = FACE_STRENGTH_WEAK; } } @@ -292,7 +292,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, switch (mode) { case MOD_WEIGHTEDNORMAL_MODE_FACE: - for (int i = 0; i < numPolys; i++) { + for (int i = 0; i < polys_num; i++) { const int mp_index = mode_pair[i].index; const float mp_val = mode_pair[i].val; @@ -312,7 +312,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, case MOD_WEIGHTEDNORMAL_MODE_FACE_ANGLE: BLI_assert(loop_to_poly != NULL); - for (int i = 0; i < numLoops; i++) { + for (int i = 0; i < loops_num; i++) { const int ml_index = mode_pair[i].index; const float ml_val = mode_pair[i].val; @@ -330,7 +330,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, } /* Validate computed weighted normals. */ - for (int item_index = 0; item_index < num_items; item_index++) { + for (int item_index = 0; item_index < items_num; item_index++) { if (normalize_v3(items_data[item_index].normal) < CLNORS_VALID_VEC_LEN) { zero_v3(items_data[item_index].normal); } @@ -341,7 +341,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, * Note that loop_normals is already populated with clnors * (before this modifier is applied, at start of this function), * so no need to recompute them here. */ - for (int ml_index = 0; ml_index < numLoops; ml_index++) { + for (int ml_index = 0; ml_index < loops_num; ml_index++) { WeightedNormalDataAggregateItem *item_data = lnors_spacearr.lspacearr[ml_index]->user_data; if (!is_zero_v3(item_data->normal)) { copy_v3_v3(loop_normals[ml_index], item_data->normal); @@ -350,15 +350,15 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, BKE_mesh_normals_loop_custom_set(mvert, wn_data->vert_normals, - numVerts, + verts_num, medge, - numEdges, + edges_num, mloop, loop_normals, - numLoops, + loops_num, mpoly, polynors, - numPolys, + polys_num, clnors); } else { @@ -372,9 +372,9 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, * But think we can live with it for now, * and it makes code simpler & cleaner. */ float(*vert_normals)[3] = MEM_calloc_arrayN( - (size_t)numVerts, sizeof(*loop_normals), __func__); + (size_t)verts_num, sizeof(*loop_normals), __func__); - for (int ml_index = 0; ml_index < numLoops; ml_index++) { + for (int ml_index = 0; ml_index < loops_num; ml_index++) { const int mv_index = mloop[ml_index].v; copy_v3_v3(vert_normals[mv_index], items_data[mv_index].normal); } @@ -382,39 +382,39 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, BKE_mesh_normals_loop_custom_from_vertices_set(mvert, wn_data->vert_normals, vert_normals, - numVerts, + verts_num, medge, - numEdges, + edges_num, mloop, - numLoops, + loops_num, mpoly, polynors, - numPolys, + polys_num, clnors); MEM_freeN(vert_normals); } else { - loop_normals = MEM_calloc_arrayN((size_t)numLoops, sizeof(*loop_normals), __func__); + loop_normals = MEM_calloc_arrayN((size_t)loops_num, sizeof(*loop_normals), __func__); BKE_mesh_normals_loop_split(mvert, wn_data->vert_normals, - numVerts, + verts_num, medge, - numEdges, + edges_num, mloop, loop_normals, - numLoops, + loops_num, mpoly, polynors, - numPolys, + polys_num, true, split_angle, NULL, has_clnors ? clnors : NULL, loop_to_poly); - for (int ml_index = 0; ml_index < numLoops; ml_index++) { + for (int ml_index = 0; ml_index < loops_num; ml_index++) { const int item_index = mloop[ml_index].v; if (!is_zero_v3(items_data[item_index].normal)) { copy_v3_v3(loop_normals[ml_index], items_data[item_index].normal); @@ -423,15 +423,15 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, BKE_mesh_normals_loop_custom_set(mvert, wn_data->vert_normals, - numVerts, + verts_num, medge, - numEdges, + edges_num, mloop, loop_normals, - numLoops, + loops_num, mpoly, polynors, - numPolys, + polys_num, clnors); } } @@ -444,7 +444,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, static void wn_face_area(WeightedNormalModifierData *wnmd, WeightedNormalData *wn_data) { - const int numPolys = wn_data->numPolys; + const int polys_num = wn_data->polys_num; MVert *mvert = wn_data->mvert; MLoop *mloop = wn_data->mloop; @@ -453,15 +453,15 @@ static void wn_face_area(WeightedNormalModifierData *wnmd, WeightedNormalData *w MPoly *mp; int mp_index; - ModePair *face_area = MEM_malloc_arrayN((size_t)numPolys, sizeof(*face_area), __func__); + ModePair *face_area = MEM_malloc_arrayN((size_t)polys_num, sizeof(*face_area), __func__); ModePair *f_area = face_area; - for (mp_index = 0, mp = mpoly; mp_index < numPolys; mp_index++, mp++, f_area++) { + for (mp_index = 0, mp = mpoly; mp_index < polys_num; mp_index++, mp++, f_area++) { f_area->val = BKE_mesh_calc_poly_area(mp, &mloop[mp->loopstart], mvert); f_area->index = mp_index; } - qsort(face_area, numPolys, sizeof(*face_area), modepair_cmp_by_val_inverse); + qsort(face_area, polys_num, sizeof(*face_area), modepair_cmp_by_val_inverse); wn_data->mode_pair = face_area; apply_weights_vertex_normal(wnmd, wn_data); @@ -469,8 +469,8 @@ static void wn_face_area(WeightedNormalModifierData *wnmd, WeightedNormalData *w static void wn_corner_angle(WeightedNormalModifierData *wnmd, WeightedNormalData *wn_data) { - const int numLoops = wn_data->numLoops; - const int numPolys = wn_data->numPolys; + const int loops_num = wn_data->loops_num; + const int polys_num = wn_data->polys_num; MVert *mvert = wn_data->mvert; MLoop *mloop = wn_data->mloop; @@ -479,11 +479,11 @@ static void wn_corner_angle(WeightedNormalModifierData *wnmd, WeightedNormalData MPoly *mp; int mp_index; - int *loop_to_poly = MEM_malloc_arrayN((size_t)numLoops, sizeof(*loop_to_poly), __func__); + int *loop_to_poly = MEM_malloc_arrayN((size_t)loops_num, sizeof(*loop_to_poly), __func__); - ModePair *corner_angle = MEM_malloc_arrayN((size_t)numLoops, sizeof(*corner_angle), __func__); + ModePair *corner_angle = MEM_malloc_arrayN((size_t)loops_num, sizeof(*corner_angle), __func__); - for (mp_index = 0, mp = mpoly; mp_index < numPolys; mp_index++, mp++) { + for (mp_index = 0, mp = mpoly; mp_index < polys_num; mp_index++, mp++) { MLoop *ml_start = &mloop[mp->loopstart]; float *index_angle = MEM_malloc_arrayN((size_t)mp->totloop, sizeof(*index_angle), __func__); @@ -501,7 +501,7 @@ static void wn_corner_angle(WeightedNormalModifierData *wnmd, WeightedNormalData MEM_freeN(index_angle); } - qsort(corner_angle, numLoops, sizeof(*corner_angle), modepair_cmp_by_val_inverse); + qsort(corner_angle, loops_num, sizeof(*corner_angle), modepair_cmp_by_val_inverse); wn_data->loop_to_poly = loop_to_poly; wn_data->mode_pair = corner_angle; @@ -510,8 +510,8 @@ static void wn_corner_angle(WeightedNormalModifierData *wnmd, WeightedNormalData static void wn_face_with_angle(WeightedNormalModifierData *wnmd, WeightedNormalData *wn_data) { - const int numLoops = wn_data->numLoops; - const int numPolys = wn_data->numPolys; + const int loops_num = wn_data->loops_num; + const int polys_num = wn_data->polys_num; MVert *mvert = wn_data->mvert; MLoop *mloop = wn_data->mloop; @@ -520,11 +520,11 @@ static void wn_face_with_angle(WeightedNormalModifierData *wnmd, WeightedNormalD MPoly *mp; int mp_index; - int *loop_to_poly = MEM_malloc_arrayN((size_t)numLoops, sizeof(*loop_to_poly), __func__); + int *loop_to_poly = MEM_malloc_arrayN((size_t)loops_num, sizeof(*loop_to_poly), __func__); - ModePair *combined = MEM_malloc_arrayN((size_t)numLoops, sizeof(*combined), __func__); + ModePair *combined = MEM_malloc_arrayN((size_t)loops_num, sizeof(*combined), __func__); - for (mp_index = 0, mp = mpoly; mp_index < numPolys; mp_index++, mp++) { + for (mp_index = 0, mp = mpoly; mp_index < polys_num; mp_index++, mp++) { MLoop *ml_start = &mloop[mp->loopstart]; float face_area = BKE_mesh_calc_poly_area(mp, ml_start, mvert); @@ -544,7 +544,7 @@ static void wn_face_with_angle(WeightedNormalModifierData *wnmd, WeightedNormalD MEM_freeN(index_angle); } - qsort(combined, numLoops, sizeof(*combined), modepair_cmp_by_val_inverse); + qsort(combined, loops_num, sizeof(*combined), modepair_cmp_by_val_inverse); wn_data->loop_to_poly = loop_to_poly; wn_data->mode_pair = combined; @@ -575,10 +575,10 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * Mesh *result; result = (Mesh *)BKE_id_copy_ex(NULL, &mesh->id, NULL, LIB_ID_COPY_LOCALIZE); - const int numVerts = result->totvert; - const int numEdges = result->totedge; - const int numLoops = result->totloop; - const int numPolys = result->totpoly; + const int verts_num = result->totvert; + const int edges_num = result->totedge; + const int loops_num = result->totloop; + const int polys_num = result->totpoly; MEdge *medge = result->medge; MPoly *mpoly = result->mpoly; @@ -611,7 +611,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * * it helps when generating clnor spaces and default normals. */ const bool has_clnors = clnors != NULL; if (!clnors) { - clnors = CustomData_add_layer(ldata, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, numLoops); + clnors = CustomData_add_layer(ldata, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, loops_num); } MDeformVert *dvert; @@ -619,10 +619,10 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * MOD_get_vgroup(ctx->object, mesh, wnmd->defgrp_name, &dvert, &defgrp_index); WeightedNormalData wn_data = { - .numVerts = numVerts, - .numEdges = numEdges, - .numLoops = numLoops, - .numPolys = numPolys, + .verts_num = verts_num, + .edges_num = edges_num, + .loops_num = loops_num, + .polys_num = polys_num, .mvert = mvert, .vert_normals = BKE_mesh_vertex_normals_ensure(result), diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.c b/source/blender/modifiers/intern/MOD_weightvg_util.c index a5c901dbe7a..b251825cd95 100644 --- a/source/blender/modifiers/intern/MOD_weightvg_util.c +++ b/source/blender/modifiers/intern/MOD_weightvg_util.c @@ -135,7 +135,7 @@ void weightvg_do_mask(const ModifierEvalContext *ctx, float(*tex_co)[3]; /* See mapping note below... */ MappingInfoModifierData t_map; - const int numVerts = mesh->totvert; + const int verts_num = mesh->totvert; /* Use new generic get_texture_coords, but do not modify our DNA struct for it... * XXX Why use a ModifierData stuff here ? Why not a simple, generic struct for parameters? @@ -148,7 +148,7 @@ void weightvg_do_mask(const ModifierEvalContext *ctx, BLI_strncpy(t_map.uvlayer_name, tex_uvlayer_name, sizeof(t_map.uvlayer_name)); t_map.texmapping = tex_mapping; - tex_co = MEM_calloc_arrayN(numVerts, sizeof(*tex_co), "WeightVG Modifier, TEX mode, tex_co"); + tex_co = MEM_calloc_arrayN(verts_num, sizeof(*tex_co), "WeightVG Modifier, TEX mode, tex_co"); MOD_get_texture_coords(&t_map, ctx, ob, mesh, NULL, tex_co); MOD_init_texture(&t_map, ctx); diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c index bce8ce82423..02991558c18 100644 --- a/source/blender/modifiers/intern/MOD_weightvgedit.c +++ b/source/blender/modifiers/intern/MOD_weightvgedit.c @@ -176,12 +176,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * #endif /* Get number of verts. */ - const int numVerts = mesh->totvert; + const int verts_num = mesh->totvert; /* Check if we can just return the original mesh. * Must have verts and therefore verts assigned to vgroups to do anything useful! */ - if ((numVerts == 0) || BLI_listbase_is_empty(&mesh->vertex_group_names)) { + if ((verts_num == 0) || BLI_listbase_is_empty(&mesh->vertex_group_names)) { return mesh; } @@ -201,11 +201,11 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } if (has_mdef) { - dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, numVerts); + dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, verts_num); } else { /* Add a valid data layer! */ - dvert = CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, numVerts); + dvert = CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, verts_num); } /* Ultimate security check. */ if (!dvert) { @@ -214,10 +214,10 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * mesh->dvert = dvert; /* Get org weights, assuming 0.0 for vertices not in given vgroup. */ - org_w = MEM_malloc_arrayN(numVerts, sizeof(float), "WeightVGEdit Modifier, org_w"); - new_w = MEM_malloc_arrayN(numVerts, sizeof(float), "WeightVGEdit Modifier, new_w"); - dw = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGEdit Modifier, dw"); - for (i = 0; i < numVerts; i++) { + org_w = MEM_malloc_arrayN(verts_num, sizeof(float), "WeightVGEdit Modifier, org_w"); + new_w = MEM_malloc_arrayN(verts_num, sizeof(float), "WeightVGEdit Modifier, new_w"); + dw = MEM_malloc_arrayN(verts_num, sizeof(MDeformWeight *), "WeightVGEdit Modifier, dw"); + for (i = 0; i < verts_num; i++) { dw[i] = BKE_defvert_find_index(&dvert[i], defgrp_index); if (dw[i]) { org_w[i] = new_w[i] = dw[i]->weight; @@ -237,7 +237,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ctx->object->id.name + 2)); } - weightvg_do_map(numVerts, new_w, wmd->falloff_type, do_invert_mapping, wmd->cmap_curve, rng); + weightvg_do_map(verts_num, new_w, wmd->falloff_type, do_invert_mapping, wmd->cmap_curve, rng); if (rng) { BLI_rng_free(rng); @@ -247,7 +247,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* Do masking. */ struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); weightvg_do_mask(ctx, - numVerts, + verts_num, NULL, org_w, new_w, @@ -268,7 +268,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * weightvg_update_vg(dvert, defgrp_index, dw, - numVerts, + verts_num, NULL, org_w, do_add, diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c index 7f9bf9d1e80..52c5e96c68e 100644 --- a/source/blender/modifiers/intern/MOD_weightvgmix.c +++ b/source/blender/modifiers/intern/MOD_weightvgmix.c @@ -213,7 +213,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * float *org_w; float *new_w; int *tidx, *indices = NULL; - int numIdx = 0; + int index_num = 0; int i; const bool invert_vgroup_mask = (wmd->flag & MOD_WVG_MIX_INVERT_VGROUP_MASK) != 0; const bool do_normalize = (wmd->flag & MOD_WVG_MIX_WEIGHTS_NORMALIZE) != 0; @@ -233,12 +233,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * #endif /* Get number of verts. */ - const int numVerts = mesh->totvert; + const int verts_num = mesh->totvert; /* Check if we can just return the original mesh. * Must have verts and therefore verts assigned to vgroups to do anything useful! */ - if ((numVerts == 0) || BLI_listbase_is_empty(&mesh->vertex_group_names)) { + if ((verts_num == 0) || BLI_listbase_is_empty(&mesh->vertex_group_names)) { return mesh; } @@ -266,11 +266,11 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } if (has_mdef) { - dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, numVerts); + dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, verts_num); } else { /* Add a valid data layer! */ - dvert = CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, numVerts); + dvert = CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, verts_num); } /* Ultimate security check. */ if (!dvert) { @@ -279,107 +279,107 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * mesh->dvert = dvert; /* Find out which vertices to work on. */ - tidx = MEM_malloc_arrayN(numVerts, sizeof(int), "WeightVGMix Modifier, tidx"); - tdw1 = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGMix Modifier, tdw1"); - tdw2 = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGMix Modifier, tdw2"); + tidx = MEM_malloc_arrayN(verts_num, sizeof(int), "WeightVGMix Modifier, tidx"); + tdw1 = MEM_malloc_arrayN(verts_num, sizeof(MDeformWeight *), "WeightVGMix Modifier, tdw1"); + tdw2 = MEM_malloc_arrayN(verts_num, sizeof(MDeformWeight *), "WeightVGMix Modifier, tdw2"); switch (wmd->mix_set) { case MOD_WVG_SET_A: /* All vertices in first vgroup. */ - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { MDeformWeight *dw = BKE_defvert_find_index(&dvert[i], defgrp_index); if (dw) { - tdw1[numIdx] = dw; - tdw2[numIdx] = (defgrp_index_other >= 0) ? - BKE_defvert_find_index(&dvert[i], defgrp_index_other) : - NULL; - tidx[numIdx++] = i; + tdw1[index_num] = dw; + tdw2[index_num] = (defgrp_index_other >= 0) ? + BKE_defvert_find_index(&dvert[i], defgrp_index_other) : + NULL; + tidx[index_num++] = i; } } break; case MOD_WVG_SET_B: /* All vertices in second vgroup. */ - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { MDeformWeight *dw = (defgrp_index_other >= 0) ? BKE_defvert_find_index(&dvert[i], defgrp_index_other) : NULL; if (dw) { - tdw1[numIdx] = BKE_defvert_find_index(&dvert[i], defgrp_index); - tdw2[numIdx] = dw; - tidx[numIdx++] = i; + tdw1[index_num] = BKE_defvert_find_index(&dvert[i], defgrp_index); + tdw2[index_num] = dw; + tidx[index_num++] = i; } } break; case MOD_WVG_SET_OR: /* All vertices in one vgroup or the other. */ - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { MDeformWeight *adw = BKE_defvert_find_index(&dvert[i], defgrp_index); MDeformWeight *bdw = (defgrp_index_other >= 0) ? BKE_defvert_find_index(&dvert[i], defgrp_index_other) : NULL; if (adw || bdw) { - tdw1[numIdx] = adw; - tdw2[numIdx] = bdw; - tidx[numIdx++] = i; + tdw1[index_num] = adw; + tdw2[index_num] = bdw; + tidx[index_num++] = i; } } break; case MOD_WVG_SET_AND: /* All vertices in both vgroups. */ - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { MDeformWeight *adw = BKE_defvert_find_index(&dvert[i], defgrp_index); MDeformWeight *bdw = (defgrp_index_other >= 0) ? BKE_defvert_find_index(&dvert[i], defgrp_index_other) : NULL; if (adw && bdw) { - tdw1[numIdx] = adw; - tdw2[numIdx] = bdw; - tidx[numIdx++] = i; + tdw1[index_num] = adw; + tdw2[index_num] = bdw; + tidx[index_num++] = i; } } break; case MOD_WVG_SET_ALL: default: /* Use all vertices. */ - for (i = 0; i < numVerts; i++) { + for (i = 0; i < verts_num; i++) { tdw1[i] = BKE_defvert_find_index(&dvert[i], defgrp_index); tdw2[i] = (defgrp_index_other >= 0) ? BKE_defvert_find_index(&dvert[i], defgrp_index_other) : NULL; } - numIdx = -1; + index_num = -1; break; } - if (numIdx == 0) { + if (index_num == 0) { /* Use no vertices! Hence, return org data. */ MEM_freeN(tdw1); MEM_freeN(tdw2); MEM_freeN(tidx); return mesh; } - if (numIdx != -1) { - indices = MEM_malloc_arrayN(numIdx, sizeof(int), "WeightVGMix Modifier, indices"); - memcpy(indices, tidx, sizeof(int) * numIdx); - dw1 = MEM_malloc_arrayN(numIdx, sizeof(MDeformWeight *), "WeightVGMix Modifier, dw1"); - memcpy(dw1, tdw1, sizeof(MDeformWeight *) * numIdx); + if (index_num != -1) { + indices = MEM_malloc_arrayN(index_num, sizeof(int), "WeightVGMix Modifier, indices"); + memcpy(indices, tidx, sizeof(int) * index_num); + dw1 = MEM_malloc_arrayN(index_num, sizeof(MDeformWeight *), "WeightVGMix Modifier, dw1"); + memcpy(dw1, tdw1, sizeof(MDeformWeight *) * index_num); MEM_freeN(tdw1); - dw2 = MEM_malloc_arrayN(numIdx, sizeof(MDeformWeight *), "WeightVGMix Modifier, dw2"); - memcpy(dw2, tdw2, sizeof(MDeformWeight *) * numIdx); + dw2 = MEM_malloc_arrayN(index_num, sizeof(MDeformWeight *), "WeightVGMix Modifier, dw2"); + memcpy(dw2, tdw2, sizeof(MDeformWeight *) * index_num); MEM_freeN(tdw2); } else { /* Use all vertices. */ - numIdx = numVerts; + index_num = verts_num; /* Just copy MDeformWeight pointers arrays, they will be freed at the end. */ dw1 = tdw1; dw2 = tdw2; } MEM_freeN(tidx); - org_w = MEM_malloc_arrayN(numIdx, sizeof(float), "WeightVGMix Modifier, org_w"); - new_w = MEM_malloc_arrayN(numIdx, sizeof(float), "WeightVGMix Modifier, new_w"); + org_w = MEM_malloc_arrayN(index_num, sizeof(float), "WeightVGMix Modifier, org_w"); + new_w = MEM_malloc_arrayN(index_num, sizeof(float), "WeightVGMix Modifier, new_w"); /* Mix weights. */ - for (i = 0; i < numIdx; i++) { + for (i = 0; i < index_num; i++) { float weight2; if (invert_vgroup_a) { org_w[i] = 1.0f - (dw1[i] ? dw1[i]->weight : wmd->default_weight_a); @@ -400,7 +400,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* Do masking. */ struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); weightvg_do_mask(ctx, - numIdx, + index_num, indices, org_w, new_w, @@ -420,13 +420,22 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* Update (add to) vgroup. * XXX Depending on the MOD_WVG_SET_xxx option chosen, we might have to add vertices to vgroup. */ - weightvg_update_vg( - dvert, defgrp_index, dw1, numIdx, indices, org_w, true, -FLT_MAX, false, 0.0f, do_normalize); + weightvg_update_vg(dvert, + defgrp_index, + dw1, + index_num, + indices, + org_w, + true, + -FLT_MAX, + false, + 0.0f, + do_normalize); /* If weight preview enabled... */ #if 0 /* XXX Currently done in mod stack :/ */ if (do_prev) { - DM_update_weight_mcol(ob, dm, 0, org_w, numIdx, indices); + DM_update_weight_mcol(ob, dm, 0, org_w, index_num, indices); } #endif diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c index 647db5c5aa4..7f11d348eff 100644 --- a/source/blender/modifiers/intern/MOD_weightvgproximity.c +++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c @@ -143,7 +143,7 @@ static void vert2geom_task_cb_ex(void *__restrict userdata, /** * Find nearest vertex and/or edge and/or face, for each vertex (adapted from shrinkwrap.c). */ -static void get_vert2geom_distance(int numVerts, +static void get_vert2geom_distance(int verts_num, float (*v_cos)[3], float *dist_v, float *dist_e, @@ -194,10 +194,10 @@ static void get_vert2geom_distance(int numVerts, TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); - settings.use_threading = (numVerts > 10000); + settings.use_threading = (verts_num > 10000); settings.userdata_chunk = &data_chunk; settings.userdata_chunk_size = sizeof(data_chunk); - BLI_task_parallel_range(0, numVerts, &data, vert2geom_task_cb_ex, &settings); + BLI_task_parallel_range(0, verts_num, &data, vert2geom_task_cb_ex, &settings); if (dist_v) { free_bvhtree_from_mesh(&treeData_v); @@ -215,11 +215,11 @@ static void get_vert2geom_distance(int numVerts, * Note that it works in final world space (i.e. with constraints etc. applied). */ static void get_vert2ob_distance( - int numVerts, float (*v_cos)[3], float *dist, Object *ob, Object *obr) + int verts_num, float (*v_cos)[3], float *dist, Object *ob, Object *obr) { /* Vertex and ref object coordinates. */ float v_wco[3]; - uint i = numVerts; + uint i = verts_num; while (i-- > 0) { /* Get world-coordinates of the vertex (constraints and anim included). */ @@ -435,7 +435,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * float *org_w = NULL; float *new_w = NULL; int *tidx, *indices = NULL; - int numIdx = 0; + int index_num = 0; int i; const bool invert_vgroup_mask = (wmd->proximity_flags & MOD_WVG_PROXIMITY_INVERT_VGROUP_MASK) != 0; @@ -450,12 +450,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * #endif /* Get number of verts. */ - const int numVerts = mesh->totvert; + const int verts_num = mesh->totvert; /* Check if we can just return the original mesh. * Must have verts and therefore verts assigned to vgroups to do anything useful! */ - if ((numVerts == 0) || BLI_listbase_is_empty(&mesh->vertex_group_names)) { + if ((verts_num == 0) || BLI_listbase_is_empty(&mesh->vertex_group_names)) { return mesh; } @@ -477,7 +477,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * return mesh; } - dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, numVerts); + dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, verts_num); /* Ultimate security check. */ if (!dvert) { return mesh; @@ -485,31 +485,31 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * mesh->dvert = dvert; /* Find out which vertices to work on (all vertices in vgroup), and get their relevant weight. */ - tidx = MEM_malloc_arrayN(numVerts, sizeof(int), "WeightVGProximity Modifier, tidx"); - tw = MEM_malloc_arrayN(numVerts, sizeof(float), "WeightVGProximity Modifier, tw"); - tdw = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGProximity Modifier, tdw"); - for (i = 0; i < numVerts; i++) { + tidx = MEM_malloc_arrayN(verts_num, sizeof(int), "WeightVGProximity Modifier, tidx"); + tw = MEM_malloc_arrayN(verts_num, sizeof(float), "WeightVGProximity Modifier, tw"); + tdw = MEM_malloc_arrayN(verts_num, sizeof(MDeformWeight *), "WeightVGProximity Modifier, tdw"); + for (i = 0; i < verts_num; i++) { MDeformWeight *_dw = BKE_defvert_find_index(&dvert[i], defgrp_index); if (_dw) { - tidx[numIdx] = i; - tw[numIdx] = _dw->weight; - tdw[numIdx++] = _dw; + tidx[index_num] = i; + tw[index_num] = _dw->weight; + tdw[index_num++] = _dw; } } /* If no vertices found, return org data! */ - if (numIdx == 0) { + if (index_num == 0) { MEM_freeN(tidx); MEM_freeN(tw); MEM_freeN(tdw); return mesh; } - if (numIdx != numVerts) { - indices = MEM_malloc_arrayN(numIdx, sizeof(int), "WeightVGProximity Modifier, indices"); - memcpy(indices, tidx, sizeof(int) * numIdx); - org_w = MEM_malloc_arrayN(numIdx, sizeof(float), "WeightVGProximity Modifier, org_w"); - memcpy(org_w, tw, sizeof(float) * numIdx); - dw = MEM_malloc_arrayN(numIdx, sizeof(MDeformWeight *), "WeightVGProximity Modifier, dw"); - memcpy(dw, tdw, sizeof(MDeformWeight *) * numIdx); + if (index_num != verts_num) { + indices = MEM_malloc_arrayN(index_num, sizeof(int), "WeightVGProximity Modifier, indices"); + memcpy(indices, tidx, sizeof(int) * index_num); + org_w = MEM_malloc_arrayN(index_num, sizeof(float), "WeightVGProximity Modifier, org_w"); + memcpy(org_w, tw, sizeof(float) * index_num); + dw = MEM_malloc_arrayN(index_num, sizeof(MDeformWeight *), "WeightVGProximity Modifier, dw"); + memcpy(dw, tdw, sizeof(MDeformWeight *) * index_num); MEM_freeN(tw); MEM_freeN(tdw); } @@ -517,14 +517,14 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * org_w = tw; dw = tdw; } - new_w = MEM_malloc_arrayN(numIdx, sizeof(float), "WeightVGProximity Modifier, new_w"); + new_w = MEM_malloc_arrayN(index_num, sizeof(float), "WeightVGProximity Modifier, new_w"); MEM_freeN(tidx); /* Get our vertex coordinates. */ - if (numIdx != numVerts) { + if (index_num != verts_num) { float(*tv_cos)[3] = BKE_mesh_vert_coords_alloc(mesh, NULL); - v_cos = MEM_malloc_arrayN(numIdx, sizeof(float[3]), "WeightVGProximity Modifier, v_cos"); - for (i = 0; i < numIdx; i++) { + v_cos = MEM_malloc_arrayN(index_num, sizeof(float[3]), "WeightVGProximity Modifier, v_cos"); + for (i = 0; i < index_num; i++) { copy_v3_v3(v_cos[i], tv_cos[indices[i]]); } MEM_freeN(tv_cos); @@ -536,7 +536,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* Compute wanted distances. */ if (wmd->proximity_mode == MOD_WVG_PROXIMITY_OBJECT) { const float dist = get_ob2ob_distance(ob, obr); - for (i = 0; i < numIdx; i++) { + for (i = 0; i < index_num; i++) { new_w[i] = dist; } } @@ -556,16 +556,17 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * BKE_mesh_wrapper_ensure_mdata(target_mesh); SpaceTransform loc2trgt; - float *dists_v = use_trgt_verts ? MEM_malloc_arrayN(numIdx, sizeof(float), "dists_v") : + float *dists_v = use_trgt_verts ? MEM_malloc_arrayN(index_num, sizeof(float), "dists_v") : NULL; - float *dists_e = use_trgt_edges ? MEM_malloc_arrayN(numIdx, sizeof(float), "dists_e") : + float *dists_e = use_trgt_edges ? MEM_malloc_arrayN(index_num, sizeof(float), "dists_e") : NULL; - float *dists_f = use_trgt_faces ? MEM_malloc_arrayN(numIdx, sizeof(float), "dists_f") : + float *dists_f = use_trgt_faces ? MEM_malloc_arrayN(index_num, sizeof(float), "dists_f") : NULL; BLI_SPACE_TRANSFORM_SETUP(&loc2trgt, ob, obr); - get_vert2geom_distance(numIdx, v_cos, dists_v, dists_e, dists_f, target_mesh, &loc2trgt); - for (i = 0; i < numIdx; i++) { + get_vert2geom_distance( + index_num, v_cos, dists_v, dists_e, dists_f, target_mesh, &loc2trgt); + for (i = 0; i < index_num; i++) { new_w[i] = dists_v ? dists_v[i] : FLT_MAX; if (dists_e) { new_w[i] = min_ff(dists_e[i], new_w[i]); @@ -581,18 +582,18 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } /* Else, fall back to default obj2vert behavior. */ else { - get_vert2ob_distance(numIdx, v_cos, new_w, ob, obr); + get_vert2ob_distance(index_num, v_cos, new_w, ob, obr); } } else { - get_vert2ob_distance(numIdx, v_cos, new_w, ob, obr); + get_vert2ob_distance(index_num, v_cos, new_w, ob, obr); } } /* Map distances to weights. */ do_map(ob, new_w, - numIdx, + index_num, wmd->min_dist, wmd->max_dist, wmd->falloff_type, @@ -602,7 +603,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* Do masking. */ struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); weightvg_do_mask(ctx, - numIdx, + index_num, indices, org_w, new_w, @@ -621,12 +622,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* Update vgroup. Note we never add nor remove vertices from vgroup here. */ weightvg_update_vg( - dvert, defgrp_index, dw, numIdx, indices, org_w, false, 0.0f, false, 0.0f, do_normalize); + dvert, defgrp_index, dw, index_num, indices, org_w, false, 0.0f, false, 0.0f, do_normalize); /* If weight preview enabled... */ #if 0 /* XXX Currently done in mod stack :/ */ if (do_prev) { - DM_update_weight_mcol(ob, dm, 0, org_w, numIdx, indices); + DM_update_weight_mcol(ob, dm, 0, org_w, index_num, indices); } #endif diff --git a/source/blender/nodes/composite/CMakeLists.txt b/source/blender/nodes/composite/CMakeLists.txt index b8bdd9859e0..57f76f20ac6 100644 --- a/source/blender/nodes/composite/CMakeLists.txt +++ b/source/blender/nodes/composite/CMakeLists.txt @@ -93,9 +93,9 @@ set(SRC nodes/node_composite_scene_time.cc nodes/node_composite_sepcomb_hsva.cc nodes/node_composite_sepcomb_rgba.cc + nodes/node_composite_sepcomb_xyz.cc nodes/node_composite_sepcomb_ycca.cc nodes/node_composite_sepcomb_yuva.cc - nodes/node_composite_sepcomb_xyz.cc nodes/node_composite_setalpha.cc nodes/node_composite_split_viewer.cc nodes/node_composite_stabilize2d.cc diff --git a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc index 162ef07a6dd..67d861aad9f 100644 --- a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc +++ b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc @@ -323,8 +323,8 @@ bNodeSocket *ntreeCompositCryptomatteAddSocket(bNodeTree *ntree, bNode *node) BLI_assert(node->type == CMP_NODE_CRYPTOMATTE_LEGACY); NodeCryptomatte *n = static_cast<NodeCryptomatte *>(node->storage); char sockname[32]; - n->num_inputs++; - BLI_snprintf(sockname, sizeof(sockname), "Crypto %.2d", n->num_inputs - 1); + n->inputs_num++; + BLI_snprintf(sockname, sizeof(sockname), "Crypto %.2d", n->inputs_num - 1); bNodeSocket *sock = nodeAddStaticSocket( ntree, node, SOCK_IN, SOCK_RGBA, PROP_NONE, nullptr, sockname); return sock; @@ -334,12 +334,12 @@ int ntreeCompositCryptomatteRemoveSocket(bNodeTree *ntree, bNode *node) { BLI_assert(node->type == CMP_NODE_CRYPTOMATTE_LEGACY); NodeCryptomatte *n = static_cast<NodeCryptomatte *>(node->storage); - if (n->num_inputs < 2) { + if (n->inputs_num < 2) { return 0; } bNodeSocket *sock = static_cast<bNodeSocket *>(node->inputs.last); nodeRemoveSocket(ntree, node, sock); - n->num_inputs--; + n->inputs_num--; return 1; } diff --git a/source/blender/nodes/geometry/CMakeLists.txt b/source/blender/nodes/geometry/CMakeLists.txt index 5c6c7532a0f..84280c0889a 100644 --- a/source/blender/nodes/geometry/CMakeLists.txt +++ b/source/blender/nodes/geometry/CMakeLists.txt @@ -58,9 +58,9 @@ set(SRC nodes/node_geo_curve_to_points.cc nodes/node_geo_curve_trim.cc nodes/node_geo_delete_geometry.cc - nodes/node_geo_duplicate_elements.cc nodes/node_geo_distribute_points_on_faces.cc nodes/node_geo_dual_mesh.cc + nodes/node_geo_duplicate_elements.cc nodes/node_geo_edge_split.cc nodes/node_geo_extrude_mesh.cc nodes/node_geo_field_at_index.cc diff --git a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc index 87fc6bcbad4..4792fada98b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc @@ -30,25 +30,25 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span<float3> coords) { plConvexHull hull = plConvexHullCompute((float(*)[3])coords.data(), coords.size()); - const int num_verts = plConvexHullNumVertices(hull); - const int num_faces = num_verts <= 2 ? 0 : plConvexHullNumFaces(hull); - const int num_loops = num_verts <= 2 ? 0 : plConvexHullNumLoops(hull); + const int verts_num = plConvexHullNumVertices(hull); + const int faces_num = verts_num <= 2 ? 0 : plConvexHullNumFaces(hull); + const int loops_num = verts_num <= 2 ? 0 : plConvexHullNumLoops(hull); /* Half as many edges as loops, because the mesh is manifold. */ - const int num_edges = num_verts == 2 ? 1 : num_verts < 2 ? 0 : num_loops / 2; + const int edges_num = verts_num == 2 ? 1 : verts_num < 2 ? 0 : loops_num / 2; /* Create Mesh *result with proper capacity. */ Mesh *result; if (mesh) { result = BKE_mesh_new_nomain_from_template( - mesh, num_verts, num_edges, 0, num_loops, num_faces); + mesh, verts_num, edges_num, 0, loops_num, faces_num); } else { - result = BKE_mesh_new_nomain(num_verts, num_edges, 0, num_loops, num_faces); + result = BKE_mesh_new_nomain(verts_num, edges_num, 0, loops_num, faces_num); BKE_id_material_eval_ensure_default_slot(&result->id); } /* Copy vertices. */ - for (const int i : IndexRange(num_verts)) { + for (const int i : IndexRange(verts_num)) { float co[3]; int original_index; plConvexHullGetVertex(hull, i, co, &original_index); @@ -73,9 +73,9 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span<float3> coords) /* NOTE: ConvexHull from Bullet uses a half-edge data structure * for its mesh. To convert that, each half-edge needs to be converted * to a loop and edges need to be created from that. */ - Array<MLoop> mloop_src(num_loops); + Array<MLoop> mloop_src(loops_num); uint edge_index = 0; - for (const int i : IndexRange(num_loops)) { + for (const int i : IndexRange(loops_num)) { int v_from; int v_to; plConvexHullGetLoop(hull, i, &v_from, &v_to); @@ -95,7 +95,7 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span<float3> coords) edge_index++; } } - if (num_edges == 1) { + if (edges_num == 1) { /* In this case there are no loops. */ MEdge &edge = result->medge[0]; edge.v1 = 0; @@ -103,13 +103,13 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span<float3> coords) edge.flag |= ME_EDGEDRAW | ME_EDGERENDER | ME_LOOSEEDGE; edge_index++; } - BLI_assert(edge_index == num_edges); + BLI_assert(edge_index == edges_num); /* Copy faces. */ Array<int> loops; int j = 0; MLoop *loop = result->mloop; - for (const int i : IndexRange(num_faces)) { + for (const int i : IndexRange(faces_num)) { const int len = plConvexHullGetFaceSize(hull, i); BLI_assert(len > 2); @@ -241,7 +241,7 @@ static void read_curve_positions(const Curves &curves_id, Vector<float3> *r_coords) { const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); - const int total_size = curves.evaluated_points_size(); + const int total_size = curves.evaluated_points_num(); r_coords->reserve(r_coords->size() + total_size * transforms.size()); r_coords->as_mutable_span().take_back(total_size).copy_from(curves.evaluated_positions()); for (const float3 &position : curves.evaluated_positions()) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc index 2c72e5f14f5..bbc8758952d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc @@ -55,24 +55,24 @@ class EndpointFieldInput final : public GeometryFieldInput { const Curves &curves_id = *curve_component.get_for_read(); const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); - if (curves.points_size() == 0) { + if (curves.points_num() == 0) { return nullptr; } GeometryComponentFieldContext size_context{curve_component, ATTR_DOMAIN_CURVE}; - fn::FieldEvaluator evaluator{size_context, curves.curves_size()}; + fn::FieldEvaluator evaluator{size_context, curves.curves_num()}; evaluator.add(start_size_); evaluator.add(end_size_); evaluator.evaluate(); const VArray<int> &start_size = evaluator.get_evaluated<int>(0); const VArray<int> &end_size = evaluator.get_evaluated<int>(1); - Array<bool> selection(curves.points_size(), false); + Array<bool> selection(curves.points_num(), false); MutableSpan<bool> selection_span = selection.as_mutable_span(); devirtualize_varray2(start_size, end_size, [&](const auto &start_size, const auto &end_size) { threading::parallel_for(curves.curves_range(), 1024, [&](IndexRange curves_range) { for (const int i : curves_range) { - const IndexRange range = curves.range_for_curve(i); + const IndexRange range = curves.points_for_curve(i); const int start = std::max(start_size[i], 0); const int end = std::max(end_size[i], 0); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc index 42c83d7a9e5..f29b193d98b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc @@ -45,14 +45,14 @@ static meshintersect::CDT_result<double> do_cdt(const bke::CurvesGeometry &curve { meshintersect::CDT_input<double> input; input.need_ids = false; - input.vert.reinitialize(curves.evaluated_points_size()); - input.face.reinitialize(curves.curves_size()); + input.vert.reinitialize(curves.evaluated_points_num()); + input.face.reinitialize(curves.curves_num()); VArray<bool> cyclic = curves.cyclic(); Span<float3> positions = curves.evaluated_positions(); for (const int i_curve : curves.curves_range()) { - const IndexRange points = curves.evaluated_range_for_curve(i_curve); + const IndexRange points = curves.evaluated_points_for_curve(i_curve); const int segment_size = bke::curves::curve_segment_size(points.size(), cyclic[i_curve]); for (const int i : points) { @@ -118,7 +118,7 @@ static void curve_fill_calculate(GeometrySet &geometry_set, const GeometryNodeCu const Curves &curves_id = *geometry_set.get_curves_for_read(); const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); - if (curves.curves_size() == 0) { + if (curves.curves_num() == 0) { geometry_set.replace_curves(nullptr); return; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc index 81ca87eec25..95ea978541c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc @@ -551,8 +551,8 @@ static std::unique_ptr<CurveEval> fillet_curve(const CurveEval &input_curve, Span<SplinePtr> input_splines = input_curve.splines(); std::unique_ptr<CurveEval> output_curve = std::make_unique<CurveEval>(); - const int num_splines = input_splines.size(); - output_curve->resize(num_splines); + const int splines_num = input_splines.size(); + output_curve->resize(splines_num); MutableSpan<SplinePtr> output_splines = output_curve->splines(); Array<int> spline_offsets = input_curve.control_point_offsets(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc index 775376d473e..dc2b9d40894 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc @@ -57,7 +57,7 @@ static void select_by_handle_type(const bke::CurvesGeometry &curves, VArray<int8_t> right = curves.handle_types_right(); for (const int i_curve : curves.curves_range()) { - const IndexRange points = curves.range_for_curve(i_curve); + const IndexRange points = curves.points_for_curve(i_curve); if (curve_types[i_curve] != CURVE_TYPE_BEZIER) { r_selection.slice(points).fill(false); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc index cf6837817c2..c3b1a141f4a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc @@ -168,12 +168,12 @@ static void copy_attributes_based_on_map(const Map<AttributeIDRef, AttributeKind static void copy_face_corner_attributes(const Map<AttributeIDRef, AttributeKind> &attributes, const GeometryComponent &in_component, GeometryComponent &out_component, - const int num_selected_loops, + const int selected_loops_num, const Span<int> selected_poly_indices, const Mesh &mesh_in) { Vector<int64_t> indices; - indices.reserve(num_selected_loops); + indices.reserve(selected_loops_num); for (const int src_poly_index : selected_poly_indices) { const MPoly &src_poly = mesh_in.mpoly[src_poly_index]; const int src_loop_start = src_poly.loopstart; @@ -546,47 +546,47 @@ static void separate_instance_selection(GeometrySet &geometry_set, static void compute_selected_vertices_from_vertex_selection(const Span<bool> vertex_selection, const bool invert, MutableSpan<int> r_vertex_map, - int *r_num_selected_vertices) + int *r_selected_vertices_num) { BLI_assert(vertex_selection.size() == r_vertex_map.size()); - int num_selected_vertices = 0; + int selected_verts_num = 0; for (const int i : r_vertex_map.index_range()) { if (vertex_selection[i] != invert) { - r_vertex_map[i] = num_selected_vertices; - num_selected_vertices++; + r_vertex_map[i] = selected_verts_num; + selected_verts_num++; } else { r_vertex_map[i] = -1; } } - *r_num_selected_vertices = num_selected_vertices; + *r_selected_vertices_num = selected_verts_num; } static void compute_selected_edges_from_vertex_selection(const Mesh &mesh, const Span<bool> vertex_selection, const bool invert, MutableSpan<int> r_edge_map, - int *r_num_selected_edges) + int *r_selected_edges_num) { BLI_assert(mesh.totedge == r_edge_map.size()); - int num_selected_edges = 0; + int selected_edges_num = 0; for (const int i : IndexRange(mesh.totedge)) { const MEdge &edge = mesh.medge[i]; /* Only add the edge if both vertices will be in the new mesh. */ if (vertex_selection[edge.v1] != invert && vertex_selection[edge.v2] != invert) { - r_edge_map[i] = num_selected_edges; - num_selected_edges++; + r_edge_map[i] = selected_edges_num; + selected_edges_num++; } else { r_edge_map[i] = -1; } } - *r_num_selected_edges = num_selected_edges; + *r_selected_edges_num = selected_edges_num; } static void compute_selected_polygons_from_vertex_selection(const Mesh &mesh, @@ -594,15 +594,15 @@ static void compute_selected_polygons_from_vertex_selection(const Mesh &mesh, const bool invert, Vector<int> &r_selected_poly_indices, Vector<int> &r_loop_starts, - int *r_num_selected_polys, - int *r_num_selected_loops) + int *r_selected_polys_num, + int *r_selected_loops_num) { BLI_assert(mesh.totvert == vertex_selection.size()); r_selected_poly_indices.reserve(mesh.totpoly); r_loop_starts.reserve(mesh.totloop); - int num_selected_loops = 0; + int selected_loops_num = 0; for (const int i : IndexRange(mesh.totpoly)) { const MPoly &poly_src = mesh.mpoly[i]; @@ -617,13 +617,13 @@ static void compute_selected_polygons_from_vertex_selection(const Mesh &mesh, if (all_verts_in_selection) { r_selected_poly_indices.append_unchecked(i); - r_loop_starts.append_unchecked(num_selected_loops); - num_selected_loops += poly_src.totloop; + r_loop_starts.append_unchecked(selected_loops_num); + selected_loops_num += poly_src.totloop; } } - *r_num_selected_polys = r_selected_poly_indices.size(); - *r_num_selected_loops = num_selected_loops; + *r_selected_polys_num = r_selected_poly_indices.size(); + *r_selected_loops_num = selected_loops_num; } /** @@ -636,25 +636,25 @@ static void compute_selected_vertices_and_edges_from_edge_selection( const bool invert, MutableSpan<int> r_vertex_map, MutableSpan<int> r_edge_map, - int *r_num_selected_vertices, - int *r_num_selected_edges) + int *r_selected_vertices_num, + int *r_selected_edges_num) { BLI_assert(mesh.totedge == edge_selection.size()); - int num_selected_edges = 0; - int num_selected_vertices = 0; + int selected_edges_num = 0; + int selected_verts_num = 0; for (const int i : IndexRange(mesh.totedge)) { const MEdge &edge = mesh.medge[i]; if (edge_selection[i] != invert) { - r_edge_map[i] = num_selected_edges; - num_selected_edges++; + r_edge_map[i] = selected_edges_num; + selected_edges_num++; if (r_vertex_map[edge.v1] == -1) { - r_vertex_map[edge.v1] = num_selected_vertices; - num_selected_vertices++; + r_vertex_map[edge.v1] = selected_verts_num; + selected_verts_num++; } if (r_vertex_map[edge.v2] == -1) { - r_vertex_map[edge.v2] = num_selected_vertices; - num_selected_vertices++; + r_vertex_map[edge.v2] = selected_verts_num; + selected_verts_num++; } } else { @@ -662,8 +662,8 @@ static void compute_selected_vertices_and_edges_from_edge_selection( } } - *r_num_selected_vertices = num_selected_vertices; - *r_num_selected_edges = num_selected_edges; + *r_selected_vertices_num = selected_verts_num; + *r_selected_edges_num = selected_edges_num; } /** @@ -673,22 +673,22 @@ static void compute_selected_edges_from_edge_selection(const Mesh &mesh, const Span<bool> edge_selection, const bool invert, MutableSpan<int> r_edge_map, - int *r_num_selected_edges) + int *r_selected_edges_num) { BLI_assert(mesh.totedge == edge_selection.size()); - int num_selected_edges = 0; + int selected_edges_num = 0; for (const int i : IndexRange(mesh.totedge)) { if (edge_selection[i] != invert) { - r_edge_map[i] = num_selected_edges; - num_selected_edges++; + r_edge_map[i] = selected_edges_num; + selected_edges_num++; } else { r_edge_map[i] = -1; } } - *r_num_selected_edges = num_selected_edges; + *r_selected_edges_num = selected_edges_num; } /** @@ -700,13 +700,13 @@ static void compute_selected_polygons_from_edge_selection(const Mesh &mesh, const bool invert, Vector<int> &r_selected_poly_indices, Vector<int> &r_loop_starts, - int *r_num_selected_polys, - int *r_num_selected_loops) + int *r_selected_polys_num, + int *r_selected_loops_num) { r_selected_poly_indices.reserve(mesh.totpoly); r_loop_starts.reserve(mesh.totloop); - int num_selected_loops = 0; + int selected_loops_num = 0; for (const int i : IndexRange(mesh.totpoly)) { const MPoly &poly_src = mesh.mpoly[i]; @@ -721,13 +721,13 @@ static void compute_selected_polygons_from_edge_selection(const Mesh &mesh, if (all_edges_in_selection) { r_selected_poly_indices.append_unchecked(i); - r_loop_starts.append_unchecked(num_selected_loops); - num_selected_loops += poly_src.totloop; + r_loop_starts.append_unchecked(selected_loops_num); + selected_loops_num += poly_src.totloop; } } - *r_num_selected_polys = r_selected_poly_indices.size(); - *r_num_selected_loops = num_selected_loops; + *r_selected_polys_num = r_selected_poly_indices.size(); + *r_selected_loops_num = selected_loops_num; } /** @@ -740,21 +740,21 @@ static void compute_selected_mesh_data_from_vertex_selection_edge_face( MutableSpan<int> r_edge_map, Vector<int> &r_selected_poly_indices, Vector<int> &r_loop_starts, - int *r_num_selected_edges, - int *r_num_selected_polys, - int *r_num_selected_loops) + int *r_selected_edges_num, + int *r_selected_polys_num, + int *r_selected_loops_num) { compute_selected_edges_from_vertex_selection( - mesh, vertex_selection, invert, r_edge_map, r_num_selected_edges); + mesh, vertex_selection, invert, r_edge_map, r_selected_edges_num); compute_selected_polygons_from_vertex_selection(mesh, vertex_selection, invert, r_selected_poly_indices, r_loop_starts, - r_num_selected_polys, - r_num_selected_loops); + r_selected_polys_num, + r_selected_loops_num); } /** @@ -768,24 +768,24 @@ static void compute_selected_mesh_data_from_vertex_selection(const Mesh &mesh, MutableSpan<int> r_edge_map, Vector<int> &r_selected_poly_indices, Vector<int> &r_loop_starts, - int *r_num_selected_vertices, - int *r_num_selected_edges, - int *r_num_selected_polys, - int *r_num_selected_loops) + int *r_selected_vertices_num, + int *r_selected_edges_num, + int *r_selected_polys_num, + int *r_selected_loops_num) { compute_selected_vertices_from_vertex_selection( - vertex_selection, invert, r_vertex_map, r_num_selected_vertices); + vertex_selection, invert, r_vertex_map, r_selected_vertices_num); compute_selected_edges_from_vertex_selection( - mesh, vertex_selection, invert, r_edge_map, r_num_selected_edges); + mesh, vertex_selection, invert, r_edge_map, r_selected_edges_num); compute_selected_polygons_from_vertex_selection(mesh, vertex_selection, invert, r_selected_poly_indices, r_loop_starts, - r_num_selected_polys, - r_num_selected_loops); + r_selected_polys_num, + r_selected_loops_num); } /** @@ -799,19 +799,19 @@ static void compute_selected_mesh_data_from_edge_selection_edge_face( MutableSpan<int> r_edge_map, Vector<int> &r_selected_poly_indices, Vector<int> &r_loop_starts, - int *r_num_selected_edges, - int *r_num_selected_polys, - int *r_num_selected_loops) + int *r_selected_edges_num, + int *r_selected_polys_num, + int *r_selected_loops_num) { compute_selected_edges_from_edge_selection( - mesh, edge_selection, invert, r_edge_map, r_num_selected_edges); + mesh, edge_selection, invert, r_edge_map, r_selected_edges_num); compute_selected_polygons_from_edge_selection(mesh, edge_selection, invert, r_selected_poly_indices, r_loop_starts, - r_num_selected_polys, - r_num_selected_loops); + r_selected_polys_num, + r_selected_loops_num); } /** @@ -825,10 +825,10 @@ static void compute_selected_mesh_data_from_edge_selection(const Mesh &mesh, MutableSpan<int> r_edge_map, Vector<int> &r_selected_poly_indices, Vector<int> &r_loop_starts, - int *r_num_selected_vertices, - int *r_num_selected_edges, - int *r_num_selected_polys, - int *r_num_selected_loops) + int *r_selected_vertices_num, + int *r_selected_edges_num, + int *r_selected_polys_num, + int *r_selected_loops_num) { r_vertex_map.fill(-1); compute_selected_vertices_and_edges_from_edge_selection(mesh, @@ -836,15 +836,15 @@ static void compute_selected_mesh_data_from_edge_selection(const Mesh &mesh, invert, r_vertex_map, r_edge_map, - r_num_selected_vertices, - r_num_selected_edges); + r_selected_vertices_num, + r_selected_edges_num); compute_selected_polygons_from_edge_selection(mesh, edge_selection, invert, r_selected_poly_indices, r_loop_starts, - r_num_selected_polys, - r_num_selected_loops); + r_selected_polys_num, + r_selected_loops_num); } /** @@ -855,26 +855,26 @@ static void compute_selected_polygons_from_poly_selection(const Mesh &mesh, const bool invert, Vector<int> &r_selected_poly_indices, Vector<int> &r_loop_starts, - int *r_num_selected_polys, - int *r_num_selected_loops) + int *r_selected_polys_num, + int *r_selected_loops_num) { BLI_assert(mesh.totpoly == poly_selection.size()); r_selected_poly_indices.reserve(mesh.totpoly); r_loop_starts.reserve(mesh.totloop); - int num_selected_loops = 0; + int selected_loops_num = 0; for (const int i : IndexRange(mesh.totpoly)) { const MPoly &poly_src = mesh.mpoly[i]; /* We keep this one. */ if (poly_selection[i] != invert) { r_selected_poly_indices.append_unchecked(i); - r_loop_starts.append_unchecked(num_selected_loops); - num_selected_loops += poly_src.totloop; + r_loop_starts.append_unchecked(selected_loops_num); + selected_loops_num += poly_src.totloop; } } - *r_num_selected_polys = r_selected_poly_indices.size(); - *r_num_selected_loops = num_selected_loops; + *r_selected_polys_num = r_selected_poly_indices.size(); + *r_selected_loops_num = selected_loops_num; } /** * Checks for every polygon if it is in `poly_selection`. If it is, the edges @@ -887,9 +887,9 @@ static void compute_selected_mesh_data_from_poly_selection_edge_face( MutableSpan<int> r_edge_map, Vector<int> &r_selected_poly_indices, Vector<int> &r_loop_starts, - int *r_num_selected_edges, - int *r_num_selected_polys, - int *r_num_selected_loops) + int *r_selected_edges_num, + int *r_selected_polys_num, + int *r_selected_loops_num) { BLI_assert(mesh.totpoly == poly_selection.size()); BLI_assert(mesh.totedge == r_edge_map.size()); @@ -898,30 +898,30 @@ static void compute_selected_mesh_data_from_poly_selection_edge_face( r_selected_poly_indices.reserve(mesh.totpoly); r_loop_starts.reserve(mesh.totloop); - int num_selected_loops = 0; - int num_selected_edges = 0; + int selected_loops_num = 0; + int selected_edges_num = 0; for (const int i : IndexRange(mesh.totpoly)) { const MPoly &poly_src = mesh.mpoly[i]; /* We keep this one. */ if (poly_selection[i] != invert) { r_selected_poly_indices.append_unchecked(i); - r_loop_starts.append_unchecked(num_selected_loops); - num_selected_loops += poly_src.totloop; + r_loop_starts.append_unchecked(selected_loops_num); + selected_loops_num += poly_src.totloop; /* Add the vertices and the edges. */ Span<MLoop> loops_src(&mesh.mloop[poly_src.loopstart], poly_src.totloop); for (const MLoop &loop : loops_src) { /* Check first if it has not yet been added. */ if (r_edge_map[loop.e] == -1) { - r_edge_map[loop.e] = num_selected_edges; - num_selected_edges++; + r_edge_map[loop.e] = selected_edges_num; + selected_edges_num++; } } } } - *r_num_selected_edges = num_selected_edges; - *r_num_selected_polys = r_selected_poly_indices.size(); - *r_num_selected_loops = num_selected_loops; + *r_selected_edges_num = selected_edges_num; + *r_selected_polys_num = r_selected_poly_indices.size(); + *r_selected_loops_num = selected_loops_num; } /** @@ -935,10 +935,10 @@ static void compute_selected_mesh_data_from_poly_selection(const Mesh &mesh, MutableSpan<int> r_edge_map, Vector<int> &r_selected_poly_indices, Vector<int> &r_loop_starts, - int *r_num_selected_vertices, - int *r_num_selected_edges, - int *r_num_selected_polys, - int *r_num_selected_loops) + int *r_selected_vertices_num, + int *r_selected_edges_num, + int *r_selected_polys_num, + int *r_selected_loops_num) { BLI_assert(mesh.totpoly == poly_selection.size()); BLI_assert(mesh.totedge == r_edge_map.size()); @@ -948,36 +948,36 @@ static void compute_selected_mesh_data_from_poly_selection(const Mesh &mesh, r_selected_poly_indices.reserve(mesh.totpoly); r_loop_starts.reserve(mesh.totloop); - int num_selected_loops = 0; - int num_selected_vertices = 0; - int num_selected_edges = 0; + int selected_loops_num = 0; + int selected_verts_num = 0; + int selected_edges_num = 0; for (const int i : IndexRange(mesh.totpoly)) { const MPoly &poly_src = mesh.mpoly[i]; /* We keep this one. */ if (poly_selection[i] != invert) { r_selected_poly_indices.append_unchecked(i); - r_loop_starts.append_unchecked(num_selected_loops); - num_selected_loops += poly_src.totloop; + r_loop_starts.append_unchecked(selected_loops_num); + selected_loops_num += poly_src.totloop; /* Add the vertices and the edges. */ Span<MLoop> loops_src(&mesh.mloop[poly_src.loopstart], poly_src.totloop); for (const MLoop &loop : loops_src) { /* Check first if it has not yet been added. */ if (r_vertex_map[loop.v] == -1) { - r_vertex_map[loop.v] = num_selected_vertices; - num_selected_vertices++; + r_vertex_map[loop.v] = selected_verts_num; + selected_verts_num++; } if (r_edge_map[loop.e] == -1) { - r_edge_map[loop.e] = num_selected_edges; - num_selected_edges++; + r_edge_map[loop.e] = selected_edges_num; + selected_edges_num++; } } } } - *r_num_selected_vertices = num_selected_vertices; - *r_num_selected_edges = num_selected_edges; - *r_num_selected_polys = r_selected_poly_indices.size(); - *r_num_selected_loops = num_selected_loops; + *r_selected_vertices_num = selected_verts_num; + *r_selected_edges_num = selected_edges_num; + *r_selected_polys_num = r_selected_poly_indices.size(); + *r_selected_loops_num = selected_loops_num; } /** @@ -993,8 +993,8 @@ static void do_mesh_separation(GeometrySet &geometry_set, /* Needed in all cases. */ Vector<int> selected_poly_indices; Vector<int> new_loop_starts; - int num_selected_polys = 0; - int num_selected_loops = 0; + int selected_polys_num = 0; + int selected_loops_num = 0; const Mesh &mesh_in = *in_component.get_for_read(); Mesh *mesh_out; @@ -1007,10 +1007,10 @@ static void do_mesh_separation(GeometrySet &geometry_set, switch (mode) { case GEO_NODE_DELETE_GEOMETRY_MODE_ALL: { Array<int> vertex_map(mesh_in.totvert); - int num_selected_vertices = 0; + int selected_verts_num = 0; Array<int> edge_map(mesh_in.totedge); - int num_selected_edges = 0; + int selected_edges_num = 0; /* Fill all the maps based on the selection. */ switch (domain) { @@ -1022,10 +1022,10 @@ static void do_mesh_separation(GeometrySet &geometry_set, edge_map, selected_poly_indices, new_loop_starts, - &num_selected_vertices, - &num_selected_edges, - &num_selected_polys, - &num_selected_loops); + &selected_verts_num, + &selected_edges_num, + &selected_polys_num, + &selected_loops_num); break; case ATTR_DOMAIN_EDGE: compute_selected_mesh_data_from_edge_selection(mesh_in, @@ -1035,10 +1035,10 @@ static void do_mesh_separation(GeometrySet &geometry_set, edge_map, selected_poly_indices, new_loop_starts, - &num_selected_vertices, - &num_selected_edges, - &num_selected_polys, - &num_selected_loops); + &selected_verts_num, + &selected_edges_num, + &selected_polys_num, + &selected_loops_num); break; case ATTR_DOMAIN_FACE: compute_selected_mesh_data_from_poly_selection(mesh_in, @@ -1048,21 +1048,21 @@ static void do_mesh_separation(GeometrySet &geometry_set, edge_map, selected_poly_indices, new_loop_starts, - &num_selected_vertices, - &num_selected_edges, - &num_selected_polys, - &num_selected_loops); + &selected_verts_num, + &selected_edges_num, + &selected_polys_num, + &selected_loops_num); break; default: BLI_assert_unreachable(); break; } mesh_out = BKE_mesh_new_nomain_from_template(&mesh_in, - num_selected_vertices, - num_selected_edges, + selected_verts_num, + selected_edges_num, 0, - num_selected_loops, - num_selected_polys); + selected_loops_num, + selected_polys_num); out_component.replace(mesh_out, GeometryOwnershipType::Editable); /* Copy the selected parts of the mesh over to the new mesh. */ @@ -1084,14 +1084,14 @@ static void do_mesh_separation(GeometrySet &geometry_set, copy_face_corner_attributes(attributes, in_component, out_component, - num_selected_loops, + selected_loops_num, selected_poly_indices, mesh_in); break; } case GEO_NODE_DELETE_GEOMETRY_MODE_EDGE_FACE: { Array<int> edge_map(mesh_in.totedge); - int num_selected_edges = 0; + int selected_edges_num = 0; /* Fill all the maps based on the selection. */ switch (domain) { @@ -1102,9 +1102,9 @@ static void do_mesh_separation(GeometrySet &geometry_set, edge_map, selected_poly_indices, new_loop_starts, - &num_selected_edges, - &num_selected_polys, - &num_selected_loops); + &selected_edges_num, + &selected_polys_num, + &selected_loops_num); break; case ATTR_DOMAIN_EDGE: compute_selected_mesh_data_from_edge_selection_edge_face(mesh_in, @@ -1113,9 +1113,9 @@ static void do_mesh_separation(GeometrySet &geometry_set, edge_map, selected_poly_indices, new_loop_starts, - &num_selected_edges, - &num_selected_polys, - &num_selected_loops); + &selected_edges_num, + &selected_polys_num, + &selected_loops_num); break; case ATTR_DOMAIN_FACE: compute_selected_mesh_data_from_poly_selection_edge_face(mesh_in, @@ -1124,9 +1124,9 @@ static void do_mesh_separation(GeometrySet &geometry_set, edge_map, selected_poly_indices, new_loop_starts, - &num_selected_edges, - &num_selected_polys, - &num_selected_loops); + &selected_edges_num, + &selected_polys_num, + &selected_loops_num); break; default: BLI_assert_unreachable(); @@ -1134,10 +1134,10 @@ static void do_mesh_separation(GeometrySet &geometry_set, } mesh_out = BKE_mesh_new_nomain_from_template(&mesh_in, mesh_in.totvert, - num_selected_edges, + selected_edges_num, 0, - num_selected_loops, - num_selected_polys); + selected_loops_num, + selected_polys_num); out_component.replace(mesh_out, GeometryOwnershipType::Editable); /* Copy the selected parts of the mesh over to the new mesh. */ @@ -1158,7 +1158,7 @@ static void do_mesh_separation(GeometrySet &geometry_set, copy_face_corner_attributes(attributes, in_component, out_component, - num_selected_loops, + selected_loops_num, selected_poly_indices, mesh_in); break; @@ -1172,8 +1172,8 @@ static void do_mesh_separation(GeometrySet &geometry_set, invert, selected_poly_indices, new_loop_starts, - &num_selected_polys, - &num_selected_loops); + &selected_polys_num, + &selected_loops_num); break; case ATTR_DOMAIN_EDGE: compute_selected_polygons_from_edge_selection(mesh_in, @@ -1181,8 +1181,8 @@ static void do_mesh_separation(GeometrySet &geometry_set, invert, selected_poly_indices, new_loop_starts, - &num_selected_polys, - &num_selected_loops); + &selected_polys_num, + &selected_loops_num); break; case ATTR_DOMAIN_FACE: compute_selected_polygons_from_poly_selection(mesh_in, @@ -1190,15 +1190,15 @@ static void do_mesh_separation(GeometrySet &geometry_set, invert, selected_poly_indices, new_loop_starts, - &num_selected_polys, - &num_selected_loops); + &selected_polys_num, + &selected_loops_num); break; default: BLI_assert_unreachable(); break; } mesh_out = BKE_mesh_new_nomain_from_template( - &mesh_in, mesh_in.totvert, mesh_in.totedge, 0, num_selected_loops, num_selected_polys); + &mesh_in, mesh_in.totvert, mesh_in.totedge, 0, selected_loops_num, selected_polys_num); out_component.replace(mesh_out, GeometryOwnershipType::Editable); /* Copy the selected parts of the mesh over to the new mesh. */ @@ -1217,7 +1217,7 @@ static void do_mesh_separation(GeometrySet &geometry_set, copy_face_corner_attributes(attributes, in_component, out_component, - num_selected_loops, + selected_loops_num, selected_poly_indices, mesh_in); break; diff --git a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc index 39e5748daa5..2aa768129cd 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc @@ -60,18 +60,16 @@ struct IndexAttributes { /** \name Utility Functions * \{ */ -static void gather_attributes_without_id(const GeometrySet &geometry_set, - const GeometryComponentType component_type, - const Span<std::string> skip_attributes, - const bool include_instances, - Map<AttributeIDRef, AttributeKind> &r_gathered_attributes) +static Map<AttributeIDRef, AttributeKind> gather_attributes_without_id( + const GeometrySet &geometry_set, + const GeometryComponentType component_type, + const bool include_instances) { + Map<AttributeIDRef, AttributeKind> attributes; geometry_set.gather_attributes_for_propagation( - {component_type}, component_type, include_instances, r_gathered_attributes); - for (const std::string &attribute : skip_attributes) { - r_gathered_attributes.remove(attribute); - } - r_gathered_attributes.remove("id"); + {component_type}, component_type, include_instances, attributes); + attributes.remove("id"); + return attributes; }; static IndexRange range_for_offsets_index(const Span<int> offsets, const int index) @@ -83,12 +81,12 @@ static Array<int> accumulate_counts_to_offsets(const IndexMask selection, const VArray<int> &counts) { Array<int> offsets(selection.size() + 1); - int dst_points_size = 0; - for (const int i_point : selection.index_range()) { - offsets[i_point] = dst_points_size; - dst_points_size += std::max(counts[selection[i_point]], 0); + int total = 0; + for (const int i : selection.index_range()) { + offsets[i] = total; + total += std::max(counts[selection[i]], 0); } - offsets.last() = dst_points_size; + offsets.last() = total; return offsets; } @@ -141,11 +139,11 @@ static void threaded_id_offset_copy(const Span<int> offsets, static void create_duplicate_index_attribute(GeometryComponent &component, const AttributeDomain output_domain, const IndexMask selection, - const IndexAttributes &attributes, + const IndexAttributes &attribute_outputs, const Span<int> offsets) { OutputAttribute_Typed<int> copy_attribute = component.attribute_try_get_for_output_only<int>( - attributes.duplicate_index.get(), output_domain); + attribute_outputs.duplicate_index.get(), output_domain); MutableSpan<int> duplicate_indices = copy_attribute.as_span(); for (const int i : IndexRange(selection.size())) { const IndexRange range = range_for_offsets_index(offsets, i); @@ -193,11 +191,10 @@ static void copy_point_attributes_without_id(GeometrySet &geometry_set, const GeometryComponent &src_component, GeometryComponent &dst_component) { - Map<AttributeIDRef, AttributeKind> gathered_attributes; - gather_attributes_without_id( - geometry_set, component_type, {}, include_instances, gathered_attributes); + Map<AttributeIDRef, AttributeKind> attributes = gather_attributes_without_id( + geometry_set, component_type, include_instances); - for (const Map<AttributeIDRef, AttributeKind>::Item entry : gathered_attributes.items()) { + for (const Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) { const AttributeIDRef attribute_id = entry.key; ReadAttributeLookup src_attribute = src_component.attribute_try_get_for_read(attribute_id); if (!src_attribute || src_attribute.domain != ATTR_DOMAIN_POINT) { @@ -239,12 +236,10 @@ static void copy_curve_attributes_without_id(const GeometrySet &geometry_set, bke::CurvesGeometry &dst_curves, CurveComponent &dst_component) { - Map<AttributeIDRef, AttributeKind> gathered_attributes; - gather_attributes_without_id( - geometry_set, GEO_COMPONENT_TYPE_CURVE, {}, false, gathered_attributes); - - for (const Map<AttributeIDRef, AttributeKind>::Item entry : gathered_attributes.items()) { + Map<AttributeIDRef, AttributeKind> attributes = gather_attributes_without_id( + geometry_set, GEO_COMPONENT_TYPE_CURVE, false); + for (const Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) { const AttributeIDRef attribute_id = entry.key; ReadAttributeLookup src_attribute = src_component.attribute_try_get_for_read(attribute_id); if (!src_attribute) { @@ -273,9 +268,9 @@ static void copy_curve_attributes_without_id(const GeometrySet &geometry_set, threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) { for (const int i_selection : range) { const int i_src_curve = selection[i_selection]; - const Span<T> curve_src = src.slice(src_curves.range_for_curve(i_src_curve)); + const Span<T> curve_src = src.slice(src_curves.points_for_curve(i_src_curve)); for (const int i_dst_curve : range_for_offsets_index(curve_offsets, i_selection)) { - dst.slice(dst_curves.range_for_curve(i_dst_curve)).copy_from(curve_src); + dst.slice(dst_curves.points_for_curve(i_dst_curve)).copy_from(curve_src); } } }); @@ -317,12 +312,12 @@ static void copy_stable_id_curves(const bke::CurvesGeometry &src_curves, threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) { for (const int i_selection : range) { const int i_src_curve = selection[i_selection]; - const Span<int> curve_src = src.slice(src_curves.range_for_curve(i_src_curve)); + const Span<int> curve_src = src.slice(src_curves.points_for_curve(i_src_curve)); const IndexRange duplicates_range = range_for_offsets_index(curve_offsets, i_selection); for (const int i_duplicate : IndexRange(duplicates_range.size()).drop_front(1)) { const int i_dst_curve = duplicates_range[i_duplicate]; copy_hashed_ids( - curve_src, i_duplicate, dst.slice(dst_curves.range_for_curve(i_dst_curve))); + curve_src, i_duplicate, dst.slice(dst_curves.points_for_curve(i_dst_curve))); } } }); @@ -332,7 +327,7 @@ static void copy_stable_id_curves(const bke::CurvesGeometry &src_curves, static void duplicate_curves(GeometrySet &geometry_set, const Field<int> &count_field, const Field<bool> &selection_field, - const IndexAttributes &attributes) + const IndexAttributes &attribute_outputs) { if (!geometry_set.has_curves()) { geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES}); @@ -345,7 +340,7 @@ static void duplicate_curves(GeometrySet &geometry_set, const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); GeometryComponentFieldContext field_context{src_component, ATTR_DOMAIN_CURVE}; - FieldEvaluator evaluator{field_context, curves.curves_size()}; + FieldEvaluator evaluator{field_context, curves.curves_num()}; evaluator.add(count_field); evaluator.set_selection(selection_field); evaluator.evaluate(); @@ -363,7 +358,7 @@ static void duplicate_curves(GeometrySet &geometry_set, curve_offsets[i_curve] = dst_curves_size; point_offsets[i_curve] = dst_points_size; dst_curves_size += count; - dst_points_size += count * curves.range_for_curve(selection[i_curve]).size(); + dst_points_size += count * curves.points_for_curve(selection[i_curve]).size(); } curve_offsets.last() = dst_curves_size; point_offsets.last() = dst_points_size; @@ -375,7 +370,7 @@ static void duplicate_curves(GeometrySet &geometry_set, threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) { for (const int i_selection : range) { const int i_src_curve = selection[i_selection]; - const IndexRange src_curve_range = curves.range_for_curve(i_src_curve); + const IndexRange src_curve_range = curves.points_for_curve(i_src_curve); const IndexRange dst_curves_range = range_for_offsets_index(curve_offsets, i_selection); MutableSpan<int> dst_offsets = all_dst_offsets.slice(dst_curves_range); for (const int i_duplicate : IndexRange(dst_curves_range.size())) { @@ -395,9 +390,9 @@ static void duplicate_curves(GeometrySet &geometry_set, copy_stable_id_curves( curves, selection, curve_offsets, src_component, new_curves, dst_component); - if (attributes.duplicate_index) { + if (attribute_outputs.duplicate_index) { create_duplicate_index_attribute( - dst_component, ATTR_DOMAIN_CURVE, selection, attributes, curve_offsets); + dst_component, ATTR_DOMAIN_CURVE, selection, attribute_outputs, curve_offsets); } geometry_set.replace_curves(new_curves_id); @@ -421,11 +416,10 @@ static void copy_face_attributes_without_id(GeometrySet &geometry_set, const GeometryComponent &src_component, GeometryComponent &dst_component) { - Map<AttributeIDRef, AttributeKind> gathered_attributes; - gather_attributes_without_id( - geometry_set, GEO_COMPONENT_TYPE_MESH, {}, false, gathered_attributes); + Map<AttributeIDRef, AttributeKind> attributes = gather_attributes_without_id( + geometry_set, GEO_COMPONENT_TYPE_MESH, false); - for (const Map<AttributeIDRef, AttributeKind>::Item entry : gathered_attributes.items()) { + for (const Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) { const AttributeIDRef attribute_id = entry.key; ReadAttributeLookup src_attribute = src_component.attribute_try_get_for_read(attribute_id); if (!src_attribute) { @@ -521,7 +515,7 @@ static void copy_stable_id_faces(const Mesh &mesh, static void duplicate_faces(GeometrySet &geometry_set, const Field<int> &count_field, const Field<bool> &selection_field, - const IndexAttributes &attributes) + const IndexAttributes &attribute_outputs) { if (!geometry_set.has_mesh()) { geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES}); @@ -609,9 +603,9 @@ static void duplicate_faces(GeometrySet &geometry_set, copy_stable_id_faces(mesh, selection, offsets, vert_mapping, src_component, dst_component); - if (attributes.duplicate_index) { + if (attribute_outputs.duplicate_index) { create_duplicate_index_attribute( - dst_component, ATTR_DOMAIN_FACE, selection, attributes, offsets); + dst_component, ATTR_DOMAIN_FACE, selection, attribute_outputs, offsets); } geometry_set.replace_mesh(new_mesh); @@ -633,11 +627,10 @@ static void copy_edge_attributes_without_id(GeometrySet &geometry_set, const GeometryComponent &src_component, GeometryComponent &dst_component) { - Map<AttributeIDRef, AttributeKind> gathered_attributes; - gather_attributes_without_id( - geometry_set, GEO_COMPONENT_TYPE_MESH, {}, false, gathered_attributes); + Map<AttributeIDRef, AttributeKind> attributes = gather_attributes_without_id( + geometry_set, GEO_COMPONENT_TYPE_MESH, false); - for (const Map<AttributeIDRef, AttributeKind>::Item entry : gathered_attributes.items()) { + for (const Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) { const AttributeIDRef attribute_id = entry.key; ReadAttributeLookup src_attribute = src_component.attribute_try_get_for_read(attribute_id); if (!src_attribute) { @@ -719,7 +712,7 @@ static void copy_stable_id_edges(const Mesh &mesh, static void duplicate_edges(GeometrySet &geometry_set, const Field<int> &count_field, const Field<bool> &selection_field, - const IndexAttributes &attributes) + const IndexAttributes &attribute_outputs) { if (!geometry_set.has_mesh()) { geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES}); @@ -778,9 +771,9 @@ static void duplicate_edges(GeometrySet &geometry_set, copy_stable_id_edges(mesh, selection, edge_offsets, src_component, dst_component); - if (attributes.duplicate_index) { + if (attribute_outputs.duplicate_index) { create_duplicate_index_attribute( - dst_component, ATTR_DOMAIN_EDGE, selection, attributes, edge_offsets); + dst_component, ATTR_DOMAIN_EDGE, selection, attribute_outputs, edge_offsets); } geometry_set.replace_mesh(new_mesh); @@ -795,17 +788,17 @@ static void duplicate_edges(GeometrySet &geometry_set, static void duplicate_points_curve(GeometrySet &geometry_set, const Field<int> &count_field, const Field<bool> &selection_field, - const IndexAttributes &attributes) + const IndexAttributes &attribute_outputs) { const CurveComponent &src_component = *geometry_set.get_component_for_read<CurveComponent>(); const Curves &src_curves_id = *src_component.get_for_read(); const bke::CurvesGeometry &src_curves = bke::CurvesGeometry::wrap(src_curves_id.geometry); - if (src_curves.points_size() == 0) { + if (src_curves.points_num() == 0) { return; } GeometryComponentFieldContext field_context{src_component, ATTR_DOMAIN_POINT}; - FieldEvaluator evaluator{field_context, src_curves.points_size()}; + FieldEvaluator evaluator{field_context, src_curves.points_num()}; evaluator.add(count_field); evaluator.set_selection(selection_field); evaluator.evaluate(); @@ -815,10 +808,10 @@ static void duplicate_points_curve(GeometrySet &geometry_set, Array<int> offsets = accumulate_counts_to_offsets(selection, counts); const int dst_size = offsets.last(); - Array<int> point_to_curve_map(src_curves.points_size()); + Array<int> point_to_curve_map(src_curves.points_num()); threading::parallel_for(src_curves.curves_range(), 1024, [&](const IndexRange range) { for (const int i_curve : range) { - const IndexRange point_range = src_curves.range_for_curve(i_curve); + const IndexRange point_range = src_curves.points_for_curve(i_curve); point_to_curve_map.as_mutable_span().slice(point_range).fill(i_curve); } }); @@ -834,11 +827,10 @@ static void duplicate_points_curve(GeometrySet &geometry_set, CurveComponent dst_component; dst_component.replace(new_curves_id, GeometryOwnershipType::Editable); - Map<AttributeIDRef, AttributeKind> gathered_attributes; - gather_attributes_without_id( - geometry_set, GEO_COMPONENT_TYPE_CURVE, {}, false, gathered_attributes); + Map<AttributeIDRef, AttributeKind> attributes = gather_attributes_without_id( + geometry_set, GEO_COMPONENT_TYPE_CURVE, false); - for (const Map<AttributeIDRef, AttributeKind>::Item entry : gathered_attributes.items()) { + for (const Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) { const AttributeIDRef attribute_id = entry.key; ReadAttributeLookup src_attribute = src_component.attribute_try_get_for_read(attribute_id); if (!src_attribute) { @@ -881,9 +873,9 @@ static void duplicate_points_curve(GeometrySet &geometry_set, copy_stable_id_point(offsets, src_component, dst_component); - if (attributes.duplicate_index) { + if (attribute_outputs.duplicate_index) { create_duplicate_index_attribute( - dst_component, ATTR_DOMAIN_POINT, selection, attributes, offsets.as_span()); + dst_component, ATTR_DOMAIN_POINT, selection, attribute_outputs, offsets.as_span()); } geometry_set.replace_curves(new_curves_id); @@ -898,7 +890,7 @@ static void duplicate_points_curve(GeometrySet &geometry_set, static void duplicate_points_mesh(GeometrySet &geometry_set, const Field<int> &count_field, const Field<bool> &selection_field, - const IndexAttributes &attributes) + const IndexAttributes &attribute_outputs) { const MeshComponent &src_component = *geometry_set.get_component_for_read<MeshComponent>(); const Mesh &mesh = *geometry_set.get_mesh_for_read(); @@ -926,9 +918,9 @@ static void duplicate_points_mesh(GeometrySet &geometry_set, copy_stable_id_point(offsets, src_component, dst_component); - if (attributes.duplicate_index) { + if (attribute_outputs.duplicate_index) { create_duplicate_index_attribute( - dst_component, ATTR_DOMAIN_POINT, selection, attributes, offsets.as_span()); + dst_component, ATTR_DOMAIN_POINT, selection, attribute_outputs, offsets.as_span()); } geometry_set.replace_mesh(new_mesh); @@ -943,7 +935,7 @@ static void duplicate_points_mesh(GeometrySet &geometry_set, static void duplicate_points_pointcloud(GeometrySet &geometry_set, const Field<int> &count_field, const Field<bool> &selection_field, - const IndexAttributes &attributes) + const IndexAttributes &attribute_outputs) { const PointCloudComponent &src_points = *geometry_set.get_component_for_read<PointCloudComponent>(); @@ -968,9 +960,9 @@ static void duplicate_points_pointcloud(GeometrySet &geometry_set, copy_stable_id_point(offsets, src_points, dst_component); - if (attributes.duplicate_index) { + if (attribute_outputs.duplicate_index) { create_duplicate_index_attribute( - dst_component, ATTR_DOMAIN_POINT, selection, attributes, offsets); + dst_component, ATTR_DOMAIN_POINT, selection, attribute_outputs, offsets); } geometry_set.replace_pointcloud(pointcloud); } @@ -984,24 +976,25 @@ static void duplicate_points_pointcloud(GeometrySet &geometry_set, static void duplicate_points(GeometrySet &geometry_set, const Field<int> &count_field, const Field<bool> &selection_field, - const IndexAttributes &attributes) + const IndexAttributes &attribute_outputs) { Vector<GeometryComponentType> component_types = geometry_set.gather_component_types(true, true); for (const GeometryComponentType component_type : component_types) { switch (component_type) { case GEO_COMPONENT_TYPE_POINT_CLOUD: if (geometry_set.has_pointcloud()) { - duplicate_points_pointcloud(geometry_set, count_field, selection_field, attributes); + duplicate_points_pointcloud( + geometry_set, count_field, selection_field, attribute_outputs); } break; case GEO_COMPONENT_TYPE_MESH: if (geometry_set.has_mesh()) { - duplicate_points_mesh(geometry_set, count_field, selection_field, attributes); + duplicate_points_mesh(geometry_set, count_field, selection_field, attribute_outputs); } break; case GEO_COMPONENT_TYPE_CURVE: if (geometry_set.has_curves()) { - duplicate_points_curve(geometry_set, count_field, selection_field, attributes); + duplicate_points_curve(geometry_set, count_field, selection_field, attribute_outputs); } break; default: @@ -1021,7 +1014,7 @@ static void duplicate_points(GeometrySet &geometry_set, static void duplicate_instances(GeometrySet &geometry_set, const Field<int> &count_field, const Field<bool> &selection_field, - const IndexAttributes &attributes) + const IndexAttributes &attribute_outputs) { if (!geometry_set.has_instances()) { geometry_set.clear(); @@ -1064,9 +1057,9 @@ static void duplicate_instances(GeometrySet &geometry_set, copy_point_attributes_without_id( geometry_set, GEO_COMPONENT_TYPE_INSTANCES, true, offsets, src_instances, dst_instances); - if (attributes.duplicate_index) { + if (attribute_outputs.duplicate_index) { create_duplicate_index_attribute( - dst_instances, ATTR_DOMAIN_INSTANCE, selection, attributes, offsets); + dst_instances, ATTR_DOMAIN_INSTANCE, selection, attribute_outputs, offsets); } geometry_set = std::move(dst_geometry); @@ -1087,28 +1080,28 @@ static void node_geo_exec(GeoNodeExecParams params) Field<int> count_field = params.extract_input<Field<int>>("Amount"); Field<bool> selection_field = params.extract_input<Field<bool>>("Selection"); - IndexAttributes attributes; + IndexAttributes attribute_outputs; if (params.output_is_required("Duplicate Index")) { - attributes.duplicate_index = StrongAnonymousAttributeID("duplicate_index"); + attribute_outputs.duplicate_index = StrongAnonymousAttributeID("duplicate_index"); } if (duplicate_domain == ATTR_DOMAIN_INSTANCE) { - duplicate_instances(geometry_set, count_field, selection_field, attributes); + duplicate_instances(geometry_set, count_field, selection_field, attribute_outputs); } else { geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { switch (duplicate_domain) { case ATTR_DOMAIN_CURVE: - duplicate_curves(geometry_set, count_field, selection_field, attributes); + duplicate_curves(geometry_set, count_field, selection_field, attribute_outputs); break; case ATTR_DOMAIN_FACE: - duplicate_faces(geometry_set, count_field, selection_field, attributes); + duplicate_faces(geometry_set, count_field, selection_field, attribute_outputs); break; case ATTR_DOMAIN_EDGE: - duplicate_edges(geometry_set, count_field, selection_field, attributes); + duplicate_edges(geometry_set, count_field, selection_field, attribute_outputs); break; case ATTR_DOMAIN_POINT: - duplicate_points(geometry_set, count_field, selection_field, attributes); + duplicate_points(geometry_set, count_field, selection_field, attribute_outputs); break; default: BLI_assert_unreachable(); @@ -1122,10 +1115,10 @@ static void node_geo_exec(GeoNodeExecParams params) return; } - if (attributes.duplicate_index) { + if (attribute_outputs.duplicate_index) { params.set_output( "Duplicate Index", - AnonymousAttributeFieldInput::Create<int>(std::move(attributes.duplicate_index), + AnonymousAttributeFieldInput::Create<int>(std::move(attribute_outputs.duplicate_index), params.attribute_producer_name())); } params.set_output("Geometry", std::move(geometry_set)); diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc b/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc index 197cb6e6852..ab6f6b40d5e 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc @@ -86,13 +86,13 @@ static VArray<int> construct_spline_count_gvarray(const CurveComponent &componen const Curves &curves_id = *component.get_for_read(); const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); - auto count_fn = [curves](int64_t i) { return curves.range_for_curve(i).size(); }; + auto count_fn = [curves](int64_t i) { return curves.points_for_curve(i).size(); }; if (domain == ATTR_DOMAIN_CURVE) { - return VArray<int>::ForFunc(curves.curves_size(), count_fn); + return VArray<int>::ForFunc(curves.curves_num(), count_fn); } if (domain == ATTR_DOMAIN_POINT) { - VArray<int> count = VArray<int>::ForFunc(curves.curves_size(), count_fn); + VArray<int> count = VArray<int>::ForFunc(curves.curves_num(), count_fn); return component.attribute_try_adapt_domain<int>( std::move(count), ATTR_DOMAIN_CURVE, ATTR_DOMAIN_POINT); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_transform.cc b/source/blender/nodes/geometry/nodes/node_geo_transform.cc index a04544e2814..cc115ee3b3f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_transform.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_transform.cc @@ -103,8 +103,8 @@ static void transform_volume(Volume &volume, const float4x4 &transform, const De memcpy(vdb_matrix.asPointer(), &scale_limited_transform, sizeof(float[4][4])); openvdb::Mat4d vdb_matrix_d{vdb_matrix}; - const int num_grids = BKE_volume_num_grids(&volume); - for (const int i : IndexRange(num_grids)) { + const int grids_num = BKE_volume_num_grids(&volume); + for (const int i : IndexRange(grids_num)) { VolumeGrid *volume_grid = BKE_volume_grid_get_for_write(&volume, i); openvdb::GridBase::Ptr grid = BKE_volume_grid_openvdb_for_write(&volume, volume_grid, false); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_sky.cc b/source/blender/nodes/shader/nodes/node_shader_tex_sky.cc index a5ab6db0002..f5a4d087dbd 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_sky.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_sky.cc @@ -239,7 +239,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) return; } if (params.node_tree().typeinfo->validate_link( - static_cast<eNodeSocketDatatype>(params.other_socket().type), SOCK_FLOAT)) { + static_cast<eNodeSocketDatatype>(params.other_socket().type), SOCK_FLOAT)) { params.add_item(IFACE_("Vector"), [](LinkSearchOpParams ¶ms) { bNode &node = params.add_node("ShaderNodeTexSky"); NodeTexSky *tex = (NodeTexSky *)node.storage; diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c index 6492f528a5e..35d5cb6a994 100644 --- a/source/blender/python/bmesh/bmesh_py_ops_call.c +++ b/source/blender/python/bmesh/bmesh_py_ops_call.c @@ -233,8 +233,8 @@ static int bpy_slot_from_py(BMesh *bm, if (!Matrix_ParseAny(value, &pymat)) { return -1; } - const ushort size = pymat->num_col; - if ((size != pymat->num_row) || (!ELEM(size, 3, 4))) { + const ushort size = pymat->col_num; + if ((size != pymat->row_num) || (!ELEM(size, 3, 4))) { PyErr_Format(PyExc_TypeError, "%.200s: keyword \"%.200s\" expected a 3x3 or 4x4 matrix", opname, diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index 9ceff9b84b6..46f89dd4103 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -1309,7 +1309,7 @@ static PyObject *bpy_bmesh_transform(BPy_BMElem *self, PyObject *args, PyObject if (BaseMath_ReadCallback(mat) == -1) { return NULL; } - if (mat->num_col != 4 || mat->num_row != 4) { + if (mat->col_num != 4 || mat->row_num != 4) { PyErr_SetString(PyExc_ValueError, "expected a 4x4 matrix"); return NULL; } diff --git a/source/blender/python/generic/blf_py_api.c b/source/blender/python/generic/blf_py_api.c index 3fbfd1655c5..9e45105d105 100644 --- a/source/blender/python/generic/blf_py_api.c +++ b/source/blender/python/generic/blf_py_api.c @@ -396,41 +396,41 @@ static PyObject *py_blf_shadow_offset(PyObject *UNUSED(self), PyObject *args) } PyDoc_STRVAR(py_blf_load_doc, - ".. function:: load(filename)\n" + ".. function:: load(filepath)\n" "\n" " Load a new font.\n" "\n" - " :arg filename: the filename of the font.\n" - " :type filename: string\n" + " :arg filepath: the filepath of the font.\n" + " :type filepath: string\n" " :return: the new font's fontid or -1 if there was an error.\n" " :rtype: integer\n"); static PyObject *py_blf_load(PyObject *UNUSED(self), PyObject *args) { - const char *filename; + const char *filepath; - if (!PyArg_ParseTuple(args, "s:blf.load", &filename)) { + if (!PyArg_ParseTuple(args, "s:blf.load", &filepath)) { return NULL; } - return PyLong_FromLong(BLF_load(filename)); + return PyLong_FromLong(BLF_load(filepath)); } PyDoc_STRVAR(py_blf_unload_doc, - ".. function:: unload(filename)\n" + ".. function:: unload(filepath)\n" "\n" " Unload an existing font.\n" "\n" - " :arg filename: the filename of the font.\n" - " :type filename: string\n"); + " :arg filepath: the filepath of the font.\n" + " :type filepath: string\n"); static PyObject *py_blf_unload(PyObject *UNUSED(self), PyObject *args) { - const char *filename; + const char *filepath; - if (!PyArg_ParseTuple(args, "s:blf.unload", &filename)) { + if (!PyArg_ParseTuple(args, "s:blf.unload", &filepath)) { return NULL; } - BLF_unload(filename); + BLF_unload(filepath); Py_RETURN_NONE; } diff --git a/source/blender/python/gpu/gpu_py_shader.c b/source/blender/python/gpu/gpu_py_shader.c index 1a53ccd6686..43b26e05327 100644 --- a/source/blender/python/gpu/gpu_py_shader.c +++ b/source/blender/python/gpu/gpu_py_shader.c @@ -381,11 +381,11 @@ static PyObject *pygpu_shader_uniform_float(BPyGPUShader *self, PyObject *args) if (BaseMath_ReadCallback(mat) == -1) { return NULL; } - if ((mat->num_row != mat->num_col) || !ELEM(mat->num_row, 3, 4)) { + if ((mat->row_num != mat->col_num) || !ELEM(mat->row_num, 3, 4)) { PyErr_SetString(PyExc_ValueError, "Expected 3x3 or 4x4 matrix"); return NULL; } - length = mat->num_row * mat->num_col; + length = mat->row_num * mat->col_num; memcpy(values, mat->matrix, sizeof(float) * length); } else { diff --git a/source/blender/python/gpu/gpu_py_state.c b/source/blender/python/gpu/gpu_py_state.c index e3ffd3cc823..fb69bb316c4 100644 --- a/source/blender/python/gpu/gpu_py_state.c +++ b/source/blender/python/gpu/gpu_py_state.c @@ -347,7 +347,7 @@ static PyObject *pygpu_state_program_point_size_set(PyObject *UNUSED(self), PyOb PyDoc_STRVAR(pygpu_state_framebuffer_active_get_doc, ".. function:: framebuffer_active_get(enable)\n" "\n" - " Return the active framefuffer in context.\n"); + " Return the active frame-buffer in context.\n"); static PyObject *pygpu_state_framebuffer_active_get(PyObject *UNUSED(self)) { GPUFrameBuffer *fb = GPU_framebuffer_active_get(); diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt index a35f03f9872..f813a006c7e 100644 --- a/source/blender/python/intern/CMakeLists.txt +++ b/source/blender/python/intern/CMakeLists.txt @@ -224,6 +224,10 @@ if(WITH_IMAGE_TIFF) add_definitions(-DWITH_TIFF) endif() +if(WITH_WEBP) + add_definitions(-DWITH_WEBP) +endif() + if(WITH_INPUT_NDOF) add_definitions(-DWITH_INPUT_NDOF) endif() diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c index ba3e6a3d74b..34ffef03e66 100644 --- a/source/blender/python/intern/bpy_app_handlers.c +++ b/source/blender/python/intern/bpy_app_handlers.c @@ -24,7 +24,7 @@ void bpy_app_generic_callback(struct Main *main, struct PointerRNA **pointers, - const int num_pointers, + const int pointers_num, void *arg); static PyTypeObject BlenderAppCbType; @@ -305,7 +305,7 @@ static PyObject *choose_arguments(PyObject *func, PyObject *args_all, PyObject * /* the actual callback - not necessarily called from py */ void bpy_app_generic_callback(struct Main *UNUSED(main), struct PointerRNA **pointers, - const int num_pointers, + const int pointers_num, void *arg) { PyObject *cb_list = py_cb_array[POINTER_AS_INT(arg)]; @@ -320,14 +320,14 @@ void bpy_app_generic_callback(struct Main *UNUSED(main), Py_ssize_t pos; /* setup arguments */ - for (int i = 0; i < num_pointers; ++i) { + for (int i = 0; i < pointers_num; ++i) { PyTuple_SET_ITEM(args_all, i, pyrna_struct_CreatePyObject(pointers[i])); } - for (int i = num_pointers; i < num_arguments; ++i) { + for (int i = pointers_num; i < num_arguments; ++i) { PyTuple_SET_ITEM(args_all, i, Py_INCREF_RET(Py_None)); } - if (num_pointers == 0) { + if (pointers_num == 0) { PyTuple_SET_ITEM(args_single, 0, Py_INCREF_RET(Py_None)); } else { diff --git a/source/blender/python/intern/bpy_interface_run.c b/source/blender/python/intern/bpy_interface_run.c index 8db122470b8..9299bd196e2 100644 --- a/source/blender/python/intern/bpy_interface_run.c +++ b/source/blender/python/intern/bpy_interface_run.c @@ -35,22 +35,33 @@ /** \name Private Utilities * \{ */ -static void python_script_error_jump_text(Text *text) +static void python_script_error_jump_text(Text *text, const char *filepath) { - int lineno; - int offset; - python_script_error_jump(text->id.name + 2, &lineno, &offset); - if (lineno != -1) { - /* select the line with the error */ - txt_move_to(text, lineno - 1, INT_MAX, false); + int lineno, lineno_end; + int offset, offset_end; + if (python_script_error_jump(filepath, &lineno, &offset, &lineno_end, &offset_end)) { + /* Start at the end so cursor motion that looses the selection, + * leaves the cursor from the most useful place. + * Also, the end can't always be set, so don't give it priority. */ + txt_move_to(text, lineno_end - 1, offset_end, false); txt_move_to(text, lineno - 1, offset, true); } } -/* returns a dummy filename for a textblock so we can tell what file a text block comes from */ -static void bpy_text_filename_get(char *fn, const Main *bmain, size_t fn_len, const Text *text) +/** + * Generate a `filepath` from a text-block so we can tell what file a text block comes from. + */ +static void bpy_text_filepath_get(char *filepath, + const size_t filepath_maxlen, + const Main *bmain, + const Text *text) { - BLI_snprintf(fn, fn_len, "%s%c%s", ID_BLEND_PATH(bmain, &text->id), SEP, text->id.name + 2); + BLI_snprintf(filepath, + filepath_maxlen, + "%s%c%s", + ID_BLEND_PATH(bmain, &text->id), + SEP, + text->id.name + 2); } /* Very annoying! Undo #_PyModule_Clear(), see T23871. */ @@ -74,17 +85,24 @@ typedef struct { * * \note Share a function for this since setup/cleanup logic is the same. */ -static bool python_script_exec( - bContext *C, const char *fn, struct Text *text, struct ReportList *reports, const bool do_jump) +static bool python_script_exec(bContext *C, + const char *filepath, + struct Text *text, + struct ReportList *reports, + const bool do_jump) { Main *bmain_old = CTX_data_main(C); PyObject *main_mod = NULL; PyObject *py_dict = NULL, *py_result = NULL; PyGILState_STATE gilstate; - BLI_assert(fn || text); + char filepath_dummy[FILE_MAX]; + /** The `__file__` added into the name-space. */ + const char *filepath_namespace = NULL; + + BLI_assert(filepath || text); - if (fn == NULL && text == NULL) { + if (filepath == NULL && text == NULL) { return 0; } @@ -93,40 +111,41 @@ static bool python_script_exec( PyC_MainModule_Backup(&main_mod); if (text) { - char fn_dummy[FILE_MAXDIR]; - bpy_text_filename_get(fn_dummy, bmain_old, sizeof(fn_dummy), text); + bpy_text_filepath_get(filepath_dummy, sizeof(filepath_dummy), bmain_old, text); + filepath_namespace = filepath_dummy; if (text->compiled == NULL) { /* if it wasn't already compiled, do it now */ char *buf; - PyObject *fn_dummy_py; + PyObject *filepath_dummy_py; - fn_dummy_py = PyC_UnicodeFromByte(fn_dummy); + filepath_dummy_py = PyC_UnicodeFromByte(filepath_dummy); size_t buf_len_dummy; buf = txt_to_buf(text, &buf_len_dummy); - text->compiled = Py_CompileStringObject(buf, fn_dummy_py, Py_file_input, NULL, -1); + text->compiled = Py_CompileStringObject(buf, filepath_dummy_py, Py_file_input, NULL, -1); MEM_freeN(buf); - Py_DECREF(fn_dummy_py); + Py_DECREF(filepath_dummy_py); if (PyErr_Occurred()) { if (do_jump) { - python_script_error_jump_text(text); + python_script_error_jump_text(text, filepath_dummy); } BPY_text_free_code(text); } } if (text->compiled) { - py_dict = PyC_DefaultNameSpace(fn_dummy); + py_dict = PyC_DefaultNameSpace(filepath_dummy); py_result = PyEval_EvalCode(text->compiled, py_dict, py_dict); } } else { - FILE *fp = BLI_fopen(fn, "r"); + FILE *fp = BLI_fopen(filepath, "r"); + filepath_namespace = filepath; if (fp) { - py_dict = PyC_DefaultNameSpace(fn); + py_dict = PyC_DefaultNameSpace(filepath); #ifdef _WIN32 /* Previously we used PyRun_File to run directly the code on a FILE @@ -153,13 +172,13 @@ static bool python_script_exec( py_result = PyRun_String(pystring, Py_file_input, py_dict, py_dict); } #else - py_result = PyRun_File(fp, fn, Py_file_input, py_dict, py_dict); + py_result = PyRun_File(fp, filepath, Py_file_input, py_dict, py_dict); fclose(fp); #endif } else { PyErr_Format( - PyExc_IOError, "Python file \"%s\" could not be opened: %s", fn, strerror(errno)); + PyExc_IOError, "Python file \"%s\" could not be opened: %s", filepath, strerror(errno)); py_result = NULL; } } @@ -170,7 +189,7 @@ static bool python_script_exec( /* ensure text is valid before use, the script may have freed itself */ Main *bmain_new = CTX_data_main(C); if ((bmain_old == bmain_new) && (BLI_findindex(&bmain_new->texts, text) != -1)) { - python_script_error_jump_text(text); + python_script_error_jump_text(text, filepath_namespace); } } } diff --git a/source/blender/python/intern/bpy_rna_array.c b/source/blender/python/intern/bpy_rna_array.c index f5bec247250..8506ec97bc3 100644 --- a/source/blender/python/intern/bpy_rna_array.c +++ b/source/blender/python/intern/bpy_rna_array.c @@ -377,15 +377,15 @@ static int validate_array(PyObject *rvalue, totdim); return -1; } - if (pymat->num_col != dimsize[0] || pymat->num_row != dimsize[1]) { + if (pymat->col_num != dimsize[0] || pymat->row_num != dimsize[1]) { PyErr_Format(PyExc_ValueError, "%s %.200s.%.200s, matrix assign dimension size mismatch, " "is %dx%d, expected be %dx%d", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), - pymat->num_col, - pymat->num_row, + pymat->col_num, + pymat->row_num, dimsize[0], dimsize[1]); return -1; @@ -473,7 +473,7 @@ static char *copy_values(PyObject *seq, if (dim == 0) { if (MatrixObject_Check(seq)) { MatrixObject *pymat = (MatrixObject *)seq; - const size_t allocsize = pymat->num_col * pymat->num_row * sizeof(float); + const size_t allocsize = pymat->col_num * pymat->row_num * sizeof(float); /* read callback already done by validate */ /* since this is the first iteration we can assume data is allocated */ diff --git a/source/blender/python/intern/bpy_traceback.c b/source/blender/python/intern/bpy_traceback.c index 13af254c286..40478f3613c 100644 --- a/source/blender/python/intern/bpy_traceback.c +++ b/source/blender/python/intern/bpy_traceback.c @@ -24,7 +24,7 @@ static const char *traceback_filepath(PyTracebackObject *tb, PyObject **coerce) return PyBytes_AS_STRING(*coerce); } -/* copied from pythonrun.c, 3.4.0 */ +/* copied from pythonrun.c, 3.10.0 */ _Py_static_string(PyId_string, "<string>"); static int parse_syntax_error(PyObject *err, @@ -32,14 +32,18 @@ static int parse_syntax_error(PyObject *err, PyObject **filename, int *lineno, int *offset, + int *end_lineno, + int *end_offset, PyObject **text) { - long hold; + Py_ssize_t hold; PyObject *v; _Py_IDENTIFIER(msg); _Py_IDENTIFIER(filename); _Py_IDENTIFIER(lineno); _Py_IDENTIFIER(offset); + _Py_IDENTIFIER(end_lineno); + _Py_IDENTIFIER(end_offset); _Py_IDENTIFIER(text); *message = NULL; @@ -71,7 +75,7 @@ static int parse_syntax_error(PyObject *err, if (!v) { goto finally; } - hold = PyLong_AsLong(v); + hold = PyLong_AsSsize_t(v); Py_DECREF(v); if (hold < 0 && PyErr_Occurred()) { goto finally; @@ -87,7 +91,7 @@ static int parse_syntax_error(PyObject *err, Py_DECREF(v); } else { - hold = PyLong_AsLong(v); + hold = PyLong_AsSsize_t(v); Py_DECREF(v); if (hold < 0 && PyErr_Occurred()) { goto finally; @@ -95,6 +99,49 @@ static int parse_syntax_error(PyObject *err, *offset = (int)hold; } + if (Py_TYPE(err) == (PyTypeObject *)PyExc_SyntaxError) { + v = _PyObject_GetAttrId(err, &PyId_end_lineno); + if (!v) { + PyErr_Clear(); + *end_lineno = *lineno; + } + else if (v == Py_None) { + *end_lineno = *lineno; + Py_DECREF(v); + } + else { + hold = PyLong_AsSsize_t(v); + Py_DECREF(v); + if (hold < 0 && PyErr_Occurred()) { + goto finally; + } + *end_lineno = hold; + } + + v = _PyObject_GetAttrId(err, &PyId_end_offset); + if (!v) { + PyErr_Clear(); + *end_offset = -1; + } + else if (v == Py_None) { + *end_offset = -1; + Py_DECREF(v); + } + else { + hold = PyLong_AsSsize_t(v); + Py_DECREF(v); + if (hold < 0 && PyErr_Occurred()) { + goto finally; + } + *end_offset = hold; + } + } + else { + /* `SyntaxError` subclasses. */ + *end_lineno = *lineno; + *end_offset = -1; + } + v = _PyObject_GetAttrId(err, &PyId_text); if (!v) { goto finally; @@ -115,39 +162,48 @@ finally: } /* end copied function! */ -void python_script_error_jump(const char *filepath, int *lineno, int *offset) +bool python_script_error_jump( + const char *filepath, int *r_lineno, int *r_offset, int *r_lineno_end, int *r_offset_end) { + bool success = false; PyObject *exception, *value; PyTracebackObject *tb; - *lineno = -1; - *offset = 0; + *r_lineno = -1; + *r_offset = 0; + + *r_lineno_end = -1; + *r_offset_end = 0; PyErr_Fetch(&exception, &value, (PyObject **)&tb); + if (exception == NULL) { + return false; + } - if (exception && PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError)) { - /* no trace-back available when `SyntaxError`. - * python has no API's to this. reference #parse_syntax_error() from pythonrun.c */ + if (PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError)) { + /* No trace-back available when `SyntaxError`. + * Python has no API's to this. reference #parse_syntax_error() from `pythonrun.c`. */ PyErr_NormalizeException(&exception, &value, (PyObject **)&tb); - if (value) { /* should always be true */ + if (value) { /* Should always be true. */ PyObject *message; - PyObject *filename_py, *text_py; - - if (parse_syntax_error(value, &message, &filename_py, lineno, offset, &text_py)) { - const char *filename = PyUnicode_AsUTF8(filename_py); + PyObject *filepath_exc_py, *text_py; + + if (parse_syntax_error(value, + &message, + &filepath_exc_py, + r_lineno, + r_offset, + r_lineno_end, + r_offset_end, + &text_py)) { + const char *filepath_exc = PyUnicode_AsUTF8(filepath_exc_py); /* python adds a '/', prefix, so check for both */ - if ((BLI_path_cmp(filename, filepath) == 0) || - (ELEM(filename[0], '\\', '/') && BLI_path_cmp(filename + 1, filepath) == 0)) { - /* good */ - } - else { - *lineno = -1; + if ((BLI_path_cmp(filepath_exc, filepath) == 0) || + (ELEM(filepath_exc[0], '\\', '/') && BLI_path_cmp(filepath_exc + 1, filepath) == 0)) { + success = true; } } - else { - *lineno = -1; - } } PyErr_Restore(exception, value, (PyObject *)tb); /* takes away reference! */ } @@ -167,9 +223,12 @@ void python_script_error_jump(const char *filepath, int *lineno, int *offset) Py_DECREF(coerce); if (match) { - *lineno = tb->tb_lineno; + success = true; + *r_lineno = *r_lineno_end = tb->tb_lineno; /* used to break here, but better find the inner most line */ } } } + + return success; } diff --git a/source/blender/python/intern/bpy_traceback.h b/source/blender/python/intern/bpy_traceback.h index 99e032f3594..f5232eca864 100644 --- a/source/blender/python/intern/bpy_traceback.h +++ b/source/blender/python/intern/bpy_traceback.h @@ -10,7 +10,8 @@ extern "C" { #endif -void python_script_error_jump(const char *filepath, int *lineno, int *offset); +bool python_script_error_jump( + const char *filepath, int *r_lineno, int *r_offset, int *r_lineno_end, int *r_offset_end); #ifdef __cplusplus } diff --git a/source/blender/python/mathutils/mathutils.c b/source/blender/python/mathutils/mathutils.c index 8ed156a7e55..1aa2cec861c 100644 --- a/source/blender/python/mathutils/mathutils.c +++ b/source/blender/python/mathutils/mathutils.c @@ -92,47 +92,46 @@ Py_hash_t mathutils_array_hash(const float *array, size_t array_len) } int mathutils_array_parse( - float *array, int array_min, int array_max, PyObject *value, const char *error_prefix) + float *array, int array_num_min, int array_num_max, PyObject *value, const char *error_prefix) { - const uint flag = array_max; - int size; + const uint flag = array_num_max; + int num; - array_max &= ~MU_ARRAY_FLAGS; + array_num_max &= ~MU_ARRAY_FLAGS; #if 1 /* approx 6x speedup for mathutils types */ - if ((size = VectorObject_Check(value) ? ((VectorObject *)value)->size : 0) || - (size = EulerObject_Check(value) ? 3 : 0) || - (size = QuaternionObject_Check(value) ? 4 : 0) || - (size = ColorObject_Check(value) ? 3 : 0)) { + if ((num = VectorObject_Check(value) ? ((VectorObject *)value)->vec_num : 0) || + (num = EulerObject_Check(value) ? 3 : 0) || (num = QuaternionObject_Check(value) ? 4 : 0) || + (num = ColorObject_Check(value) ? 3 : 0)) { if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) { return -1; } if (flag & MU_ARRAY_SPILL) { - CLAMP_MAX(size, array_max); + CLAMP_MAX(num, array_num_max); } - if (size > array_max || size < array_min) { - if (array_max == array_min) { + if (num > array_num_max || num < array_num_min) { + if (array_num_max == array_num_min) { PyErr_Format(PyExc_ValueError, - "%.200s: sequence size is %d, expected %d", + "%.200s: sequence length is %d, expected %d", error_prefix, - size, - array_max); + num, + array_num_max); } else { PyErr_Format(PyExc_ValueError, - "%.200s: sequence size is %d, expected [%d - %d]", + "%.200s: sequence length is %d, expected [%d - %d]", error_prefix, - size, - array_min, - array_max); + num, + array_num_min, + array_num_max); } return -1; } - memcpy(array, ((const BaseMathObject *)value)->data, size * sizeof(float)); + memcpy(array, ((const BaseMathObject *)value)->data, num * sizeof(float)); } else #endif @@ -145,77 +144,76 @@ int mathutils_array_parse( return -1; } - size = PySequence_Fast_GET_SIZE(value_fast); + num = PySequence_Fast_GET_SIZE(value_fast); if (flag & MU_ARRAY_SPILL) { - CLAMP_MAX(size, array_max); + CLAMP_MAX(num, array_num_max); } - if (size > array_max || size < array_min) { - if (array_max == array_min) { + if (num > array_num_max || num < array_num_min) { + if (array_num_max == array_num_min) { PyErr_Format(PyExc_ValueError, - "%.200s: sequence size is %d, expected %d", + "%.200s: sequence length is %d, expected %d", error_prefix, - size, - array_max); + num, + array_num_max); } else { PyErr_Format(PyExc_ValueError, - "%.200s: sequence size is %d, expected [%d - %d]", + "%.200s: sequence length is %d, expected [%d - %d]", error_prefix, - size, - array_min, - array_max); + num, + array_num_min, + array_num_max); } Py_DECREF(value_fast); return -1; } - size = mathutils_array_parse_fast(array, size, value_fast, error_prefix); + num = mathutils_array_parse_fast(array, num, value_fast, error_prefix); Py_DECREF(value_fast); } - if (size != -1) { + if (num != -1) { if (flag & MU_ARRAY_ZERO) { - const int size_left = array_max - size; - if (size_left) { - memset(&array[size], 0, sizeof(float) * size_left); + const int array_num_left = array_num_max - num; + if (array_num_left) { + memset(&array[num], 0, sizeof(float) * array_num_left); } } } - return size; + return num; } int mathutils_array_parse_alloc(float **array, - int array_min, + int array_num, PyObject *value, const char *error_prefix) { - int size; + int num; #if 1 /* approx 6x speedup for mathutils types */ - if ((size = VectorObject_Check(value) ? ((VectorObject *)value)->size : 0) || - (size = EulerObject_Check(value) ? 3 : 0) || - (size = QuaternionObject_Check(value) ? 4 : 0) || - (size = ColorObject_Check(value) ? 3 : 0)) { + if ((num = VectorObject_Check(value) ? ((VectorObject *)value)->vec_num : 0) || + (num = EulerObject_Check(value) ? 3 : 0) || (num = QuaternionObject_Check(value) ? 4 : 0) || + (num = ColorObject_Check(value) ? 3 : 0)) { if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) { return -1; } - if (size < array_min) { + if (num < array_num) { PyErr_Format(PyExc_ValueError, "%.200s: sequence size is %d, expected > %d", error_prefix, - size, - array_min); + num, + array_num); return -1; } - *array = PyMem_Malloc(size * sizeof(float)); - memcpy(*array, ((const BaseMathObject *)value)->data, size * sizeof(float)); - return size; + *array = PyMem_Malloc(num * sizeof(float)); + memcpy(*array, ((const BaseMathObject *)value)->data, num * sizeof(float)); + return num; } #endif @@ -230,21 +228,21 @@ int mathutils_array_parse_alloc(float **array, return -1; } - size = PySequence_Fast_GET_SIZE(value_fast); + num = PySequence_Fast_GET_SIZE(value_fast); - if (size < array_min) { + if (num < array_num) { Py_DECREF(value_fast); PyErr_Format(PyExc_ValueError, "%.200s: sequence size is %d, expected > %d", error_prefix, - size, - array_min); + num, + array_num); return -1; } - *array = PyMem_Malloc(size * sizeof(float)); + *array = PyMem_Malloc(num * sizeof(float)); - ret = mathutils_array_parse_fast(*array, size, value_fast, error_prefix); + ret = mathutils_array_parse_fast(*array, num, value_fast, error_prefix); Py_DECREF(value_fast); if (ret == -1) { @@ -261,7 +259,7 @@ int mathutils_array_parse_alloc_v(float **array, { PyObject *value_fast; const int array_dim_flag = array_dim; - int i, size; + int i, num; /* non list/tuple cases */ if (!(value_fast = PySequence_Fast(value, error_prefix))) { @@ -269,30 +267,30 @@ int mathutils_array_parse_alloc_v(float **array, return -1; } - size = PySequence_Fast_GET_SIZE(value_fast); + num = PySequence_Fast_GET_SIZE(value_fast); - if (size != 0) { + if (num != 0) { PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast); float *fp; array_dim &= ~MU_ARRAY_FLAGS; - fp = *array = PyMem_Malloc(size * array_dim * sizeof(float)); + fp = *array = PyMem_Malloc(num * array_dim * sizeof(float)); - for (i = 0; i < size; i++, fp += array_dim) { + for (i = 0; i < num; i++, fp += array_dim) { PyObject *item = value_fast_items[i]; if (mathutils_array_parse(fp, array_dim, array_dim_flag, item, error_prefix) == -1) { PyMem_Free(*array); *array = NULL; - size = -1; + num = -1; break; } } } Py_DECREF(value_fast); - return size; + return num; } int mathutils_int_array_parse(int *array, int array_dim, PyObject *value, const char *error_prefix) @@ -458,7 +456,7 @@ int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) { return -1; } - if (((MatrixObject *)value)->num_row < 3 || ((MatrixObject *)value)->num_col < 3) { + if (((MatrixObject *)value)->row_num < 3 || ((MatrixObject *)value)->col_num < 3) { PyErr_Format( PyExc_ValueError, "%.200s: matrix must have minimum 3x3 dimensions", error_prefix); return -1; diff --git a/source/blender/python/mathutils/mathutils.h b/source/blender/python/mathutils/mathutils.h index 5831489ef5b..84386e99d18 100644 --- a/source/blender/python/mathutils/mathutils.h +++ b/source/blender/python/mathutils/mathutils.h @@ -153,12 +153,12 @@ void _BaseMathObject_RaiseNotFrozenExc(const BaseMathObject *self); * \return length of `value`, -1 on error. */ int mathutils_array_parse( - float *array, int array_min, int array_max, PyObject *value, const char *error_prefix); + float *array, int array_num_min, int array_num_max, PyObject *value, const char *error_prefix); /** * \return -1 is returned on error and no allocation is made. */ int mathutils_array_parse_alloc(float **array, - int array_min, + int array_num_min, PyObject *value, const char *error_prefix); /** diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c index b8eaf1486ab..76b5424711f 100644 --- a/source/blender/python/mathutils/mathutils_Matrix.c +++ b/source/blender/python/mathutils/mathutils_Matrix.c @@ -34,7 +34,7 @@ static PyObject *MatrixAccess_CreatePyObject(MatrixObject *matrix, const eMatrix static int matrix_row_vector_check(MatrixObject *mat, VectorObject *vec, int row) { - if ((vec->size != mat->num_col) || (row >= mat->num_row)) { + if ((vec->vec_num != mat->col_num) || (row >= mat->row_num)) { PyErr_SetString(PyExc_AttributeError, "Matrix(): " "owner matrix has been resized since this row vector was created"); @@ -46,7 +46,7 @@ static int matrix_row_vector_check(MatrixObject *mat, VectorObject *vec, int row static int matrix_col_vector_check(MatrixObject *mat, VectorObject *vec, int col) { - if ((vec->size != mat->num_row) || (col >= mat->num_col)) { + if ((vec->vec_num != mat->row_num) || (col >= mat->col_num)) { PyErr_SetString(PyExc_AttributeError, "Matrix(): " "owner matrix has been resized since this column vector was created"); @@ -80,7 +80,7 @@ static int mathutils_matrix_row_get(BaseMathObject *bmo, int row) return -1; } - for (col = 0; col < self->num_col; col++) { + for (col = 0; col < self->col_num; col++) { bmo->data[col] = MATRIX_ITEM(self, row, col); } @@ -99,7 +99,7 @@ static int mathutils_matrix_row_set(BaseMathObject *bmo, int row) return -1; } - for (col = 0; col < self->num_col; col++) { + for (col = 0; col < self->col_num; col++) { MATRIX_ITEM(self, row, col) = bmo->data[col]; } @@ -162,7 +162,7 @@ static int mathutils_matrix_col_check(BaseMathObject *bmo) static int mathutils_matrix_col_get(BaseMathObject *bmo, int col) { MatrixObject *self = (MatrixObject *)bmo->cb_user; - int num_row; + int row_num; int row; if (BaseMath_ReadCallback(self) == -1) { @@ -172,10 +172,10 @@ static int mathutils_matrix_col_get(BaseMathObject *bmo, int col) return -1; } - /* for 'translation' size will always be '3' even on 4x4 vec */ - num_row = min_ii(self->num_row, ((const VectorObject *)bmo)->size); + /* for 'translation' `vec_num` will always be '3' even on 4x4 vec */ + row_num = min_ii(self->row_num, ((const VectorObject *)bmo)->vec_num); - for (row = 0; row < num_row; row++) { + for (row = 0; row < row_num; row++) { bmo->data[row] = MATRIX_ITEM(self, row, col); } @@ -185,7 +185,7 @@ static int mathutils_matrix_col_get(BaseMathObject *bmo, int col) static int mathutils_matrix_col_set(BaseMathObject *bmo, int col) { MatrixObject *self = (MatrixObject *)bmo->cb_user; - int num_row; + int row_num; int row; if (BaseMath_ReadCallback_ForWrite(self) == -1) { @@ -195,10 +195,10 @@ static int mathutils_matrix_col_set(BaseMathObject *bmo, int col) return -1; } - /* for 'translation' size will always be '3' even on 4x4 vec */ - num_row = min_ii(self->num_row, ((const VectorObject *)bmo)->size); + /* for 'translation' `vec_num` will always be '3' even on 4x4 vec */ + row_num = min_ii(self->row_num, ((const VectorObject *)bmo)->vec_num); - for (row = 0; row < num_row; row++) { + for (row = 0; row < row_num; row++) { MATRIX_ITEM(self, row, col) = bmo->data[row]; } @@ -349,18 +349,18 @@ static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds) /* Input is now as a sequence of rows so length of sequence * is the number of rows */ /* -1 is an error, size checks will account for this */ - const ushort num_row = PySequence_Size(arg); + const ushort row_num = PySequence_Size(arg); - if (num_row >= 2 && num_row <= 4) { + if (row_num >= 2 && row_num <= 4) { PyObject *item = PySequence_GetItem(arg, 0); /* Since each item is a row, number of items is the * same as the number of columns */ - const ushort num_col = PySequence_Size(item); + const ushort col_num = PySequence_Size(item); Py_XDECREF(item); - if (num_col >= 2 && num_col <= 4) { + if (col_num >= 2 && col_num <= 4) { /* Sane row & col size, new matrix and assign as slice. */ - PyObject *matrix = Matrix_CreatePyObject(NULL, num_col, num_row, type); + PyObject *matrix = Matrix_CreatePyObject(NULL, col_num, row_num, type); if (Matrix_ass_slice((MatrixObject *)matrix, 0, INT_MAX, arg) == 0) { return matrix; } @@ -613,7 +613,7 @@ PyDoc_STRVAR(C_Matrix_Scale_doc, static PyObject *C_Matrix_Scale(PyObject *cls, PyObject *args) { PyObject *vec = NULL; - int vec_size; + int vec_num; float tvec[3]; float factor; int matSize; @@ -646,12 +646,10 @@ static PyObject *C_Matrix_Scale(PyObject *cls, PyObject *args) return NULL; } if (vec) { - vec_size = (matSize == 2 ? 2 : 3); - if (mathutils_array_parse(tvec, - vec_size, - vec_size, - vec, - "Matrix.Scale(factor, size, axis), invalid 'axis' arg") == -1) { + vec_num = (matSize == 2 ? 2 : 3); + if (mathutils_array_parse( + tvec, vec_num, vec_num, vec, "Matrix.Scale(factor, size, axis), invalid 'axis' arg") == + -1) { return NULL; } } @@ -671,11 +669,11 @@ static PyObject *C_Matrix_Scale(PyObject *cls, PyObject *args) * normalize arbitrary axis */ float norm = 0.0f; int x; - for (x = 0; x < vec_size; x++) { + for (x = 0; x < vec_num; x++) { norm += tvec[x] * tvec[x]; } norm = sqrtf(norm); - for (x = 0; x < vec_size; x++) { + for (x = 0; x < vec_num; x++) { tvec[x] /= norm; } if (matSize == 2) { @@ -795,23 +793,23 @@ static PyObject *C_Matrix_OrthoProjection(PyObject *cls, PyObject *args) else { /* arbitrary plane */ - const int vec_size = (matSize == 2 ? 2 : 3); + const int vec_num = (matSize == 2 ? 2 : 3); float tvec[4]; if (mathutils_array_parse(tvec, - vec_size, - vec_size, + vec_num, + vec_num, axis, "Matrix.OrthoProjection(axis, size), invalid 'axis' arg") == -1) { return NULL; } /* normalize arbitrary axis */ - for (x = 0; x < vec_size; x++) { + for (x = 0; x < vec_num; x++) { norm += tvec[x] * tvec[x]; } norm = sqrtf(norm); - for (x = 0; x < vec_size; x++) { + for (x = 0; x < vec_num; x++) { tvec[x] /= norm; } if (matSize == 2) { @@ -1019,7 +1017,7 @@ static PyObject *C_Matrix_LocRotScale(PyObject *cls, PyObject *args) return NULL; } - if (mat_obj->num_col == 3 && mat_obj->num_row == 3) { + if (mat_obj->col_num == 3 && mat_obj->row_num == 3) { copy_m4_m3(mat, (const float(*)[3])mat_obj->matrix); } else { @@ -1062,20 +1060,20 @@ void matrix_as_3x3(float mat[3][3], MatrixObject *self) static void matrix_copy(MatrixObject *mat_dst, const MatrixObject *mat_src) { - BLI_assert((mat_dst->num_col == mat_src->num_col) && (mat_dst->num_row == mat_src->num_row)); + BLI_assert((mat_dst->col_num == mat_src->col_num) && (mat_dst->row_num == mat_src->row_num)); BLI_assert(mat_dst != mat_src); - memcpy(mat_dst->matrix, mat_src->matrix, sizeof(float) * (mat_dst->num_col * mat_dst->num_row)); + memcpy(mat_dst->matrix, mat_src->matrix, sizeof(float) * (mat_dst->col_num * mat_dst->row_num)); } static void matrix_unit_internal(MatrixObject *self) { - const int mat_size = sizeof(float) * (self->num_col * self->num_row); + const int mat_size = sizeof(float) * (self->col_num * self->row_num); memset(self->matrix, 0x0, mat_size); - const int col_row_max = min_ii(self->num_col, self->num_row); - const int num_row = self->num_row; + const int col_row_max = min_ii(self->col_num, self->row_num); + const int row_num = self->row_num; for (int col = 0; col < col_row_max; col++) { - self->matrix[(col * num_row) + col] = 1.0f; + self->matrix[(col * row_num) + col] = 1.0f; } } @@ -1085,8 +1083,8 @@ static void matrix_transpose_internal(float mat_dst_fl[], const MatrixObject *ma ushort col, row; uint i = 0; - for (row = 0; row < mat_src->num_row; row++) { - for (col = 0; col < mat_src->num_col; col++) { + for (row = 0; row < mat_src->row_num; row++) { + for (col = 0; col < mat_src->col_num; col++) { mat_dst_fl[i++] = MATRIX_ITEM(mat_src, row, col); } } @@ -1095,13 +1093,13 @@ static void matrix_transpose_internal(float mat_dst_fl[], const MatrixObject *ma /* assumes rowsize == colsize is checked and the read callback has run */ static float matrix_determinant_internal(const MatrixObject *self) { - if (self->num_col == 2) { + if (self->col_num == 2) { return determinant_m2(MATRIX_ITEM(self, 0, 0), MATRIX_ITEM(self, 0, 1), MATRIX_ITEM(self, 1, 0), MATRIX_ITEM(self, 1, 1)); } - if (self->num_col == 3) { + if (self->col_num == 3) { return determinant_m3(MATRIX_ITEM(self, 0, 0), MATRIX_ITEM(self, 0, 1), MATRIX_ITEM(self, 0, 2), @@ -1152,8 +1150,8 @@ static void matrix_invert_with_det_n_internal(float *mat_dst, /* divide by determinant & set values */ k = 0; - for (i = 0; i < dim; i++) { /* num_col */ - for (j = 0; j < dim; j++) { /* num_row */ + for (i = 0; i < dim; i++) { /* col_num */ + for (j = 0; j < dim; j++) { /* row_num */ mat_dst[MATRIX_ITEM_INDEX_NUMROW(dim, j, i)] = mat[k++] / det; } } @@ -1165,11 +1163,11 @@ static void matrix_invert_with_det_n_internal(float *mat_dst, static bool matrix_invert_internal(const MatrixObject *self, float *r_mat) { float det; - BLI_assert(self->num_col == self->num_row); + BLI_assert(self->col_num == self->row_num); det = matrix_determinant_internal(self); if (det != 0.0f) { - matrix_invert_with_det_n_internal(r_mat, self->matrix, det, self->num_col); + matrix_invert_with_det_n_internal(r_mat, self->matrix, det, self->col_num); return true; } @@ -1184,7 +1182,7 @@ static void matrix_invert_safe_internal(const MatrixObject *self, float *r_mat) { float det; float *in_mat = self->matrix; - BLI_assert(self->num_col == self->num_row); + BLI_assert(self->col_num == self->row_num); det = matrix_determinant_internal(self); if (det == 0.0f) { @@ -1194,7 +1192,7 @@ static void matrix_invert_safe_internal(const MatrixObject *self, float *r_mat) * and modify it in place to add diagonal epsilon. */ in_mat = r_mat; - switch (self->num_col) { + switch (self->col_num) { case 2: { float(*mat)[2] = (float(*)[2])in_mat; @@ -1248,7 +1246,7 @@ static void matrix_invert_safe_internal(const MatrixObject *self, float *r_mat) } } - matrix_invert_with_det_n_internal(r_mat, in_mat, det, self->num_col); + matrix_invert_with_det_n_internal(r_mat, in_mat, det, self->col_num); } /*-----------------------------METHODS----------------------------*/ @@ -1268,13 +1266,13 @@ static PyObject *Matrix_to_quaternion(MatrixObject *self) } /* must be 3-4 cols, 3-4 rows, square matrix */ - if ((self->num_row < 3) || (self->num_col < 3) || (self->num_row != self->num_col)) { + if ((self->row_num < 3) || (self->col_num < 3) || (self->row_num != self->col_num)) { PyErr_SetString(PyExc_ValueError, "Matrix.to_quat(): " "inappropriate matrix size - expects 3x3 or 4x4 matrix"); return NULL; } - if (self->num_row == 3) { + if (self->row_num == 3) { mat3_to_quat(quat, (float(*)[3])self->matrix); } else { @@ -1326,10 +1324,10 @@ static PyObject *Matrix_to_euler(MatrixObject *self, PyObject *args) } /* Must be 3-4 cols, 3-4 rows, square matrix. */ - if (self->num_row == 3 && self->num_col == 3) { + if (self->row_num == 3 && self->col_num == 3) { copy_m3_m3(mat, (const float(*)[3])self->matrix); } - else if (self->num_row == 4 && self->num_col == 4) { + else if (self->row_num == 4 && self->col_num == 4) { copy_m3_m4(mat, (const float(*)[4])self->matrix); } else { @@ -1401,36 +1399,36 @@ static PyObject *Matrix_resize_4x4(MatrixObject *self) unit_m4(mat); - for (col = 0; col < self->num_col; col++) { - memcpy(mat[col], MATRIX_COL_PTR(self, col), self->num_row * sizeof(float)); + for (col = 0; col < self->col_num; col++) { + memcpy(mat[col], MATRIX_COL_PTR(self, col), self->row_num * sizeof(float)); } copy_m4_m4((float(*)[4])self->matrix, (const float(*)[4])mat); - self->num_col = 4; - self->num_row = 4; + self->col_num = 4; + self->row_num = 4; Py_RETURN_NONE; } -static PyObject *Matrix_to_NxN(MatrixObject *self, const int num_col, const int num_row) +static PyObject *Matrix_to_NxN(MatrixObject *self, const int col_num, const int row_num) { - const int mat_size = sizeof(float) * (num_col * num_row); + const int mat_size = sizeof(float) * (col_num * row_num); MatrixObject *pymat = (MatrixObject *)Matrix_CreatePyObject_alloc( - PyMem_Malloc(mat_size), num_col, num_row, Py_TYPE(self)); + PyMem_Malloc(mat_size), col_num, row_num, Py_TYPE(self)); - if ((self->num_row == num_row) && (self->num_col == num_col)) { + if ((self->row_num == row_num) && (self->col_num == col_num)) { memcpy(pymat->matrix, self->matrix, mat_size); } else { - if ((self->num_col < num_col) || (self->num_row < num_row)) { + if ((self->col_num < col_num) || (self->row_num < row_num)) { matrix_unit_internal(pymat); } - const int col_len_src = min_ii(num_col, self->num_col); - const int row_len_src = min_ii(num_row, self->num_row); + const int col_len_src = min_ii(col_num, self->col_num); + const int row_len_src = min_ii(row_num, self->row_num); for (int col = 0; col < col_len_src; col++) { memcpy( - &pymat->matrix[col * num_row], MATRIX_COL_PTR(self, col), sizeof(float) * row_len_src); + &pymat->matrix[col * row_num], MATRIX_COL_PTR(self, col), sizeof(float) * row_len_src); } } return (PyObject *)pymat; @@ -1495,7 +1493,7 @@ static PyObject *Matrix_to_translation(MatrixObject *self) return NULL; } - if ((self->num_row < 3) || self->num_col < 4) { + if ((self->row_num < 3) || self->col_num < 4) { PyErr_SetString(PyExc_ValueError, "Matrix.to_translation(): " "inappropriate matrix size"); @@ -1526,7 +1524,7 @@ static PyObject *Matrix_to_scale(MatrixObject *self) } /* Must be 3-4 cols, 3-4 rows, square matrix. */ - if ((self->num_row < 3) || (self->num_col < 3)) { + if ((self->row_num < 3) || (self->col_num < 3)) { PyErr_SetString(PyExc_ValueError, "Matrix.to_scale(): " "inappropriate matrix size, 3x3 minimum size"); @@ -1546,7 +1544,7 @@ static PyObject *Matrix_to_scale(MatrixObject *self) /* re-usable checks for invert */ static bool matrix_invert_is_compat(const MatrixObject *self) { - if (self->num_col != self->num_row) { + if (self->col_num != self->row_num) { PyErr_SetString(PyExc_ValueError, "Matrix.invert(ed): " "only square matrices are supported"); @@ -1571,7 +1569,7 @@ static bool matrix_invert_args_check(const MatrixObject *self, PyObject *args, b return false; } - if ((self->num_col != fallback->num_col) || (self->num_row != fallback->num_row)) { + if ((self->col_num != fallback->col_num) || (self->row_num != fallback->row_num)) { PyErr_SetString(PyExc_TypeError, "Matrix.invert: " "matrix argument has different dimensions"); @@ -1782,7 +1780,7 @@ static PyObject *Matrix_adjugate(MatrixObject *self) return NULL; } - if (self->num_col != self->num_row) { + if (self->col_num != self->row_num) { PyErr_SetString(PyExc_ValueError, "Matrix.adjugate(d): " "only square matrices are supported"); @@ -1790,12 +1788,12 @@ static PyObject *Matrix_adjugate(MatrixObject *self) } /* calculate the classical adjoint */ - if (self->num_col <= 4) { - adjoint_matrix_n(self->matrix, self->matrix, self->num_col); + if (self->col_num <= 4) { + adjoint_matrix_n(self->matrix, self->matrix, self->col_num); } else { PyErr_Format( - PyExc_ValueError, "Matrix adjugate(d): size (%d) unsupported", (int)self->num_col); + PyExc_ValueError, "Matrix adjugate(d): size (%d) unsupported", (int)self->col_num); return NULL; } @@ -1838,7 +1836,7 @@ static PyObject *Matrix_rotate(MatrixObject *self, PyObject *value) return NULL; } - if (self->num_row != 3 || self->num_col != 3) { + if (self->row_num != 3 || self->col_num != 3) { PyErr_SetString(PyExc_ValueError, "Matrix.rotate(): " "must have 3x3 dimensions"); @@ -1870,7 +1868,7 @@ static PyObject *Matrix_decompose(MatrixObject *self) float quat[4]; float size[3]; - if (self->num_row != 4 || self->num_col != 4) { + if (self->row_num != 4 || self->col_num != 4) { PyErr_SetString(PyExc_ValueError, "Matrix.decompose(): " "inappropriate matrix size - expects 4x4 matrix"); @@ -1913,7 +1911,7 @@ static PyObject *Matrix_lerp(MatrixObject *self, PyObject *args) return NULL; } - if (self->num_col != mat2->num_col || self->num_row != mat2->num_row) { + if (self->col_num != mat2->col_num || self->row_num != mat2->row_num) { PyErr_SetString(PyExc_ValueError, "Matrix.lerp(): " "expects both matrix objects of the same dimensions"); @@ -1925,14 +1923,14 @@ static PyObject *Matrix_lerp(MatrixObject *self, PyObject *args) } /* TODO: different sized matrix. */ - if (self->num_col == 4 && self->num_row == 4) { + if (self->col_num == 4 && self->row_num == 4) { #ifdef MATH_STANDALONE blend_m4_m4m4((float(*)[4])mat, (float(*)[4])self->matrix, (float(*)[4])mat2->matrix, fac); #else interp_m4_m4m4((float(*)[4])mat, (float(*)[4])self->matrix, (float(*)[4])mat2->matrix, fac); #endif } - else if (self->num_col == 3 && self->num_row == 3) { + else if (self->col_num == 3 && self->row_num == 3) { #ifdef MATH_STANDALONE blend_m3_m3m3((float(*)[3])mat, (float(*)[3])self->matrix, (float(*)[3])mat2->matrix, fac); #else @@ -1946,7 +1944,7 @@ static PyObject *Matrix_lerp(MatrixObject *self, PyObject *args) return NULL; } - return Matrix_CreatePyObject(mat, self->num_col, self->num_row, Py_TYPE(self)); + return Matrix_CreatePyObject(mat, self->col_num, self->row_num, Py_TYPE(self)); } /*---------------------------matrix.determinant() ----------------*/ @@ -1966,7 +1964,7 @@ static PyObject *Matrix_determinant(MatrixObject *self) return NULL; } - if (self->num_col != self->num_row) { + if (self->col_num != self->row_num) { PyErr_SetString(PyExc_ValueError, "Matrix.determinant(): " "only square matrices are supported"); @@ -1989,19 +1987,19 @@ static PyObject *Matrix_transpose(MatrixObject *self) return NULL; } - if (self->num_col != self->num_row) { + if (self->col_num != self->row_num) { PyErr_SetString(PyExc_ValueError, "Matrix.transpose(d): " "only square matrices are supported"); return NULL; } - if (self->num_col == 2) { + if (self->col_num == 2) { const float t = MATRIX_ITEM(self, 1, 0); MATRIX_ITEM(self, 1, 0) = MATRIX_ITEM(self, 0, 1); MATRIX_ITEM(self, 0, 1) = t; } - else if (self->num_col == 3) { + else if (self->col_num == 3) { transpose_m3((float(*)[3])self->matrix); } else { @@ -2035,17 +2033,17 @@ static PyObject *Matrix_normalize(MatrixObject *self) return NULL; } - if (self->num_col != self->num_row) { + if (self->col_num != self->row_num) { PyErr_SetString(PyExc_ValueError, "Matrix.normalize(): " "only square matrices are supported"); return NULL; } - if (self->num_col == 3) { + if (self->col_num == 3) { normalize_m3((float(*)[3])self->matrix); } - else if (self->num_col == 4) { + else if (self->col_num == 4) { normalize_m4((float(*)[4])self->matrix); } else { @@ -2083,7 +2081,7 @@ static PyObject *Matrix_zero(MatrixObject *self) return NULL; } - copy_vn_fl(self->matrix, self->num_col * self->num_row, 0.0f); + copy_vn_fl(self->matrix, self->col_num * self->row_num, 0.0f); if (BaseMath_WriteCallback(self) == -1) { return NULL; @@ -2094,12 +2092,12 @@ static PyObject *Matrix_zero(MatrixObject *self) /*---------------------------matrix.identity(() ------------------*/ static void matrix_identity_internal(MatrixObject *self) { - BLI_assert((self->num_col == self->num_row) && (self->num_row <= 4)); + BLI_assert((self->col_num == self->row_num) && (self->row_num <= 4)); - if (self->num_col == 2) { + if (self->col_num == 2) { unit_m2((float(*)[2])self->matrix); } - else if (self->num_col == 3) { + else if (self->col_num == 3) { unit_m3((float(*)[3])self->matrix); } else { @@ -2123,7 +2121,7 @@ static PyObject *Matrix_identity(MatrixObject *self) return NULL; } - if (self->num_col != self->num_row) { + if (self->col_num != self->row_num) { PyErr_SetString(PyExc_ValueError, "Matrix.identity(): " "only square matrices are supported"); @@ -2143,7 +2141,7 @@ static PyObject *Matrix_identity(MatrixObject *self) static PyObject *Matrix_copy_notest(MatrixObject *self, const float *matrix) { - return Matrix_CreatePyObject((const float *)matrix, self->num_col, self->num_row, Py_TYPE(self)); + return Matrix_CreatePyObject((const float *)matrix, self->col_num, self->row_num, Py_TYPE(self)); } PyDoc_STRVAR(Matrix_copy_doc, @@ -2180,13 +2178,13 @@ static PyObject *Matrix_repr(MatrixObject *self) return NULL; } - for (row = 0; row < self->num_row; row++) { - rows[row] = PyTuple_New(self->num_col); - for (col = 0; col < self->num_col; col++) { + for (row = 0; row < self->row_num; row++) { + rows[row] = PyTuple_New(self->col_num); + for (col = 0; col < self->col_num; col++) { PyTuple_SET_ITEM(rows[row], col, PyFloat_FromDouble(MATRIX_ITEM(self, row, col))); } } - switch (self->num_row) { + switch (self->row_num) { case 2: return PyUnicode_FromFormat( "Matrix((%R,\n" @@ -2236,9 +2234,9 @@ static PyObject *Matrix_str(MatrixObject *self) ds = BLI_dynstr_new(); /* First determine the maximum width for each column */ - for (col = 0; col < self->num_col; col++) { + for (col = 0; col < self->col_num; col++) { maxsize[col] = 0; - for (row = 0; row < self->num_row; row++) { + for (row = 0; row < self->row_num; row++) { const int size = BLI_snprintf_rlen( dummy_buf, sizeof(dummy_buf), "%.4f", MATRIX_ITEM(self, row, col)); maxsize[col] = max_ii(maxsize[col], size); @@ -2246,12 +2244,12 @@ static PyObject *Matrix_str(MatrixObject *self) } /* Now write the unicode string to be printed */ - BLI_dynstr_appendf(ds, "<Matrix %dx%d (", self->num_row, self->num_col); - for (row = 0; row < self->num_row; row++) { - for (col = 0; col < self->num_col; col++) { + BLI_dynstr_appendf(ds, "<Matrix %dx%d (", self->row_num, self->col_num); + for (row = 0; row < self->row_num; row++) { + for (col = 0; col < self->col_num; col++) { BLI_dynstr_appendf(ds, col ? ", %*.4f" : "%*.4f", maxsize[col], MATRIX_ITEM(self, row, col)); } - BLI_dynstr_append(ds, row + 1 != self->num_row ? ")\n (" : ")"); + BLI_dynstr_append(ds, row + 1 != self->row_num ? ")\n (" : ")"); } BLI_dynstr_append(ds, ">"); @@ -2272,8 +2270,8 @@ static PyObject *Matrix_richcmpr(PyObject *a, PyObject *b, int op) return NULL; } - ok = ((matA->num_row == matB->num_row) && (matA->num_col == matB->num_col) && - EXPP_VectorsAreEqual(matA->matrix, matB->matrix, (matA->num_col * matA->num_row), 1)) ? + ok = ((matA->row_num == matB->row_num) && (matA->col_num == matB->col_num) && + EXPP_VectorsAreEqual(matA->matrix, matB->matrix, (matA->col_num * matA->row_num), 1)) ? 0 : -1; } @@ -2314,7 +2312,7 @@ static Py_hash_t Matrix_hash(MatrixObject *self) matrix_transpose_internal(mat, self); - return mathutils_array_hash(mat, self->num_row * self->num_col); + return mathutils_array_hash(mat, self->row_num * self->col_num); } /*---------------------SEQUENCE PROTOCOLS------------------------ @@ -2322,7 +2320,7 @@ static Py_hash_t Matrix_hash(MatrixObject *self) * sequence length */ static int Matrix_len(MatrixObject *self) { - return self->num_row; + return self->row_num; } /*----------------------------object[]--------------------------- * sequence accessor (get) @@ -2333,14 +2331,14 @@ static PyObject *Matrix_item_row(MatrixObject *self, int row) return NULL; } - if (row < 0 || row >= self->num_row) { + if (row < 0 || row >= self->row_num) { PyErr_SetString(PyExc_IndexError, "matrix[attribute]: " "array index out of range"); return NULL; } return Vector_CreatePyObject_cb( - (PyObject *)self, self->num_col, mathutils_matrix_row_cb_index, row); + (PyObject *)self, self->col_num, mathutils_matrix_row_cb_index, row); } /* same but column access */ static PyObject *Matrix_item_col(MatrixObject *self, int col) @@ -2349,14 +2347,14 @@ static PyObject *Matrix_item_col(MatrixObject *self, int col) return NULL; } - if (col < 0 || col >= self->num_col) { + if (col < 0 || col >= self->col_num) { PyErr_SetString(PyExc_IndexError, "matrix[attribute]: " "array index out of range"); return NULL; } return Vector_CreatePyObject_cb( - (PyObject *)self, self->num_row, mathutils_matrix_col_cb_index, col); + (PyObject *)self, self->row_num, mathutils_matrix_col_cb_index, col); } /*----------------------------object[]------------------------- @@ -2370,18 +2368,18 @@ static int Matrix_ass_item_row(MatrixObject *self, int row, PyObject *value) return -1; } - if (row >= self->num_row || row < 0) { + if (row >= self->row_num || row < 0) { PyErr_SetString(PyExc_IndexError, "matrix[attribute] = x: bad row"); return -1; } if (mathutils_array_parse( - vec, self->num_col, self->num_col, value, "matrix[i] = value assignment") == -1) { + vec, self->col_num, self->col_num, value, "matrix[i] = value assignment") == -1) { return -1; } /* Since we are assigning a row we cannot memcpy */ - for (col = 0; col < self->num_col; col++) { + for (col = 0; col < self->col_num; col++) { MATRIX_ITEM(self, row, col) = vec[col]; } @@ -2396,18 +2394,18 @@ static int Matrix_ass_item_col(MatrixObject *self, int col, PyObject *value) return -1; } - if (col >= self->num_col || col < 0) { + if (col >= self->col_num || col < 0) { PyErr_SetString(PyExc_IndexError, "matrix[attribute] = x: bad col"); return -1; } if (mathutils_array_parse( - vec, self->num_row, self->num_row, value, "matrix[i] = value assignment") == -1) { + vec, self->row_num, self->row_num, value, "matrix[i] = value assignment") == -1) { return -1; } /* Since we are assigning a row we cannot memcpy */ - for (row = 0; row < self->num_row; row++) { + for (row = 0; row < self->row_num; row++) { MATRIX_ITEM(self, row, col) = vec[row]; } @@ -2427,8 +2425,8 @@ static PyObject *Matrix_slice(MatrixObject *self, int begin, int end) return NULL; } - CLAMP(begin, 0, self->num_row); - CLAMP(end, 0, self->num_row); + CLAMP(begin, 0, self->row_num); + CLAMP(end, 0, self->row_num); begin = MIN2(begin, end); tuple = PyTuple_New(end - begin); @@ -2436,7 +2434,7 @@ static PyObject *Matrix_slice(MatrixObject *self, int begin, int end) PyTuple_SET_ITEM(tuple, count - begin, Vector_CreatePyObject_cb( - (PyObject *)self, self->num_col, mathutils_matrix_row_cb_index, count)); + (PyObject *)self, self->col_num, mathutils_matrix_row_cb_index, count)); } return tuple; @@ -2451,8 +2449,8 @@ static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *va return -1; } - CLAMP(begin, 0, self->num_row); - CLAMP(end, 0, self->num_row); + CLAMP(begin, 0, self->row_num); + CLAMP(end, 0, self->row_num); begin = MIN2(begin, end); /* non list/tuple cases */ @@ -2475,7 +2473,7 @@ static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *va return -1; } - memcpy(mat, self->matrix, self->num_col * self->num_row * sizeof(float)); + memcpy(mat, self->matrix, self->col_num * self->row_num * sizeof(float)); /* parse sub items */ for (row = begin; row < end; row++) { @@ -2483,21 +2481,21 @@ static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *va PyObject *item = value_fast_items[row - begin]; if (mathutils_array_parse( - vec, self->num_col, self->num_col, item, "matrix[begin:end] = value assignment") == + vec, self->col_num, self->col_num, item, "matrix[begin:end] = value assignment") == -1) { Py_DECREF(value_fast); return -1; } - for (col = 0; col < self->num_col; col++) { - mat[col * self->num_row + row] = vec[col]; + for (col = 0; col < self->col_num; col++) { + mat[col * self->row_num + row] = vec[col]; } } Py_DECREF(value_fast); /* Parsed well - now set in matrix. */ - memcpy(self->matrix, mat, self->num_col * self->num_row * sizeof(float)); + memcpy(self->matrix, mat, self->col_num * self->row_num * sizeof(float)); (void)BaseMath_WriteCallback(self); return 0; @@ -2525,16 +2523,16 @@ static PyObject *Matrix_add(PyObject *m1, PyObject *m2) return NULL; } - if (mat1->num_col != mat2->num_col || mat1->num_row != mat2->num_row) { + if (mat1->col_num != mat2->col_num || mat1->row_num != mat2->row_num) { PyErr_SetString(PyExc_ValueError, "Matrix addition: " "matrices must have the same dimensions for this operation"); return NULL; } - add_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row); + add_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->col_num * mat1->row_num); - return Matrix_CreatePyObject(mat, mat1->num_col, mat1->num_row, Py_TYPE(mat1)); + return Matrix_CreatePyObject(mat, mat1->col_num, mat1->row_num, Py_TYPE(mat1)); } /*------------------------obj - obj------------------------------ * subtraction */ @@ -2559,24 +2557,24 @@ static PyObject *Matrix_sub(PyObject *m1, PyObject *m2) return NULL; } - if (mat1->num_col != mat2->num_col || mat1->num_row != mat2->num_row) { + if (mat1->col_num != mat2->col_num || mat1->row_num != mat2->row_num) { PyErr_SetString(PyExc_ValueError, "Matrix addition: " "matrices must have the same dimensions for this operation"); return NULL; } - sub_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row); + sub_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->col_num * mat1->row_num); - return Matrix_CreatePyObject(mat, mat1->num_col, mat1->num_row, Py_TYPE(mat1)); + return Matrix_CreatePyObject(mat, mat1->col_num, mat1->row_num, Py_TYPE(mat1)); } /*------------------------obj * obj------------------------------ * element-wise multiplication */ static PyObject *matrix_mul_float(MatrixObject *mat, const float scalar) { float tmat[MATRIX_MAX_DIM * MATRIX_MAX_DIM]; - mul_vn_vn_fl(tmat, mat->matrix, mat->num_col * mat->num_row, scalar); - return Matrix_CreatePyObject(tmat, mat->num_col, mat->num_row, Py_TYPE(mat)); + mul_vn_vn_fl(tmat, mat->matrix, mat->col_num * mat->row_num, scalar); + return Matrix_CreatePyObject(tmat, mat->col_num, mat->row_num, Py_TYPE(mat)); } static PyObject *Matrix_mul(PyObject *m1, PyObject *m2) @@ -2602,16 +2600,16 @@ static PyObject *Matrix_mul(PyObject *m1, PyObject *m2) /* MATRIX * MATRIX */ float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM]; - if ((mat1->num_row != mat2->num_row) || (mat1->num_col != mat2->num_col)) { + if ((mat1->row_num != mat2->row_num) || (mat1->col_num != mat2->col_num)) { PyErr_SetString(PyExc_ValueError, "matrix1 * matrix2: matrix1 number of rows/columns " "and the matrix2 number of rows/columns must be the same"); return NULL; } - mul_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row); + mul_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->col_num * mat1->row_num); - return Matrix_CreatePyObject(mat, mat2->num_col, mat1->num_row, Py_TYPE(mat1)); + return Matrix_CreatePyObject(mat, mat2->col_num, mat1->row_num, Py_TYPE(mat1)); } if (mat2) { /* FLOAT/INT * MATRIX */ @@ -2656,18 +2654,18 @@ static PyObject *Matrix_imul(PyObject *m1, PyObject *m2) if (mat1 && mat2) { /* MATRIX *= MATRIX */ - if ((mat1->num_row != mat2->num_row) || (mat1->num_col != mat2->num_col)) { + if ((mat1->row_num != mat2->row_num) || (mat1->col_num != mat2->col_num)) { PyErr_SetString(PyExc_ValueError, "matrix1 *= matrix2: matrix1 number of rows/columns " "and the matrix2 number of rows/columns must be the same"); return NULL; } - mul_vn_vn(mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row); + mul_vn_vn(mat1->matrix, mat2->matrix, mat1->col_num * mat1->row_num); } else if (mat1 && (((scalar = PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred()) == 0)) { /* MATRIX *= FLOAT/INT */ - mul_vn_fl(mat1->matrix, mat1->num_row * mat1->num_col, scalar); + mul_vn_fl(mat1->matrix, mat1->row_num * mat1->col_num, scalar); } else { PyErr_Format(PyExc_TypeError, @@ -2686,7 +2684,7 @@ static PyObject *Matrix_imul(PyObject *m1, PyObject *m2) * matrix multiplication */ static PyObject *Matrix_matmul(PyObject *m1, PyObject *m2) { - int vec_size; + int vec_num; MatrixObject *mat1 = NULL, *mat2 = NULL; @@ -2709,24 +2707,24 @@ static PyObject *Matrix_matmul(PyObject *m1, PyObject *m2) int col, row, item; - if (mat1->num_col != mat2->num_row) { + if (mat1->col_num != mat2->row_num) { PyErr_SetString(PyExc_ValueError, "matrix1 * matrix2: matrix1 number of columns " "and the matrix2 number of rows must be the same"); return NULL; } - for (col = 0; col < mat2->num_col; col++) { - for (row = 0; row < mat1->num_row; row++) { + for (col = 0; col < mat2->col_num; col++) { + for (row = 0; row < mat1->row_num; row++) { double dot = 0.0f; - for (item = 0; item < mat1->num_col; item++) { + for (item = 0; item < mat1->col_num; item++) { dot += (double)(MATRIX_ITEM(mat1, row, item) * MATRIX_ITEM(mat2, item, col)); } - mat[(col * mat1->num_row) + row] = (float)dot; + mat[(col * mat1->row_num) + row] = (float)dot; } } - return Matrix_CreatePyObject(mat, mat2->num_col, mat1->num_row, Py_TYPE(mat1)); + return Matrix_CreatePyObject(mat, mat2->col_num, mat1->row_num, Py_TYPE(mat1)); } if (mat1) { /* MATRIX @ VECTOR */ @@ -2740,14 +2738,14 @@ static PyObject *Matrix_matmul(PyObject *m1, PyObject *m2) return NULL; } - if (mat1->num_col == 4 && vec2->size == 3) { - vec_size = 3; + if (mat1->col_num == 4 && vec2->vec_num == 3) { + vec_num = 3; } else { - vec_size = mat1->num_row; + vec_num = mat1->row_num; } - return Vector_CreatePyObject(tvec, vec_size, Py_TYPE(m2)); + return Vector_CreatePyObject(tvec, vec_num, Py_TYPE(m2)); } } @@ -2782,27 +2780,27 @@ static PyObject *Matrix_imatmul(PyObject *m1, PyObject *m2) float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM]; int col, row, item; - if (mat1->num_col != mat2->num_row) { + if (mat1->col_num != mat2->row_num) { PyErr_SetString(PyExc_ValueError, "matrix1 * matrix2: matrix1 number of columns " "and the matrix2 number of rows must be the same"); return NULL; } - for (col = 0; col < mat2->num_col; col++) { - for (row = 0; row < mat1->num_row; row++) { + for (col = 0; col < mat2->col_num; col++) { + for (row = 0; row < mat1->row_num; row++) { double dot = 0.0f; - for (item = 0; item < mat1->num_col; item++) { + for (item = 0; item < mat1->col_num; item++) { dot += (double)(MATRIX_ITEM(mat1, row, item) * MATRIX_ITEM(mat2, item, col)); } /* store in new matrix as overwriting original at this point will cause * subsequent iterations to use incorrect values */ - mat[(col * mat1->num_row) + row] = (float)dot; + mat[(col * mat1->row_num) + row] = (float)dot; } } /* copy matrix back */ - memcpy(mat1->matrix, mat, (mat1->num_row * mat1->num_col) * sizeof(float)); + memcpy(mat1->matrix, mat, (mat1->row_num * mat1->col_num) * sizeof(float)); } else { PyErr_Format(PyExc_TypeError, @@ -2841,14 +2839,14 @@ static PyObject *Matrix_subscript(MatrixObject *self, PyObject *item) return NULL; } if (i < 0) { - i += self->num_row; + i += self->row_num; } return Matrix_item_row(self, i); } if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; - if (PySlice_GetIndicesEx(item, self->num_row, &start, &stop, &step, &slicelength) < 0) { + if (PySlice_GetIndicesEx(item, self->row_num, &start, &stop, &step, &slicelength) < 0) { return NULL; } @@ -2876,14 +2874,14 @@ static int Matrix_ass_subscript(MatrixObject *self, PyObject *item, PyObject *va return -1; } if (i < 0) { - i += self->num_row; + i += self->row_num; } return Matrix_ass_item_row(self, i, value); } if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; - if (PySlice_GetIndicesEx(item, self->num_row, &start, &stop, &step, &slicelength) < 0) { + if (PySlice_GetIndicesEx(item, self->row_num, &start, &stop, &step, &slicelength) < 0) { return -1; } @@ -2955,7 +2953,7 @@ static PyObject *Matrix_translation_get(MatrixObject *self, void *UNUSED(closure } /* Must be 4x4 square matrix. */ - if (self->num_row != 4 || self->num_col != 4) { + if (self->row_num != 4 || self->col_num != 4) { PyErr_SetString(PyExc_AttributeError, "Matrix.translation: " "inappropriate matrix size, must be 4x4"); @@ -2977,7 +2975,7 @@ static int Matrix_translation_set(MatrixObject *self, PyObject *value, void *UNU } /* Must be 4x4 square matrix. */ - if (self->num_row != 4 || self->num_col != 4) { + if (self->row_num != 4 || self->col_num != 4) { PyErr_SetString(PyExc_AttributeError, "Matrix.translation: " "inappropriate matrix size, must be 4x4"); @@ -3021,7 +3019,7 @@ static PyObject *Matrix_median_scale_get(MatrixObject *self, void *UNUSED(closur } /* Must be 3-4 cols, 3-4 rows, square matrix. */ - if ((self->num_row < 3) || (self->num_col < 3)) { + if ((self->row_num < 3) || (self->col_num < 3)) { PyErr_SetString(PyExc_AttributeError, "Matrix.median_scale: " "inappropriate matrix size, 3x3 minimum"); @@ -3043,10 +3041,10 @@ static PyObject *Matrix_is_negative_get(MatrixObject *self, void *UNUSED(closure } /* Must be 3-4 cols, 3-4 rows, square matrix. */ - if (self->num_row == 4 && self->num_col == 4) { + if (self->row_num == 4 && self->col_num == 4) { return PyBool_FromLong(is_negative_m4((const float(*)[4])self->matrix)); } - if (self->num_row == 3 && self->num_col == 3) { + if (self->row_num == 3 && self->col_num == 3) { return PyBool_FromLong(is_negative_m3((const float(*)[3])self->matrix)); } @@ -3065,10 +3063,10 @@ static PyObject *Matrix_is_orthogonal_get(MatrixObject *self, void *UNUSED(closu } /* Must be 3-4 cols, 3-4 rows, square matrix. */ - if (self->num_row == 4 && self->num_col == 4) { + if (self->row_num == 4 && self->col_num == 4) { return PyBool_FromLong(is_orthonormal_m4((const float(*)[4])self->matrix)); } - if (self->num_row == 3 && self->num_col == 3) { + if (self->row_num == 3 && self->col_num == 3) { return PyBool_FromLong(is_orthonormal_m3((const float(*)[3])self->matrix)); } @@ -3088,10 +3086,10 @@ static PyObject *Matrix_is_orthogonal_axis_vectors_get(MatrixObject *self, void } /* Must be 3-4 cols, 3-4 rows, square matrix. */ - if (self->num_row == 4 && self->num_col == 4) { + if (self->row_num == 4 && self->col_num == 4) { return PyBool_FromLong(is_orthogonal_m4((const float(*)[4])self->matrix)); } - if (self->num_row == 3 && self->num_col == 3) { + if (self->row_num == 3 && self->col_num == 3) { return PyBool_FromLong(is_orthogonal_m3((const float(*)[3])self->matrix)); } @@ -3271,22 +3269,22 @@ PyTypeObject matrix_Type = { }; PyObject *Matrix_CreatePyObject(const float *mat, - const ushort num_col, - const ushort num_row, + const ushort col_num, + const ushort row_num, PyTypeObject *base_type) { MatrixObject *self; float *mat_alloc; /* matrix objects can be any 2-4row x 2-4col matrix */ - if (num_col < 2 || num_col > 4 || num_row < 2 || num_row > 4) { + if (col_num < 2 || col_num > 4 || row_num < 2 || row_num > 4) { PyErr_SetString(PyExc_RuntimeError, "Matrix(): " "row and column sizes must be between 2 and 4"); return NULL; } - mat_alloc = PyMem_Malloc(num_col * num_row * sizeof(float)); + mat_alloc = PyMem_Malloc(col_num * row_num * sizeof(float)); if (UNLIKELY(mat_alloc == NULL)) { PyErr_SetString(PyExc_MemoryError, "Matrix(): " @@ -3297,23 +3295,23 @@ PyObject *Matrix_CreatePyObject(const float *mat, self = BASE_MATH_NEW(MatrixObject, matrix_Type, base_type); if (self) { self->matrix = mat_alloc; - self->num_col = num_col; - self->num_row = num_row; + self->col_num = col_num; + self->row_num = row_num; /* init callbacks as NULL */ self->cb_user = NULL; self->cb_type = self->cb_subtype = 0; if (mat) { /* If a float array passed. */ - memcpy(self->matrix, mat, num_col * num_row * sizeof(float)); + memcpy(self->matrix, mat, col_num * row_num * sizeof(float)); } - else if (num_col == num_row) { + else if (col_num == row_num) { /* or if no arguments are passed return identity matrix for square matrices */ matrix_identity_internal(self); } else { /* otherwise zero everything */ - memset(self->matrix, 0, num_col * num_row * sizeof(float)); + memset(self->matrix, 0, col_num * row_num * sizeof(float)); } self->flag = BASE_MATH_FLAG_DEFAULT; } @@ -3325,14 +3323,14 @@ PyObject *Matrix_CreatePyObject(const float *mat, } PyObject *Matrix_CreatePyObject_wrap(float *mat, - const ushort num_col, - const ushort num_row, + const ushort col_num, + const ushort row_num, PyTypeObject *base_type) { MatrixObject *self; /* matrix objects can be any 2-4row x 2-4col matrix */ - if (num_col < 2 || num_col > 4 || num_row < 2 || num_row > 4) { + if (col_num < 2 || col_num > 4 || row_num < 2 || row_num > 4) { PyErr_SetString(PyExc_RuntimeError, "Matrix(): " "row and column sizes must be between 2 and 4"); @@ -3341,8 +3339,8 @@ PyObject *Matrix_CreatePyObject_wrap(float *mat, self = BASE_MATH_NEW(MatrixObject, matrix_Type, base_type); if (self) { - self->num_col = num_col; - self->num_row = num_row; + self->col_num = col_num; + self->row_num = row_num; /* init callbacks as NULL */ self->cb_user = NULL; @@ -3355,9 +3353,9 @@ PyObject *Matrix_CreatePyObject_wrap(float *mat, } PyObject *Matrix_CreatePyObject_cb( - PyObject *cb_user, const ushort num_col, const ushort num_row, uchar cb_type, uchar cb_subtype) + PyObject *cb_user, const ushort col_num, const ushort row_num, uchar cb_type, uchar cb_subtype) { - MatrixObject *self = (MatrixObject *)Matrix_CreatePyObject(NULL, num_col, num_row, NULL); + MatrixObject *self = (MatrixObject *)Matrix_CreatePyObject(NULL, col_num, row_num, NULL); if (self) { Py_INCREF(cb_user); self->cb_user = cb_user; @@ -3369,12 +3367,12 @@ PyObject *Matrix_CreatePyObject_cb( } PyObject *Matrix_CreatePyObject_alloc(float *mat, - const ushort num_col, - const ushort num_row, + const ushort col_num, + const ushort row_num, PyTypeObject *base_type) { MatrixObject *self; - self = (MatrixObject *)Matrix_CreatePyObject_wrap(mat, num_col, num_row, base_type); + self = (MatrixObject *)Matrix_CreatePyObject_wrap(mat, col_num, row_num, base_type); if (self) { self->flag &= ~BASE_MATH_FLAG_IS_WRAP; } @@ -3419,7 +3417,7 @@ int Matrix_Parse2x2(PyObject *o, void *p) if (!Matrix_ParseCheck(pymat)) { return 0; } - if ((pymat->num_col != 2) || (pymat->num_row != 2)) { + if ((pymat->col_num != 2) || (pymat->row_num != 2)) { PyErr_SetString(PyExc_ValueError, "matrix must be 2x2"); return 0; } @@ -3436,7 +3434,7 @@ int Matrix_Parse3x3(PyObject *o, void *p) if (!Matrix_ParseCheck(pymat)) { return 0; } - if ((pymat->num_col != 3) || (pymat->num_row != 3)) { + if ((pymat->col_num != 3) || (pymat->row_num != 3)) { PyErr_SetString(PyExc_ValueError, "matrix must be 3x3"); return 0; } @@ -3453,7 +3451,7 @@ int Matrix_Parse4x4(PyObject *o, void *p) if (!Matrix_ParseCheck(pymat)) { return 0; } - if ((pymat->num_col != 4) || (pymat->num_row != 4)) { + if ((pymat->col_num != 4) || (pymat->row_num != 4)) { PyErr_SetString(PyExc_ValueError, "matrix must be 4x4"); return 0; } @@ -3497,7 +3495,7 @@ static void MatrixAccess_dealloc(MatrixAccessObject *self) static int MatrixAccess_len(MatrixAccessObject *self) { - return (self->type == MAT_ACCESS_ROW) ? self->matrix_user->num_row : self->matrix_user->num_col; + return (self->type == MAT_ACCESS_ROW) ? self->matrix_user->row_num : self->matrix_user->col_num; } static PyObject *MatrixAccess_slice(MatrixAccessObject *self, int begin, int end) @@ -3511,11 +3509,11 @@ static PyObject *MatrixAccess_slice(MatrixAccessObject *self, int begin, int end PyObject *(*Matrix_item_new)(MatrixObject *, int); if (self->type == MAT_ACCESS_ROW) { - matrix_access_len = matrix_user->num_row; + matrix_access_len = matrix_user->row_num; Matrix_item_new = Matrix_item_row; } else { /* MAT_ACCESS_ROW */ - matrix_access_len = matrix_user->num_col; + matrix_access_len = matrix_user->col_num; Matrix_item_new = Matrix_item_col; } @@ -3546,13 +3544,13 @@ static PyObject *MatrixAccess_subscript(MatrixAccessObject *self, PyObject *item } if (self->type == MAT_ACCESS_ROW) { if (i < 0) { - i += matrix_user->num_row; + i += matrix_user->row_num; } return Matrix_item_row(matrix_user, i); } /* MAT_ACCESS_ROW */ if (i < 0) { - i += matrix_user->num_col; + i += matrix_user->col_num; } return Matrix_item_col(matrix_user, i); } @@ -3592,13 +3590,13 @@ static int MatrixAccess_ass_subscript(MatrixAccessObject *self, PyObject *item, if (self->type == MAT_ACCESS_ROW) { if (i < 0) { - i += matrix_user->num_row; + i += matrix_user->row_num; } return Matrix_ass_item_row(matrix_user, i, value); } /* MAT_ACCESS_ROW */ if (i < 0) { - i += matrix_user->num_col; + i += matrix_user->col_num; } return Matrix_ass_item_col(matrix_user, i, value); } diff --git a/source/blender/python/mathutils/mathutils_Matrix.h b/source/blender/python/mathutils/mathutils_Matrix.h index 6dd1640b3bf..bc596ce6ac8 100644 --- a/source/blender/python/mathutils/mathutils_Matrix.h +++ b/source/blender/python/mathutils/mathutils_Matrix.h @@ -20,14 +20,14 @@ typedef unsigned short ushort; #ifdef DEBUG # define MATRIX_ITEM_ASSERT(_mat, _row, _col) \ - (BLI_assert(_row < (_mat)->num_row && _col < (_mat)->num_col)) + (BLI_assert(_row < (_mat)->row_num && _col < (_mat)->col_num)) #else # define MATRIX_ITEM_ASSERT(_mat, _row, _col) (void)0 #endif #define MATRIX_ITEM_INDEX_NUMROW(_totrow, _row, _col) (((_totrow) * (_col)) + (_row)) #define MATRIX_ITEM_INDEX(_mat, _row, _col) \ - (MATRIX_ITEM_ASSERT(_mat, _row, _col), (((_mat)->num_row * (_col)) + (_row))) + (MATRIX_ITEM_ASSERT(_mat, _row, _col), (((_mat)->row_num * (_col)) + (_row))) #define MATRIX_ITEM_PTR(_mat, _row, _col) ((_mat)->matrix + MATRIX_ITEM_INDEX(_mat, _row, _col)) #define MATRIX_ITEM(_mat, _row, _col) ((_mat)->matrix[MATRIX_ITEM_INDEX(_mat, _row, _col)]) @@ -36,8 +36,8 @@ typedef unsigned short ushort; typedef struct { BASE_MATH_MEMBERS(matrix); - ushort num_col; - ushort num_row; + ushort col_num; + ushort row_num; } MatrixObject; /* struct data contains a pointer to the actual data that the @@ -47,17 +47,17 @@ typedef struct { /* prototypes */ PyObject *Matrix_CreatePyObject(const float *mat, - ushort num_col, - ushort num_row, + ushort col_num, + ushort row_num, PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT; PyObject *Matrix_CreatePyObject_wrap(float *mat, - ushort num_col, - ushort num_row, + ushort col_num, + ushort row_num, PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); PyObject *Matrix_CreatePyObject_cb(PyObject *user, - unsigned short num_col, - unsigned short num_row, + unsigned short col_num, + unsigned short row_num, unsigned char cb_type, unsigned char cb_subtype) ATTR_WARN_UNUSED_RESULT; @@ -65,8 +65,8 @@ PyObject *Matrix_CreatePyObject_cb(PyObject *user, * \param mat: Initialized matrix value to use in-place, allocated with #PyMem_Malloc */ PyObject *Matrix_CreatePyObject_alloc(float *mat, - ushort num_col, - ushort num_row, + ushort col_num, + ushort row_num, PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT; /* PyArg_ParseTuple's "O&" formatting helpers. */ diff --git a/source/blender/python/mathutils/mathutils_Quaternion.c b/source/blender/python/mathutils/mathutils_Quaternion.c index f0ba125e768..7b51154f0d0 100644 --- a/source/blender/python/mathutils/mathutils_Quaternion.c +++ b/source/blender/python/mathutils/mathutils_Quaternion.c @@ -1035,7 +1035,7 @@ static PyObject *Quaternion_matmul(PyObject *q1, PyObject *q2) VectorObject *vec2 = (VectorObject *)q2; float tvec[3]; - if (vec2->size != 3) { + if (vec2->vec_num != 3) { PyErr_SetString(PyExc_ValueError, "Vector multiplication: " "only 3D vector rotations (with quats) " diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c index 080a1e7fbdd..ffeb121b3d1 100644 --- a/source/blender/python/mathutils/mathutils_Vector.c +++ b/source/blender/python/mathutils/mathutils_Vector.c @@ -45,7 +45,7 @@ static int row_vector_multiplication(float r_vec[MAX_DIMENSIONS], static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { float *vec = NULL; - int size = 3; /* default to a 3D vector */ + int vec_num = 3; /* default to a 3D vector */ if (kwds && PyDict_Size(kwds)) { PyErr_SetString(PyExc_TypeError, @@ -56,7 +56,7 @@ static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds) switch (PyTuple_GET_SIZE(args)) { case 0: - vec = PyMem_Malloc(size * sizeof(float)); + vec = PyMem_Malloc(vec_num * sizeof(float)); if (vec == NULL) { PyErr_SetString(PyExc_MemoryError, @@ -65,10 +65,10 @@ static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } - copy_vn_fl(vec, size, 0.0f); + copy_vn_fl(vec, vec_num, 0.0f); break; case 1: - if ((size = mathutils_array_parse_alloc( + if ((vec_num = mathutils_array_parse_alloc( &vec, 2, PyTuple_GET_ITEM(args, 0), "mathutils.Vector()")) == -1) { return NULL; } @@ -79,7 +79,7 @@ static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds) "more than a single arg given"); return NULL; } - return Vector_CreatePyObject_alloc(vec, size, type); + return Vector_CreatePyObject_alloc(vec, vec_num, type); } static PyObject *vec__apply_to_copy(PyObject *(*vec_func)(VectorObject *), VectorObject *self) @@ -108,19 +108,19 @@ PyDoc_STRVAR(C_Vector_Fill_doc, static PyObject *C_Vector_Fill(PyObject *cls, PyObject *args) { float *vec; - int size; + int vec_num; float fill = 0.0f; - if (!PyArg_ParseTuple(args, "i|f:Vector.Fill", &size, &fill)) { + if (!PyArg_ParseTuple(args, "i|f:Vector.Fill", &vec_num, &fill)) { return NULL; } - if (size < 2) { + if (vec_num < 2) { PyErr_SetString(PyExc_RuntimeError, "Vector(): invalid size"); return NULL; } - vec = PyMem_Malloc(size * sizeof(float)); + vec = PyMem_Malloc(vec_num * sizeof(float)); if (vec == NULL) { PyErr_SetString(PyExc_MemoryError, @@ -129,9 +129,9 @@ static PyObject *C_Vector_Fill(PyObject *cls, PyObject *args) return NULL; } - copy_vn_fl(vec, size, fill); + copy_vn_fl(vec, vec_num, fill); - return Vector_CreatePyObject_alloc(vec, size, (PyTypeObject *)cls); + return Vector_CreatePyObject_alloc(vec, vec_num, (PyTypeObject *)cls); } PyDoc_STRVAR(C_Vector_Range_doc, @@ -148,7 +148,7 @@ PyDoc_STRVAR(C_Vector_Range_doc, static PyObject *C_Vector_Range(PyObject *cls, PyObject *args) { float *vec; - int stop, size; + int stop, vec_num; int start = 0; int step = 1; @@ -158,7 +158,7 @@ static PyObject *C_Vector_Range(PyObject *cls, PyObject *args) switch (PyTuple_GET_SIZE(args)) { case 1: - size = start; + vec_num = start; start = 0; break; case 2: @@ -169,7 +169,7 @@ static PyObject *C_Vector_Range(PyObject *cls, PyObject *args) return NULL; } - size = stop - start; + vec_num = stop - start; break; default: if (start >= stop) { @@ -179,23 +179,23 @@ static PyObject *C_Vector_Range(PyObject *cls, PyObject *args) return NULL; } - size = (stop - start); + vec_num = (stop - start); - if ((size % step) != 0) { - size += step; + if ((vec_num % step) != 0) { + vec_num += step; } - size /= step; + vec_num /= step; break; } - if (size < 2) { + if (vec_num < 2) { PyErr_SetString(PyExc_RuntimeError, "Vector(): invalid size"); return NULL; } - vec = PyMem_Malloc(size * sizeof(float)); + vec = PyMem_Malloc(vec_num * sizeof(float)); if (vec == NULL) { PyErr_SetString(PyExc_MemoryError, @@ -204,9 +204,9 @@ static PyObject *C_Vector_Range(PyObject *cls, PyObject *args) return NULL; } - range_vn_fl(vec, size, (float)start, (float)step); + range_vn_fl(vec, vec_num, (float)start, (float)step); - return Vector_CreatePyObject_alloc(vec, size, (PyTypeObject *)cls); + return Vector_CreatePyObject_alloc(vec, vec_num, (PyTypeObject *)cls); } PyDoc_STRVAR(C_Vector_Linspace_doc, @@ -224,21 +224,21 @@ PyDoc_STRVAR(C_Vector_Linspace_doc, static PyObject *C_Vector_Linspace(PyObject *cls, PyObject *args) { float *vec; - int size; + int vec_num; float start, end, step; - if (!PyArg_ParseTuple(args, "ffi:Vector.Linspace", &start, &end, &size)) { + if (!PyArg_ParseTuple(args, "ffi:Vector.Linspace", &start, &end, &vec_num)) { return NULL; } - if (size < 2) { + if (vec_num < 2) { PyErr_SetString(PyExc_RuntimeError, "Vector.Linspace(): invalid size"); return NULL; } - step = (end - start) / (float)(size - 1); + step = (end - start) / (float)(vec_num - 1); - vec = PyMem_Malloc(size * sizeof(float)); + vec = PyMem_Malloc(vec_num * sizeof(float)); if (vec == NULL) { PyErr_SetString(PyExc_MemoryError, @@ -247,9 +247,9 @@ static PyObject *C_Vector_Linspace(PyObject *cls, PyObject *args) return NULL; } - range_vn_fl(vec, size, start, step); + range_vn_fl(vec, vec_num, start, step); - return Vector_CreatePyObject_alloc(vec, size, (PyTypeObject *)cls); + return Vector_CreatePyObject_alloc(vec, vec_num, (PyTypeObject *)cls); } PyDoc_STRVAR( @@ -266,20 +266,20 @@ static PyObject *C_Vector_Repeat(PyObject *cls, PyObject *args) { float *vec; float *iter_vec = NULL; - int i, size, value_size; + int i, vec_num, value_num; PyObject *value; - if (!PyArg_ParseTuple(args, "Oi:Vector.Repeat", &value, &size)) { + if (!PyArg_ParseTuple(args, "Oi:Vector.Repeat", &value, &vec_num)) { return NULL; } - if (size < 2) { - PyErr_SetString(PyExc_RuntimeError, "Vector.Repeat(): invalid size"); + if (vec_num < 2) { + PyErr_SetString(PyExc_RuntimeError, "Vector.Repeat(): invalid vec_num"); return NULL; } - if ((value_size = mathutils_array_parse_alloc( - &iter_vec, 2, value, "Vector.Repeat(vector, size), invalid 'vector' arg")) == -1) { + if ((value_num = mathutils_array_parse_alloc( + &iter_vec, 2, value, "Vector.Repeat(vector, vec_num), invalid 'vector' arg")) == -1) { return NULL; } @@ -290,7 +290,7 @@ static PyObject *C_Vector_Repeat(PyObject *cls, PyObject *args) return NULL; } - vec = PyMem_Malloc(size * sizeof(float)); + vec = PyMem_Malloc(vec_num * sizeof(float)); if (vec == NULL) { PyMem_Free(iter_vec); @@ -301,14 +301,14 @@ static PyObject *C_Vector_Repeat(PyObject *cls, PyObject *args) } i = 0; - while (i < size) { - vec[i] = iter_vec[i % value_size]; + while (i < vec_num) { + vec[i] = iter_vec[i % value_num]; i++; } PyMem_Free(iter_vec); - return Vector_CreatePyObject_alloc(vec, size, (PyTypeObject *)cls); + return Vector_CreatePyObject_alloc(vec, vec_num, (PyTypeObject *)cls); } /*-----------------------------METHODS---------------------------- */ @@ -322,7 +322,7 @@ static PyObject *Vector_zero(VectorObject *self) return NULL; } - copy_vn_fl(self->vec, self->size, 0.0f); + copy_vn_fl(self->vec, self->vec_num, 0.0f); if (BaseMath_WriteCallback(self) == -1) { return NULL; @@ -342,12 +342,12 @@ PyDoc_STRVAR(Vector_normalize_doc, " however 4D Vectors w axis is left untouched.\n"); static PyObject *Vector_normalize(VectorObject *self) { - const int size = (self->size == 4 ? 3 : self->size); + const int vec_num = (self->vec_num == 4 ? 3 : self->vec_num); if (BaseMath_ReadCallback_ForWrite(self) == -1) { return NULL; } - normalize_vn(self->vec, size); + normalize_vn(self->vec, vec_num); (void)BaseMath_WriteCallback(self); Py_RETURN_NONE; @@ -370,7 +370,7 @@ PyDoc_STRVAR(Vector_resize_doc, " Resize the vector to have size number of elements.\n"); static PyObject *Vector_resize(VectorObject *self, PyObject *value) { - int size; + int vec_num; if (self->flag & BASE_MATH_FLAG_IS_WRAP) { PyErr_SetString(PyExc_TypeError, @@ -385,19 +385,19 @@ static PyObject *Vector_resize(VectorObject *self, PyObject *value) return NULL; } - if ((size = PyC_Long_AsI32(value)) == -1) { + if ((vec_num = PyC_Long_AsI32(value)) == -1) { PyErr_SetString(PyExc_TypeError, "Vector.resize(size): " "expected size argument to be an integer"); return NULL; } - if (size < 2) { + if (vec_num < 2) { PyErr_SetString(PyExc_RuntimeError, "Vector.resize(): invalid size"); return NULL; } - self->vec = PyMem_Realloc(self->vec, (size * sizeof(float))); + self->vec = PyMem_Realloc(self->vec, (vec_num * sizeof(float))); if (self->vec == NULL) { PyErr_SetString(PyExc_MemoryError, "Vector.resize(): " @@ -406,11 +406,11 @@ static PyObject *Vector_resize(VectorObject *self, PyObject *value) } /* If the vector has increased in length, set all new elements to 0.0f */ - if (size > self->size) { - copy_vn_fl(self->vec + self->size, size - self->size, 0.0f); + if (vec_num > self->vec_num) { + copy_vn_fl(self->vec + self->vec_num, vec_num - self->vec_num, 0.0f); } - self->size = size; + self->vec_num = vec_num; Py_RETURN_NONE; } @@ -423,19 +423,19 @@ PyDoc_STRVAR(Vector_resized_doc, " :rtype: :class:`Vector`\n"); static PyObject *Vector_resized(VectorObject *self, PyObject *value) { - int size; + int vec_num; float *vec; - if ((size = PyLong_AsLong(value)) == -1) { + if ((vec_num = PyLong_AsLong(value)) == -1) { return NULL; } - if (size < 2) { + if (vec_num < 2) { PyErr_SetString(PyExc_RuntimeError, "Vector.resized(): invalid size"); return NULL; } - vec = PyMem_Malloc(size * sizeof(float)); + vec = PyMem_Malloc(vec_num * sizeof(float)); if (vec == NULL) { PyErr_SetString(PyExc_MemoryError, @@ -444,10 +444,10 @@ static PyObject *Vector_resized(VectorObject *self, PyObject *value) return NULL; } - copy_vn_fl(vec, size, 0.0f); - memcpy(vec, self->vec, self->size * sizeof(float)); + copy_vn_fl(vec, vec_num, 0.0f); + memcpy(vec, self->vec, self->vec_num * sizeof(float)); - return Vector_CreatePyObject_alloc(vec, size, NULL); + return Vector_CreatePyObject_alloc(vec, vec_num, NULL); } PyDoc_STRVAR(Vector_resize_2d_doc, @@ -477,7 +477,7 @@ static PyObject *Vector_resize_2d(VectorObject *self) return NULL; } - self->size = 2; + self->vec_num = 2; Py_RETURN_NONE; } @@ -508,11 +508,11 @@ static PyObject *Vector_resize_3d(VectorObject *self) return NULL; } - if (self->size == 2) { + if (self->vec_num == 2) { self->vec[2] = 0.0f; } - self->size = 3; + self->vec_num = 3; Py_RETURN_NONE; } @@ -543,14 +543,14 @@ static PyObject *Vector_resize_4d(VectorObject *self) return NULL; } - if (self->size == 2) { + if (self->vec_num == 2) { self->vec[2] = 0.0f; self->vec[3] = 1.0f; } - else if (self->size == 3) { + else if (self->vec_num == 3) { self->vec[3] = 1.0f; } - self->size = 4; + self->vec_num = 4; Py_RETURN_NONE; } PyDoc_STRVAR(Vector_to_2d_doc, @@ -583,7 +583,7 @@ static PyObject *Vector_to_3d(VectorObject *self) return NULL; } - memcpy(tvec, self->vec, sizeof(float) * MIN2(self->size, 3)); + memcpy(tvec, self->vec, sizeof(float) * MIN2(self->vec_num, 3)); return Vector_CreatePyObject(tvec, 3, Py_TYPE(self)); } PyDoc_STRVAR(Vector_to_4d_doc, @@ -601,7 +601,7 @@ static PyObject *Vector_to_4d(VectorObject *self) return NULL; } - memcpy(tvec, self->vec, sizeof(float) * MIN2(self->size, 4)); + memcpy(tvec, self->vec, sizeof(float) * MIN2(self->vec_num, 4)); return Vector_CreatePyObject(tvec, 4, Py_TYPE(self)); } @@ -620,15 +620,15 @@ static PyObject *Vector_to_tuple_ex(VectorObject *self, int ndigits) PyObject *ret; int i; - ret = PyTuple_New(self->size); + ret = PyTuple_New(self->vec_num); if (ndigits >= 0) { - for (i = 0; i < self->size; i++) { + for (i = 0; i < self->vec_num; i++) { PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(double_round((double)self->vec[i], ndigits))); } } else { - for (i = 0; i < self->size; i++) { + for (i = 0; i < self->vec_num; i++) { PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(self->vec[i])); } } @@ -684,7 +684,7 @@ static PyObject *Vector_to_track_quat(VectorObject *self, PyObject *args) return NULL; } - if (self->size != 3) { + if (self->vec_num != 3) { PyErr_SetString(PyExc_TypeError, "Vector.to_track_quat(): " "only for 3D vectors"); @@ -795,7 +795,7 @@ static PyObject *Vector_orthogonal(VectorObject *self) { float vec[3]; - if (self->size > 3) { + if (self->vec_num > 3) { PyErr_SetString(PyExc_TypeError, "Vector.orthogonal(): " "Vector must be 3D or 2D"); @@ -806,14 +806,14 @@ static PyObject *Vector_orthogonal(VectorObject *self) return NULL; } - if (self->size == 3) { + if (self->vec_num == 3) { ortho_v3_v3(vec, self->vec); } else { ortho_v2_v2(vec, self->vec); } - return Vector_CreatePyObject(vec, self->size, Py_TYPE(self)); + return Vector_CreatePyObject(vec, self->vec_num, Py_TYPE(self)); } /** @@ -833,7 +833,7 @@ PyDoc_STRVAR(Vector_reflect_doc, " :rtype: :class:`Vector`\n"); static PyObject *Vector_reflect(VectorObject *self, PyObject *value) { - int value_size; + int value_num; float mirror[3], vec[3]; float reflect[3] = {0.0f}; float tvec[MAX_DIMENSIONS]; @@ -842,28 +842,28 @@ static PyObject *Vector_reflect(VectorObject *self, PyObject *value) return NULL; } - if ((value_size = mathutils_array_parse( + if ((value_num = mathutils_array_parse( tvec, 2, 4, value, "Vector.reflect(other), invalid 'other' arg")) == -1) { return NULL; } - if (self->size < 2 || self->size > 4) { + if (self->vec_num < 2 || self->vec_num > 4) { PyErr_SetString(PyExc_ValueError, "Vector must be 2D, 3D or 4D"); return NULL; } mirror[0] = tvec[0]; mirror[1] = tvec[1]; - mirror[2] = (value_size > 2) ? tvec[2] : 0.0f; + mirror[2] = (value_num > 2) ? tvec[2] : 0.0f; vec[0] = self->vec[0]; vec[1] = self->vec[1]; - vec[2] = (value_size > 2) ? self->vec[2] : 0.0f; + vec[2] = (value_num > 2) ? self->vec[2] : 0.0f; normalize_v3(mirror); reflect_v3_v3v3(reflect, vec, mirror); - return Vector_CreatePyObject(reflect, self->size, Py_TYPE(self)); + return Vector_CreatePyObject(reflect, self->vec_num, Py_TYPE(self)); } PyDoc_STRVAR(Vector_cross_doc, @@ -886,17 +886,18 @@ static PyObject *Vector_cross(VectorObject *self, PyObject *value) return NULL; } - if (self->size > 3) { + if (self->vec_num > 3) { PyErr_SetString(PyExc_ValueError, "Vector must be 2D or 3D"); return NULL; } if (mathutils_array_parse( - tvec, self->size, self->size, value, "Vector.cross(other), invalid 'other' arg") == -1) { + tvec, self->vec_num, self->vec_num, value, "Vector.cross(other), invalid 'other' arg") == + -1) { return NULL; } - if (self->size == 3) { + if (self->vec_num == 3) { ret = Vector_CreatePyObject(NULL, 3, Py_TYPE(self)); cross_v3_v3v3(((VectorObject *)ret)->vec, self->vec, tvec); } @@ -926,11 +927,11 @@ static PyObject *Vector_dot(VectorObject *self, PyObject *value) } if (mathutils_array_parse_alloc( - &tvec, self->size, value, "Vector.dot(other), invalid 'other' arg") == -1) { + &tvec, self->vec_num, value, "Vector.dot(other), invalid 'other' arg") == -1) { return NULL; } - ret = PyFloat_FromDouble(dot_vn_vn(self->vec, tvec, self->size)); + ret = PyFloat_FromDouble(dot_vn_vn(self->vec, tvec, self->vec_num)); PyMem_Free(tvec); return ret; } @@ -950,7 +951,7 @@ PyDoc_STRVAR( " :rtype: float\n"); static PyObject *Vector_angle(VectorObject *self, PyObject *args) { - const int size = MIN2(self->size, 3); /* 4D angle makes no sense */ + const int vec_num = MIN2(self->vec_num, 3); /* 4D angle makes no sense */ float tvec[MAX_DIMENSIONS]; PyObject *value; double dot = 0.0f, dot_self = 0.0f, dot_other = 0.0f; @@ -968,16 +969,17 @@ static PyObject *Vector_angle(VectorObject *self, PyObject *args) /* don't use clamped size, rule of thumb is vector sizes must match, * even though n this case 'w' is ignored */ if (mathutils_array_parse( - tvec, self->size, self->size, value, "Vector.angle(other), invalid 'other' arg") == -1) { + tvec, self->vec_num, self->vec_num, value, "Vector.angle(other), invalid 'other' arg") == + -1) { return NULL; } - if (self->size > 4) { + if (self->vec_num > 4) { PyErr_SetString(PyExc_ValueError, "Vector must be 2D, 3D or 4D"); return NULL; } - for (x = 0; x < size; x++) { + for (x = 0; x < vec_num; x++) { dot_self += (double)self->vec[x] * (double)self->vec[x]; dot_other += (double)tvec[x] * (double)tvec[x]; dot += (double)self->vec[x] * (double)tvec[x]; @@ -1032,7 +1034,7 @@ static PyObject *Vector_angle_signed(VectorObject *self, PyObject *args) return NULL; } - if (self->size != 2) { + if (self->vec_num != 2) { PyErr_SetString(PyExc_ValueError, "Vector must be 2D"); return NULL; } @@ -1069,7 +1071,7 @@ static PyObject *Vector_rotation_difference(VectorObject *self, PyObject *value) { float quat[4], vec_a[3], vec_b[3]; - if (self->size < 3 || self->size > 4) { + if (self->vec_num < 3 || self->vec_num > 4) { PyErr_SetString(PyExc_ValueError, "vec.difference(value): " "expects both vectors to be size 3 or 4"); @@ -1105,7 +1107,7 @@ PyDoc_STRVAR(Vector_project_doc, " :rtype: :class:`Vector`\n"); static PyObject *Vector_project(VectorObject *self, PyObject *value) { - const int size = self->size; + const int vec_num = self->vec_num; float *tvec; double dot = 0.0f, dot2 = 0.0f; int x; @@ -1115,21 +1117,21 @@ static PyObject *Vector_project(VectorObject *self, PyObject *value) } if (mathutils_array_parse_alloc( - &tvec, size, value, "Vector.project(other), invalid 'other' arg") == -1) { + &tvec, vec_num, value, "Vector.project(other), invalid 'other' arg") == -1) { return NULL; } /* get dot products */ - for (x = 0; x < size; x++) { + for (x = 0; x < vec_num; x++) { dot += (double)(self->vec[x] * tvec[x]); dot2 += (double)(tvec[x] * tvec[x]); } /* projection */ dot /= dot2; - for (x = 0; x < size; x++) { + for (x = 0; x < vec_num; x++) { tvec[x] *= (float)dot; } - return Vector_CreatePyObject_alloc(tvec, size, Py_TYPE(self)); + return Vector_CreatePyObject_alloc(tvec, vec_num, Py_TYPE(self)); } PyDoc_STRVAR(Vector_lerp_doc, @@ -1145,7 +1147,7 @@ PyDoc_STRVAR(Vector_lerp_doc, " :rtype: :class:`Vector`\n"); static PyObject *Vector_lerp(VectorObject *self, PyObject *args) { - const int size = self->size; + const int vec_num = self->vec_num; PyObject *value = NULL; float fac; float *tvec; @@ -1158,14 +1160,14 @@ static PyObject *Vector_lerp(VectorObject *self, PyObject *args) return NULL; } - if (mathutils_array_parse_alloc(&tvec, size, value, "Vector.lerp(other), invalid 'other' arg") == - -1) { + if (mathutils_array_parse_alloc( + &tvec, vec_num, value, "Vector.lerp(other), invalid 'other' arg") == -1) { return NULL; } - interp_vn_vn(tvec, self->vec, 1.0f - fac, size); + interp_vn_vn(tvec, self->vec, 1.0f - fac, vec_num); - return Vector_CreatePyObject_alloc(tvec, size, Py_TYPE(self)); + return Vector_CreatePyObject_alloc(tvec, vec_num, Py_TYPE(self)); } PyDoc_STRVAR(Vector_slerp_doc, @@ -1185,7 +1187,7 @@ PyDoc_STRVAR(Vector_slerp_doc, " :rtype: :class:`Vector`\n"); static PyObject *Vector_slerp(VectorObject *self, PyObject *args) { - const int size = self->size; + const int vec_num = self->vec_num; PyObject *value = NULL; float fac, cosom, w[2]; float self_vec[3], other_vec[3], ret_vec[3]; @@ -1201,18 +1203,18 @@ static PyObject *Vector_slerp(VectorObject *self, PyObject *args) return NULL; } - if (self->size > 3) { + if (self->vec_num > 3) { PyErr_SetString(PyExc_ValueError, "Vector must be 2D or 3D"); return NULL; } if (mathutils_array_parse( - other_vec, size, size, value, "Vector.slerp(other), invalid 'other' arg") == -1) { + other_vec, vec_num, vec_num, value, "Vector.slerp(other), invalid 'other' arg") == -1) { return NULL; } - self_len_sq = normalize_vn_vn(self_vec, self->vec, size); - other_len_sq = normalize_vn(other_vec, size); + self_len_sq = normalize_vn_vn(self_vec, self->vec, vec_num); + other_len_sq = normalize_vn(other_vec, vec_num); /* use fallbacks for zero length vectors */ if (UNLIKELY((self_len_sq < FLT_EPSILON) || (other_len_sq < FLT_EPSILON))) { @@ -1229,7 +1231,7 @@ static PyObject *Vector_slerp(VectorObject *self, PyObject *args) } /* We have sane state, execute slerp */ - cosom = (float)dot_vn_vn(self_vec, other_vec, size); + cosom = (float)dot_vn_vn(self_vec, other_vec, vec_num); /* direct opposite, can't slerp */ if (UNLIKELY(cosom < (-1.0f + FLT_EPSILON))) { @@ -1247,11 +1249,11 @@ static PyObject *Vector_slerp(VectorObject *self, PyObject *args) interp_dot_slerp(fac, cosom, w); - for (x = 0; x < size; x++) { + for (x = 0; x < vec_num; x++) { ret_vec[x] = (w[0] * self_vec[x]) + (w[1] * other_vec[x]); } - return Vector_CreatePyObject(ret_vec, size, Py_TYPE(self)); + return Vector_CreatePyObject(ret_vec, vec_num, Py_TYPE(self)); } PyDoc_STRVAR( @@ -1270,7 +1272,7 @@ static PyObject *Vector_rotate(VectorObject *self, PyObject *value) return NULL; } - if (self->size == 2) { + if (self->vec_num == 2) { /* Special case for 2D Vector with 2x2 matrix, so we avoid resizing it to a 3x3. */ float other_rmat[2][2]; MatrixObject *pymat; @@ -1311,7 +1313,7 @@ static PyObject *Vector_copy(VectorObject *self) return NULL; } - return Vector_CreatePyObject(self->vec, self->size, Py_TYPE(self)); + return Vector_CreatePyObject(self->vec, self->vec_num, Py_TYPE(self)); } static PyObject *Vector_deepcopy(VectorObject *self, PyObject *args) { @@ -1350,7 +1352,7 @@ static PyObject *Vector_str(VectorObject *self) BLI_dynstr_append(ds, "<Vector ("); - for (i = 0; i < self->size; i++) { + for (i = 0; i < self->vec_num; i++) { BLI_dynstr_appendf(ds, i ? ", %.4f" : "%.4f", self->vec[i]); } @@ -1364,21 +1366,21 @@ static PyObject *Vector_str(VectorObject *self) /* sequence length len(vector) */ static int Vector_len(VectorObject *self) { - return self->size; + return self->vec_num; } /* sequence accessor (get): vector[index] */ static PyObject *vector_item_internal(VectorObject *self, int i, const bool is_attr) { if (i < 0) { - i = self->size - i; + i = self->vec_num - i; } - if (i < 0 || i >= self->size) { + if (i < 0 || i >= self->vec_num) { if (is_attr) { PyErr_Format(PyExc_AttributeError, "Vector.%c: unavailable on %dd vector", *(((const char *)"xyzw") + i), - self->size); + self->vec_num); } else { PyErr_SetString(PyExc_IndexError, "vector[index]: out of range"); @@ -1415,15 +1417,15 @@ static int vector_ass_item_internal(VectorObject *self, int i, PyObject *value, } if (i < 0) { - i = self->size - i; + i = self->vec_num - i; } - if (i < 0 || i >= self->size) { + if (i < 0 || i >= self->vec_num) { if (is_attr) { PyErr_Format(PyExc_AttributeError, "Vector.%c = x: unavailable on %dd vector", *(((const char *)"xyzw") + i), - self->size); + self->vec_num); } else { PyErr_SetString(PyExc_IndexError, @@ -1455,11 +1457,11 @@ static PyObject *Vector_slice(VectorObject *self, int begin, int end) return NULL; } - CLAMP(begin, 0, self->size); + CLAMP(begin, 0, self->vec_num); if (end < 0) { - end = self->size + end + 1; + end = self->vec_num + end + 1; } - CLAMP(end, 0, self->size); + CLAMP(end, 0, self->vec_num); begin = MIN2(begin, end); tuple = PyTuple_New(end - begin); @@ -1472,19 +1474,19 @@ static PyObject *Vector_slice(VectorObject *self, int begin, int end) /* sequence slice (set): vector[a:b] = value */ static int Vector_ass_slice(VectorObject *self, int begin, int end, PyObject *seq) { - int size = 0; + int vec_num = 0; float *vec = NULL; if (BaseMath_ReadCallback_ForWrite(self) == -1) { return -1; } - CLAMP(begin, 0, self->size); - CLAMP(end, 0, self->size); + CLAMP(begin, 0, self->vec_num); + CLAMP(end, 0, self->vec_num); begin = MIN2(begin, end); - size = (end - begin); - if (mathutils_array_parse_alloc(&vec, size, seq, "vector[begin:end] = [...]") == -1) { + vec_num = (end - begin); + if (mathutils_array_parse_alloc(&vec, vec_num, seq, "vector[begin:end] = [...]") == -1) { return -1; } @@ -1496,7 +1498,7 @@ static int Vector_ass_slice(VectorObject *self, int begin, int end, PyObject *se } /* Parsed well - now set in vector. */ - memcpy(self->vec + begin, vec, size * sizeof(float)); + memcpy(self->vec + begin, vec, vec_num * sizeof(float)); PyMem_Free(vec); @@ -1530,14 +1532,14 @@ static PyObject *Vector_add(PyObject *v1, PyObject *v2) } /* VECTOR + VECTOR. */ - if (vec1->size != vec2->size) { + if (vec1->vec_num != vec2->vec_num) { PyErr_SetString(PyExc_AttributeError, "Vector addition: " "vectors must have the same dimensions for this operation"); return NULL; } - vec = PyMem_Malloc(vec1->size * sizeof(float)); + vec = PyMem_Malloc(vec1->vec_num * sizeof(float)); if (vec == NULL) { PyErr_SetString(PyExc_MemoryError, "Vector(): " @@ -1545,9 +1547,9 @@ static PyObject *Vector_add(PyObject *v1, PyObject *v2) return NULL; } - add_vn_vnvn(vec, vec1->vec, vec2->vec, vec1->size); + add_vn_vnvn(vec, vec1->vec, vec2->vec, vec1->vec_num); - return Vector_CreatePyObject_alloc(vec, vec1->size, Py_TYPE(v1)); + return Vector_CreatePyObject_alloc(vec, vec1->vec_num, Py_TYPE(v1)); } /* addition in-place: obj += obj */ @@ -1566,7 +1568,7 @@ static PyObject *Vector_iadd(PyObject *v1, PyObject *v2) vec1 = (VectorObject *)v1; vec2 = (VectorObject *)v2; - if (vec1->size != vec2->size) { + if (vec1->vec_num != vec2->vec_num) { PyErr_SetString(PyExc_AttributeError, "Vector addition: " "vectors must have the same dimensions for this operation"); @@ -1577,7 +1579,7 @@ static PyObject *Vector_iadd(PyObject *v1, PyObject *v2) return NULL; } - add_vn_vn(vec1->vec, vec2->vec, vec1->size); + add_vn_vn(vec1->vec, vec2->vec, vec1->vec_num); (void)BaseMath_WriteCallback(vec1); Py_INCREF(v1); @@ -1605,14 +1607,14 @@ static PyObject *Vector_sub(PyObject *v1, PyObject *v2) return NULL; } - if (vec1->size != vec2->size) { + if (vec1->vec_num != vec2->vec_num) { PyErr_SetString(PyExc_AttributeError, "Vector subtraction: " "vectors must have the same dimensions for this operation"); return NULL; } - vec = PyMem_Malloc(vec1->size * sizeof(float)); + vec = PyMem_Malloc(vec1->vec_num * sizeof(float)); if (vec == NULL) { PyErr_SetString(PyExc_MemoryError, "Vector(): " @@ -1620,9 +1622,9 @@ static PyObject *Vector_sub(PyObject *v1, PyObject *v2) return NULL; } - sub_vn_vnvn(vec, vec1->vec, vec2->vec, vec1->size); + sub_vn_vnvn(vec, vec1->vec, vec2->vec, vec1->vec_num); - return Vector_CreatePyObject_alloc(vec, vec1->size, Py_TYPE(v1)); + return Vector_CreatePyObject_alloc(vec, vec1->vec_num, Py_TYPE(v1)); } /* subtraction in-place: obj -= obj */ @@ -1641,7 +1643,7 @@ static PyObject *Vector_isub(PyObject *v1, PyObject *v2) vec1 = (VectorObject *)v1; vec2 = (VectorObject *)v2; - if (vec1->size != vec2->size) { + if (vec1->vec_num != vec2->vec_num) { PyErr_SetString(PyExc_AttributeError, "Vector subtraction: " "vectors must have the same dimensions for this operation"); @@ -1652,7 +1654,7 @@ static PyObject *Vector_isub(PyObject *v1, PyObject *v2) return NULL; } - sub_vn_vn(vec1->vec, vec2->vec, vec1->size); + sub_vn_vn(vec1->vec, vec2->vec, vec1->vec_num); (void)BaseMath_WriteCallback(vec1); Py_INCREF(v1); @@ -1667,8 +1669,8 @@ int column_vector_multiplication(float r_vec[MAX_DIMENSIONS], VectorObject *vec, float vec_cpy[MAX_DIMENSIONS]; int row, col, z = 0; - if (mat->num_col != vec->size) { - if (mat->num_col == 4 && vec->size == 3) { + if (mat->col_num != vec->vec_num) { + if (mat->col_num == 4 && vec->vec_num == 3) { vec_cpy[3] = 1.0f; } else { @@ -1680,13 +1682,13 @@ int column_vector_multiplication(float r_vec[MAX_DIMENSIONS], VectorObject *vec, } } - memcpy(vec_cpy, vec->vec, vec->size * sizeof(float)); + memcpy(vec_cpy, vec->vec, vec->vec_num * sizeof(float)); r_vec[3] = 1.0f; - for (row = 0; row < mat->num_row; row++) { + for (row = 0; row < mat->row_num; row++) { double dot = 0.0f; - for (col = 0; col < mat->num_col; col++) { + for (col = 0; col < mat->col_num; col++) { dot += (double)(MATRIX_ITEM(mat, row, col) * vec_cpy[col]); } r_vec[z++] = (float)dot; @@ -1697,7 +1699,7 @@ int column_vector_multiplication(float r_vec[MAX_DIMENSIONS], VectorObject *vec, static PyObject *vector_mul_float(VectorObject *vec, const float scalar) { - float *tvec = PyMem_Malloc(vec->size * sizeof(float)); + float *tvec = PyMem_Malloc(vec->vec_num * sizeof(float)); if (tvec == NULL) { PyErr_SetString(PyExc_MemoryError, "vec * float: " @@ -1705,13 +1707,13 @@ static PyObject *vector_mul_float(VectorObject *vec, const float scalar) return NULL; } - mul_vn_vn_fl(tvec, vec->vec, vec->size, scalar); - return Vector_CreatePyObject_alloc(tvec, vec->size, Py_TYPE(vec)); + mul_vn_vn_fl(tvec, vec->vec, vec->vec_num, scalar); + return Vector_CreatePyObject_alloc(tvec, vec->vec_num, Py_TYPE(vec)); } static PyObject *vector_mul_vec(VectorObject *vec1, VectorObject *vec2) { - float *tvec = PyMem_Malloc(vec1->size * sizeof(float)); + float *tvec = PyMem_Malloc(vec1->vec_num * sizeof(float)); if (tvec == NULL) { PyErr_SetString(PyExc_MemoryError, "vec * vec: " @@ -1719,8 +1721,8 @@ static PyObject *vector_mul_vec(VectorObject *vec1, VectorObject *vec2) return NULL; } - mul_vn_vnvn(tvec, vec1->vec, vec2->vec, vec1->size); - return Vector_CreatePyObject_alloc(tvec, vec1->size, Py_TYPE(vec1)); + mul_vn_vnvn(tvec, vec1->vec, vec2->vec, vec1->vec_num); + return Vector_CreatePyObject_alloc(tvec, vec1->vec_num, Py_TYPE(vec1)); } static PyObject *Vector_mul(PyObject *v1, PyObject *v2) @@ -1745,7 +1747,7 @@ static PyObject *Vector_mul(PyObject *v1, PyObject *v2) /* make sure v1 is always the vector */ if (vec1 && vec2) { - if (vec1->size != vec2->size) { + if (vec1->vec_num != vec2->vec_num) { PyErr_SetString(PyExc_ValueError, "Vector multiplication: " "vectors must have the same dimensions for this operation"); @@ -1800,7 +1802,7 @@ static PyObject *Vector_imul(PyObject *v1, PyObject *v2) /* Intentionally don't support (Quaternion, Matrix) here, uses reverse order instead. */ if (vec1 && vec2) { - if (vec1->size != vec2->size) { + if (vec1->vec_num != vec2->vec_num) { PyErr_SetString(PyExc_ValueError, "Vector multiplication: " "vectors must have the same dimensions for this operation"); @@ -1808,11 +1810,11 @@ static PyObject *Vector_imul(PyObject *v1, PyObject *v2) } /* Element-wise product in-place. */ - mul_vn_vn(vec1->vec, vec2->vec, vec1->size); + mul_vn_vn(vec1->vec, vec2->vec, vec1->vec_num); } else if (vec1 && (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0)) { /* VEC *= FLOAT */ - mul_vn_fl(vec1->vec, vec1->size, scalar); + mul_vn_fl(vec1->vec, vec1->vec_num, scalar); } else { PyErr_Format(PyExc_TypeError, @@ -1831,7 +1833,7 @@ static PyObject *Vector_imul(PyObject *v1, PyObject *v2) static PyObject *Vector_matmul(PyObject *v1, PyObject *v2) { VectorObject *vec1 = NULL, *vec2 = NULL; - int vec_size; + int vec_num; if (VectorObject_Check(v1)) { vec1 = (VectorObject *)v1; @@ -1850,7 +1852,7 @@ static PyObject *Vector_matmul(PyObject *v1, PyObject *v2) /* make sure v1 is always the vector */ if (vec1 && vec2) { - if (vec1->size != vec2->size) { + if (vec1->vec_num != vec2->vec_num) { PyErr_SetString(PyExc_ValueError, "Vector multiplication: " "vectors must have the same dimensions for this operation"); @@ -1858,7 +1860,7 @@ static PyObject *Vector_matmul(PyObject *v1, PyObject *v2) } /* Dot product. */ - return PyFloat_FromDouble(dot_vn_vn(vec1->vec, vec2->vec, vec1->size)); + return PyFloat_FromDouble(dot_vn_vn(vec1->vec, vec2->vec, vec1->vec_num)); } if (vec1) { if (MatrixObject_Check(v2)) { @@ -1872,14 +1874,14 @@ static PyObject *Vector_matmul(PyObject *v1, PyObject *v2) return NULL; } - if (((MatrixObject *)v2)->num_row == 4 && vec1->size == 3) { - vec_size = 3; + if (((MatrixObject *)v2)->row_num == 4 && vec1->vec_num == 3) { + vec_num = 3; } else { - vec_size = ((MatrixObject *)v2)->num_col; + vec_num = ((MatrixObject *)v2)->col_num; } - return Vector_CreatePyObject(tvec, vec_size, Py_TYPE(vec1)); + return Vector_CreatePyObject(tvec, vec_num, Py_TYPE(vec1)); } } @@ -1934,7 +1936,7 @@ static PyObject *Vector_div(PyObject *v1, PyObject *v2) return NULL; } - vec = PyMem_Malloc(vec1->size * sizeof(float)); + vec = PyMem_Malloc(vec1->vec_num * sizeof(float)); if (vec == NULL) { PyErr_SetString(PyExc_MemoryError, @@ -1943,9 +1945,9 @@ static PyObject *Vector_div(PyObject *v1, PyObject *v2) return NULL; } - mul_vn_vn_fl(vec, vec1->vec, vec1->size, 1.0f / scalar); + mul_vn_vn_fl(vec, vec1->vec, vec1->vec_num, 1.0f / scalar); - return Vector_CreatePyObject_alloc(vec, vec1->size, Py_TYPE(v1)); + return Vector_CreatePyObject_alloc(vec, vec1->vec_num, Py_TYPE(v1)); } /* divide in-place: obj /= obj */ @@ -1973,7 +1975,7 @@ static PyObject *Vector_idiv(PyObject *v1, PyObject *v2) return NULL; } - mul_vn_fl(vec1->vec, vec1->size, 1.0f / scalar); + mul_vn_fl(vec1->vec, vec1->vec_num, 1.0f / scalar); (void)BaseMath_WriteCallback(vec1); @@ -1991,9 +1993,9 @@ static PyObject *Vector_neg(VectorObject *self) return NULL; } - tvec = PyMem_Malloc(self->size * sizeof(float)); - negate_vn_vn(tvec, self->vec, self->size); - return Vector_CreatePyObject_alloc(tvec, self->size, Py_TYPE(self)); + tvec = PyMem_Malloc(self->vec_num * sizeof(float)); + negate_vn_vn(tvec, self->vec, self->vec_num); + return Vector_CreatePyObject_alloc(tvec, self->vec_num, Py_TYPE(self)); } /*------------------------tp_richcmpr @@ -2019,7 +2021,7 @@ static PyObject *Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa return NULL; } - if (vecA->size != vecB->size) { + if (vecA->vec_num != vecB->vec_num) { if (comparison_type == Py_NE) { Py_RETURN_TRUE; } @@ -2029,15 +2031,15 @@ static PyObject *Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa switch (comparison_type) { case Py_LT: - lenA = len_squared_vn(vecA->vec, vecA->size); - lenB = len_squared_vn(vecB->vec, vecB->size); + lenA = len_squared_vn(vecA->vec, vecA->vec_num); + lenB = len_squared_vn(vecB->vec, vecB->vec_num); if (lenA < lenB) { result = 1; } break; case Py_LE: - lenA = len_squared_vn(vecA->vec, vecA->size); - lenB = len_squared_vn(vecB->vec, vecB->size); + lenA = len_squared_vn(vecA->vec, vecA->vec_num); + lenB = len_squared_vn(vecB->vec, vecB->vec_num); if (lenA < lenB) { result = 1; } @@ -2046,21 +2048,21 @@ static PyObject *Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa } break; case Py_EQ: - result = EXPP_VectorsAreEqual(vecA->vec, vecB->vec, vecA->size, 1); + result = EXPP_VectorsAreEqual(vecA->vec, vecB->vec, vecA->vec_num, 1); break; case Py_NE: - result = !EXPP_VectorsAreEqual(vecA->vec, vecB->vec, vecA->size, 1); + result = !EXPP_VectorsAreEqual(vecA->vec, vecB->vec, vecA->vec_num, 1); break; case Py_GT: - lenA = len_squared_vn(vecA->vec, vecA->size); - lenB = len_squared_vn(vecB->vec, vecB->size); + lenA = len_squared_vn(vecA->vec, vecA->vec_num); + lenB = len_squared_vn(vecB->vec, vecB->vec_num); if (lenA > lenB) { result = 1; } break; case Py_GE: - lenA = len_squared_vn(vecA->vec, vecA->size); - lenB = len_squared_vn(vecB->vec, vecB->size); + lenA = len_squared_vn(vecA->vec, vecA->vec_num); + lenB = len_squared_vn(vecB->vec, vecB->vec_num); if (lenA > lenB) { result = 1; } @@ -2089,7 +2091,7 @@ static Py_hash_t Vector_hash(VectorObject *self) return -1; } - return mathutils_array_hash(self->vec, self->size); + return mathutils_array_hash(self->vec, self->vec_num); } /*-----------------PROTCOL DECLARATIONS--------------------------*/ @@ -2115,14 +2117,14 @@ static PyObject *Vector_subscript(VectorObject *self, PyObject *item) return NULL; } if (i < 0) { - i += self->size; + i += self->vec_num; } return Vector_item(self, i); } if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; - if (PySlice_GetIndicesEx(item, self->size, &start, &stop, &step, &slicelength) < 0) { + if (PySlice_GetIndicesEx(item, self->vec_num, &start, &stop, &step, &slicelength) < 0) { return NULL; } @@ -2150,14 +2152,14 @@ static int Vector_ass_subscript(VectorObject *self, PyObject *item, PyObject *va return -1; } if (i < 0) { - i += self->size; + i += self->vec_num; } return Vector_ass_item(self, i, value); } if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; - if (PySlice_GetIndicesEx(item, self->size, &start, &stop, &step, &slicelength) < 0) { + if (PySlice_GetIndicesEx(item, self->vec_num, &start, &stop, &step, &slicelength) < 0) { return -1; } @@ -2247,7 +2249,7 @@ static PyObject *Vector_length_get(VectorObject *self, void *UNUSED(closure)) return NULL; } - return PyFloat_FromDouble(sqrt(dot_vn_vn(self->vec, self->vec, self->size))); + return PyFloat_FromDouble(sqrt(dot_vn_vn(self->vec, self->vec, self->vec_num))); } static int Vector_length_set(VectorObject *self, PyObject *value) @@ -2268,11 +2270,11 @@ static int Vector_length_set(VectorObject *self, PyObject *value) return -1; } if (param == 0.0) { - copy_vn_fl(self->vec, self->size, 0.0f); + copy_vn_fl(self->vec, self->vec_num, 0.0f); return 0; } - dot = dot_vn_vn(self->vec, self->vec, self->size); + dot = dot_vn_vn(self->vec, self->vec, self->vec_num); if (!dot) { /* can't sqrt zero */ @@ -2287,7 +2289,7 @@ static int Vector_length_set(VectorObject *self, PyObject *value) dot = dot / param; - mul_vn_fl(self->vec, self->size, 1.0 / dot); + mul_vn_fl(self->vec, self->vec_num, 1.0 / dot); (void)BaseMath_WriteCallback(self); /* checked already */ @@ -2302,7 +2304,7 @@ static PyObject *Vector_length_squared_get(VectorObject *self, void *UNUSED(clos return NULL; } - return PyFloat_FromDouble(dot_vn_vn(self->vec, self->vec, self->size)); + return PyFloat_FromDouble(dot_vn_vn(self->vec, self->vec, self->vec_num)); } /** @@ -2382,7 +2384,7 @@ static PyObject *Vector_swizzle_get(VectorObject *self, void *closure) swizzleClosure = POINTER_AS_INT(closure); while (swizzleClosure & SWIZZLE_VALID_AXIS) { axis_from = swizzleClosure & SWIZZLE_AXIS; - if (axis_from >= self->size) { + if (axis_from >= self->vec_num) { PyErr_SetString(PyExc_AttributeError, "Vector swizzle: " "specified axis not present"); @@ -2432,7 +2434,7 @@ static int Vector_swizzle_set(VectorObject *self, PyObject *value, void *closure while (swizzleClosure & SWIZZLE_VALID_AXIS) { axis_to = swizzleClosure & SWIZZLE_AXIS; - if (axis_to >= self->size) { + if (axis_to >= self->vec_num) { PyErr_SetString(PyExc_AttributeError, "Vector swizzle: " "specified axis not present"); @@ -2468,8 +2470,8 @@ static int Vector_swizzle_set(VectorObject *self, PyObject *value, void *closure /* We must first copy current vec into tvec, else some org values may be lost. * See T31760. - * Assuming self->size can't be higher than MAX_DIMENSIONS! */ - memcpy(tvec, self->vec, self->size * sizeof(float)); + * Assuming self->vec_num can't be higher than MAX_DIMENSIONS! */ + memcpy(tvec, self->vec, self->vec_num * sizeof(float)); while (swizzleClosure & SWIZZLE_VALID_AXIS) { axis_to = swizzleClosure & SWIZZLE_AXIS; @@ -2480,7 +2482,7 @@ static int Vector_swizzle_set(VectorObject *self, PyObject *value, void *closure /* We must copy back the whole tvec into vec, else some changes may be lost (e.g. xz...). * See T31760. */ - memcpy(self->vec, tvec, self->size * sizeof(float)); + memcpy(self->vec, tvec, self->vec_num * sizeof(float)); /* continue with BaseMathObject_WriteCallback at the end */ if (BaseMath_WriteCallback(self) == -1) { @@ -2898,10 +2900,10 @@ static int row_vector_multiplication(float r_vec[MAX_DIMENSIONS], MatrixObject *mat) { float vec_cpy[MAX_DIMENSIONS]; - int row, col, z = 0, vec_size = vec->size; + int row, col, z = 0, vec_num = vec->vec_num; - if (mat->num_row != vec_size) { - if (mat->num_row == 4 && vec_size == 3) { + if (mat->row_num != vec_num) { + if (mat->row_num == 4 && vec_num == 3) { vec_cpy[3] = 1.0f; } else { @@ -2916,13 +2918,13 @@ static int row_vector_multiplication(float r_vec[MAX_DIMENSIONS], return -1; } - memcpy(vec_cpy, vec->vec, vec_size * sizeof(float)); + memcpy(vec_cpy, vec->vec, vec_num * sizeof(float)); r_vec[3] = 1.0f; /* Multiplication. */ - for (col = 0; col < mat->num_col; col++) { + for (col = 0; col < mat->col_num; col++) { double dot = 0.0; - for (row = 0; row < mat->num_row; row++) { + for (row = 0; row < mat->row_num; row++) { dot += (double)(MATRIX_ITEM(mat, row, col) * vec_cpy[row]); } r_vec[z++] = (float)dot; @@ -2941,7 +2943,7 @@ static PyObject *Vector_negate(VectorObject *self) return NULL; } - negate_vn(self->vec, self->size); + negate_vn(self->vec, self->vec_num); (void)BaseMath_WriteCallback(self); /* already checked for error */ Py_RETURN_NONE; @@ -3096,17 +3098,17 @@ PyTypeObject vector_Type = { NULL, }; -PyObject *Vector_CreatePyObject(const float *vec, const int size, PyTypeObject *base_type) +PyObject *Vector_CreatePyObject(const float *vec, const int vec_num, PyTypeObject *base_type) { VectorObject *self; float *vec_alloc; - if (size < 2) { + if (vec_num < 2) { PyErr_SetString(PyExc_RuntimeError, "Vector(): invalid size"); return NULL; } - vec_alloc = PyMem_Malloc(size * sizeof(float)); + vec_alloc = PyMem_Malloc(vec_num * sizeof(float)); if (UNLIKELY(vec_alloc == NULL)) { PyErr_SetString(PyExc_MemoryError, "Vector(): " @@ -3117,18 +3119,18 @@ PyObject *Vector_CreatePyObject(const float *vec, const int size, PyTypeObject * self = BASE_MATH_NEW(VectorObject, vector_Type, base_type); if (self) { self->vec = vec_alloc; - self->size = size; + self->vec_num = vec_num; /* init callbacks as NULL */ self->cb_user = NULL; self->cb_type = self->cb_subtype = 0; if (vec) { - memcpy(self->vec, vec, size * sizeof(float)); + memcpy(self->vec, vec, vec_num * sizeof(float)); } else { /* new empty */ - copy_vn_fl(self->vec, size, 0.0f); - if (size == 4) { /* do the homogeneous thing */ + copy_vn_fl(self->vec, vec_num, 0.0f); + if (vec_num == 4) { /* do the homogeneous thing */ self->vec[3] = 1.0f; } } @@ -3141,18 +3143,18 @@ PyObject *Vector_CreatePyObject(const float *vec, const int size, PyTypeObject * return (PyObject *)self; } -PyObject *Vector_CreatePyObject_wrap(float *vec, const int size, PyTypeObject *base_type) +PyObject *Vector_CreatePyObject_wrap(float *vec, const int vec_num, PyTypeObject *base_type) { VectorObject *self; - if (size < 2) { + if (vec_num < 2) { PyErr_SetString(PyExc_RuntimeError, "Vector(): invalid size"); return NULL; } self = BASE_MATH_NEW(VectorObject, vector_Type, base_type); if (self) { - self->size = size; + self->vec_num = vec_num; /* init callbacks as NULL */ self->cb_user = NULL; @@ -3164,9 +3166,9 @@ PyObject *Vector_CreatePyObject_wrap(float *vec, const int size, PyTypeObject *b return (PyObject *)self; } -PyObject *Vector_CreatePyObject_cb(PyObject *cb_user, int size, uchar cb_type, uchar cb_subtype) +PyObject *Vector_CreatePyObject_cb(PyObject *cb_user, int vec_num, uchar cb_type, uchar cb_subtype) { - VectorObject *self = (VectorObject *)Vector_CreatePyObject(NULL, size, NULL); + VectorObject *self = (VectorObject *)Vector_CreatePyObject(NULL, vec_num, NULL); if (self) { Py_INCREF(cb_user); self->cb_user = cb_user; @@ -3178,10 +3180,10 @@ PyObject *Vector_CreatePyObject_cb(PyObject *cb_user, int size, uchar cb_type, u return (PyObject *)self; } -PyObject *Vector_CreatePyObject_alloc(float *vec, const int size, PyTypeObject *base_type) +PyObject *Vector_CreatePyObject_alloc(float *vec, const int vec_num, PyTypeObject *base_type) { VectorObject *self; - self = (VectorObject *)Vector_CreatePyObject_wrap(vec, size, base_type); + self = (VectorObject *)Vector_CreatePyObject_wrap(vec, vec_num, base_type); if (self) { self->flag &= ~BASE_MATH_FLAG_IS_WRAP; } diff --git a/source/blender/python/mathutils/mathutils_Vector.h b/source/blender/python/mathutils/mathutils_Vector.h index 422050c8742..3bc4e9d6b6f 100644 --- a/source/blender/python/mathutils/mathutils_Vector.h +++ b/source/blender/python/mathutils/mathutils_Vector.h @@ -14,12 +14,13 @@ extern PyTypeObject vector_Type; typedef struct { BASE_MATH_MEMBERS(vec); - int size; /* vec size 2 or more */ + /** Number of items in this vector (2 or more). */ + int vec_num; } VectorObject; /*prototypes*/ PyObject *Vector_CreatePyObject(const float *vec, - int size, + int vec_num, PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT; /** * Create a vector that wraps existing memory. @@ -27,7 +28,7 @@ PyObject *Vector_CreatePyObject(const float *vec, * \param vec: Use this vector in-place. */ PyObject *Vector_CreatePyObject_wrap(float *vec, - int size, + int vec_num, PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); /** @@ -35,13 +36,13 @@ PyObject *Vector_CreatePyObject_wrap(float *vec, * see: #Mathutils_RegisterCallback */ PyObject *Vector_CreatePyObject_cb(PyObject *user, - int size, + int vec_num, unsigned char cb_type, unsigned char subtype) ATTR_WARN_UNUSED_RESULT; /** * \param vec: Initialized vector value to use in-place, allocated with #PyMem_Malloc */ PyObject *Vector_CreatePyObject_alloc(float *vec, - int size, + int vec_num, PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c index 84ba2ce4031..1e492574903 100644 --- a/source/blender/python/mathutils/mathutils_geometry.c +++ b/source/blender/python/mathutils/mathutils_geometry.c @@ -158,24 +158,30 @@ static PyObject *M_Geometry_intersect_line_line(PyObject *UNUSED(self), PyObject PyObject *tuple; PyObject *py_lines[4]; float lines[4][3], i1[3], i2[3]; - int len; + int ix_vec_num; int result; if (!PyArg_ParseTuple(args, "OOOO:intersect_line_line", UNPACK4_EX(&, py_lines, ))) { return NULL; } - if ((((len = mathutils_array_parse( + if ((((ix_vec_num = mathutils_array_parse( lines[0], 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_lines[0], error_prefix)) != -1) && - (mathutils_array_parse( - lines[1], len, len | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_lines[1], error_prefix) != - -1) && - (mathutils_array_parse( - lines[2], len, len | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_lines[2], error_prefix) != - -1) && - (mathutils_array_parse( - lines[3], len, len | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_lines[3], error_prefix) != - -1)) == 0) { + (mathutils_array_parse(lines[1], + ix_vec_num, + ix_vec_num | MU_ARRAY_SPILL | MU_ARRAY_ZERO, + py_lines[1], + error_prefix) != -1) && + (mathutils_array_parse(lines[2], + ix_vec_num, + ix_vec_num | MU_ARRAY_SPILL | MU_ARRAY_ZERO, + py_lines[2], + error_prefix) != -1) && + (mathutils_array_parse(lines[3], + ix_vec_num, + ix_vec_num | MU_ARRAY_SPILL | MU_ARRAY_ZERO, + py_lines[3], + error_prefix) != -1)) == 0) { return NULL; } @@ -192,8 +198,9 @@ static PyObject *M_Geometry_intersect_line_line(PyObject *UNUSED(self), PyObject } tuple = PyTuple_New(2); - PyTuple_SET_ITEMS( - tuple, Vector_CreatePyObject(i1, len, NULL), Vector_CreatePyObject(i2, len, NULL)); + PyTuple_SET_ITEMS(tuple, + Vector_CreatePyObject(i1, ix_vec_num, NULL), + Vector_CreatePyObject(i2, ix_vec_num, NULL)); return tuple; } @@ -764,14 +771,14 @@ static PyObject *M_Geometry_intersect_point_line(PyObject *UNUSED(self), PyObjec float pt[3], pt_out[3], line_a[3], line_b[3]; float lambda; PyObject *ret; - int size = 2; + int pt_num = 2; if (!PyArg_ParseTuple(args, "OOO:intersect_point_line", &py_pt, &py_line_a, &py_line_b)) { return NULL; } /* accept 2d verts */ - if ((((size = mathutils_array_parse( + if ((((pt_num = mathutils_array_parse( pt, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_pt, error_prefix)) != -1) && (mathutils_array_parse( line_a, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_line_a, error_prefix) != -1) && @@ -784,7 +791,7 @@ static PyObject *M_Geometry_intersect_point_line(PyObject *UNUSED(self), PyObjec lambda = closest_to_line_v3(pt_out, pt, line_a, line_b); ret = PyTuple_New(2); - PyTuple_SET_ITEMS(ret, Vector_CreatePyObject(pt_out, size, NULL), PyFloat_FromDouble(lambda)); + PyTuple_SET_ITEMS(ret, Vector_CreatePyObject(pt_out, pt_num, NULL), PyFloat_FromDouble(lambda)); return ret; } diff --git a/source/blender/python/mathutils/mathutils_noise.c b/source/blender/python/mathutils/mathutils_noise.c index 0853c5dd3ea..e1282e90c48 100644 --- a/source/blender/python/mathutils/mathutils_noise.c +++ b/source/blender/python/mathutils/mathutils_noise.c @@ -305,23 +305,24 @@ static PyObject *M_Noise_random_unit_vector(PyObject *UNUSED(self), PyObject *ar static const char *kwlist[] = {"size", NULL}; float vec[4] = {0.0f, 0.0f, 0.0f, 0.0f}; float norm = 2.0f; - int size = 3; + int vec_num = 3; - if (!PyArg_ParseTupleAndKeywords(args, kw, "|$i:random_unit_vector", (char **)kwlist, &size)) { + if (!PyArg_ParseTupleAndKeywords( + args, kw, "|$i:random_unit_vector", (char **)kwlist, &vec_num)) { return NULL; } - if (size > 4 || size < 2) { + if (vec_num > 4 || vec_num < 2) { PyErr_SetString(PyExc_ValueError, "Vector(): invalid size"); return NULL; } while (norm == 0.0f || norm > 1.0f) { - rand_vn(vec, size); - norm = normalize_vn(vec, size); + rand_vn(vec, vec_num); + norm = normalize_vn(vec, vec_num); } - return Vector_CreatePyObject(vec, size, NULL); + return Vector_CreatePyObject(vec, vec_num, NULL); } PyDoc_STRVAR(M_Noise_random_vector_doc, @@ -337,22 +338,22 @@ static PyObject *M_Noise_random_vector(PyObject *UNUSED(self), PyObject *args, P { static const char *kwlist[] = {"size", NULL}; float *vec = NULL; - int size = 3; + int vec_num = 3; - if (!PyArg_ParseTupleAndKeywords(args, kw, "|$i:random_vector", (char **)kwlist, &size)) { + if (!PyArg_ParseTupleAndKeywords(args, kw, "|$i:random_vector", (char **)kwlist, &vec_num)) { return NULL; } - if (size < 2) { + if (vec_num < 2) { PyErr_SetString(PyExc_ValueError, "Vector(): invalid size"); return NULL; } - vec = PyMem_New(float, size); + vec = PyMem_New(float, vec_num); - rand_vn(vec, size); + rand_vn(vec, vec_num); - return Vector_CreatePyObject_alloc(vec, size, NULL); + return Vector_CreatePyObject_alloc(vec, vec_num, NULL); } PyDoc_STRVAR(M_Noise_seed_set_doc, diff --git a/source/blender/render/RE_bake.h b/source/blender/render/RE_bake.h index 6d849757166..3a4a3e6dcb9 100644 --- a/source/blender/render/RE_bake.h +++ b/source/blender/render/RE_bake.h @@ -27,16 +27,16 @@ typedef struct BakeImage { typedef struct BakeTargets { /* All images of the object. */ BakeImage *images; - int num_images; + int images_num; /* Lookup table from Material number to BakeImage. */ int *material_to_image; - int num_materials; + int materials_num; /* Pixel buffer to bake to. */ float *result; - int num_pixels; - int num_channels; + int pixels_num; + int channels_num; /* Baking to non-color data image. */ bool is_noncolor; @@ -81,7 +81,7 @@ bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low, BakePixel pixel_array_to[], BakeHighPolyData highpoly[], int tot_highpoly, - size_t num_pixels, + size_t pixels_num, bool is_custom_cage, float cage_extrusion, float max_ray_distance, @@ -91,11 +91,11 @@ bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low, void RE_bake_pixels_populate(struct Mesh *me, struct BakePixel *pixel_array, - size_t num_pixels, + size_t pixels_num, const struct BakeTargets *targets, const char *uv_layer); -void RE_bake_mask_fill(const BakePixel pixel_array[], size_t num_pixels, char *mask); +void RE_bake_mask_fill(const BakePixel pixel_array[], size_t pixels_num, char *mask); void RE_bake_margin(struct ImBuf *ibuf, char *mask, @@ -105,7 +105,7 @@ void RE_bake_margin(struct ImBuf *ibuf, char const *uv_layer); void RE_bake_normal_world_to_object(const BakePixel pixel_array[], - size_t num_pixels, + size_t pixels_num, int depth, float result[], struct Object *ob, @@ -115,14 +115,14 @@ void RE_bake_normal_world_to_object(const BakePixel pixel_array[], * to a tangent space normal map for a given low poly mesh. */ void RE_bake_normal_world_to_tangent(const BakePixel pixel_array[], - size_t num_pixels, + size_t pixels_num, int depth, float result[], struct Mesh *me, const eBakeNormalSwizzle normal_swizzle[3], float mat[4][4]); void RE_bake_normal_world_to_world(const BakePixel pixel_array[], - size_t num_pixels, + size_t pixels_num, int depth, float result[], const eBakeNormalSwizzle normal_swizzle[3]); diff --git a/source/blender/render/RE_engine.h b/source/blender/render/RE_engine.h index e8e47b1f646..e56e7b8d2e4 100644 --- a/source/blender/render/RE_engine.h +++ b/source/blender/render/RE_engine.h @@ -169,10 +169,10 @@ void RE_engine_free(RenderEngine *engine); * x/y offsets are only used on a partial copy when dimensions don't match. */ void RE_layer_load_from_file( - struct RenderLayer *layer, struct ReportList *reports, const char *filename, int x, int y); + struct RenderLayer *layer, struct ReportList *reports, const char *filepath, int x, int y); void RE_result_load_from_file(struct RenderResult *result, struct ReportList *reports, - const char *filename); + const char *filepath); struct RenderResult *RE_engine_begin_result( RenderEngine *engine, int x, int y, int w, int h, const char *layername, const char *viewname); diff --git a/source/blender/render/intern/bake.c b/source/blender/render/intern/bake.c index 596adafb2c9..69235fb6cb1 100644 --- a/source/blender/render/intern/bake.c +++ b/source/blender/render/intern/bake.c @@ -12,14 +12,14 @@ * The Bake API is fully implemented with Python rna functions. * The operator expects/call a function: * - * `def bake(scene, object, pass_type, object_id, pixel_array, num_pixels, depth, result)` + * `def bake(scene, object, pass_type, object_id, pixel_array, pixels_num, depth, result)` * - scene: current scene (Python object) * - object: object to render (Python object) * - pass_type: pass to render (string, e.g., "COMBINED", "AO", "NORMAL", ...) * - object_id: index of object to bake (to use with the pixel_array) * - pixel_array: list of primitive ids and barycentric coordinates to * `bake(Python object, see bake_pixel)`. - * - num_pixels: size of pixel_array, number of pixels to bake (int) + * - pixels_num: size of pixel_array, number of pixels to bake (int) * - depth: depth of pixels to return (int, assuming always 4 now) * - result: array to be populated by the engine (float array, PyLong_AsVoidPtr) * @@ -126,7 +126,7 @@ static void store_bake_pixel(void *handle, int x, int y, float u, float v) pixel->seed = i; } -void RE_bake_mask_fill(const BakePixel pixel_array[], const size_t num_pixels, char *mask) +void RE_bake_mask_fill(const BakePixel pixel_array[], const size_t pixels_num, char *mask) { size_t i; if (!mask) { @@ -134,7 +134,7 @@ void RE_bake_mask_fill(const BakePixel pixel_array[], const size_t num_pixels, c } /* only extend to pixels outside the mask area */ - for (i = 0; i < num_pixels; i++) { + for (i = 0; i < pixels_num; i++) { if (pixel_array[i].primitive_id != -1) { mask[i] = FILTER_MASK_USED; } @@ -539,7 +539,7 @@ bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low, BakePixel pixel_array_to[], BakeHighPolyData highpoly[], const int tot_highpoly, - const size_t num_pixels, + const size_t pixels_num, const bool is_custom_cage, const float cage_extrusion, const float max_ray_distance, @@ -603,7 +603,7 @@ bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low, } } - for (i = 0; i < num_pixels; i++) { + for (i = 0; i < pixels_num; i++) { float co[3]; float dir[3]; TriTessFace *tri_low; @@ -707,7 +707,7 @@ static void bake_differentials(BakeDataZSpan *bd, void RE_bake_pixels_populate(Mesh *me, BakePixel pixel_array[], - const size_t num_pixels, + const size_t pixels_num, const BakeTargets *targets, const char *uv_layer) { @@ -726,15 +726,15 @@ void RE_bake_pixels_populate(Mesh *me, BakeDataZSpan bd; bd.pixel_array = pixel_array; - bd.zspan = MEM_callocN(sizeof(ZSpan) * targets->num_images, "bake zspan"); + bd.zspan = MEM_callocN(sizeof(ZSpan) * targets->images_num, "bake zspan"); /* initialize all pixel arrays so we know which ones are 'blank' */ - for (int i = 0; i < num_pixels; i++) { + for (int i = 0; i < pixels_num; i++) { pixel_array[i].primitive_id = -1; pixel_array[i].object_id = 0; } - for (int i = 0; i < targets->num_images; i++) { + for (int i = 0; i < targets->images_num; i++) { zbuf_alloc_span(&bd.zspan[i], targets->images[i].width, targets->images[i].height); } @@ -772,7 +772,7 @@ void RE_bake_pixels_populate(Mesh *me, zspan_scanconvert(&bd.zspan[image_id], (void *)&bd, vec[0], vec[1], vec[2], store_bake_pixel); } - for (int i = 0; i < targets->num_images; i++) { + for (int i = 0; i < targets->images_num; i++) { zbuf_free_span(&bd.zspan[i]); } @@ -823,7 +823,7 @@ static void normal_compress(float out[3], } void RE_bake_normal_world_to_tangent(const BakePixel pixel_array[], - const size_t num_pixels, + const size_t pixels_num, const int depth, float result[], Mesh *me, @@ -838,9 +838,9 @@ void RE_bake_normal_world_to_tangent(const BakePixel pixel_array[], triangles = mesh_calc_tri_tessface(me, true, me_eval); - BLI_assert(num_pixels >= 3); + BLI_assert(pixels_num >= 3); - for (i = 0; i < num_pixels; i++) { + for (i = 0; i < pixels_num; i++) { TriTessFace *triangle; float tangents[3][3]; float normals[3][3]; @@ -948,7 +948,7 @@ void RE_bake_normal_world_to_tangent(const BakePixel pixel_array[], } void RE_bake_normal_world_to_object(const BakePixel pixel_array[], - const size_t num_pixels, + const size_t pixels_num, const int depth, float result[], struct Object *ob, @@ -959,7 +959,7 @@ void RE_bake_normal_world_to_object(const BakePixel pixel_array[], invert_m4_m4(iobmat, ob->obmat); - for (i = 0; i < num_pixels; i++) { + for (i = 0; i < pixels_num; i++) { size_t offset; float nor[3]; @@ -980,14 +980,14 @@ void RE_bake_normal_world_to_object(const BakePixel pixel_array[], } void RE_bake_normal_world_to_world(const BakePixel pixel_array[], - const size_t num_pixels, + const size_t pixels_num, const int depth, float result[], const eBakeNormalSwizzle normal_swizzle[3]) { size_t i; - for (i = 0; i < num_pixels; i++) { + for (i = 0; i < pixels_num; i++) { size_t offset; float nor[3]; diff --git a/source/blender/render/intern/engine.c b/source/blender/render/intern/engine.c index 3a7ac22dc1f..8a4b4c2a70d 100644 --- a/source/blender/render/intern/engine.c +++ b/source/blender/render/intern/engine.c @@ -827,14 +827,14 @@ bool RE_bake_engine(Render *re, type->update(engine, re->main, engine->depsgraph); } - for (int i = 0; i < targets->num_images; i++) { + for (int i = 0; i < targets->images_num; i++) { const BakeImage *image = targets->images + i; engine->bake.pixels = pixel_array + image->offset; - engine->bake.result = result + image->offset * targets->num_channels; + engine->bake.result = result + image->offset * targets->channels_num; engine->bake.width = image->width; engine->bake.height = image->height; - engine->bake.depth = targets->num_channels; + engine->bake.depth = targets->channels_num; engine->bake.object_id = object_id; type->bake( diff --git a/source/blender/render/intern/multires_bake.c b/source/blender/render/intern/multires_bake.c index c573d4feed1..33d961c027d 100644 --- a/source/blender/render/intern/multires_bake.c +++ b/source/blender/render/intern/multires_bake.c @@ -1061,23 +1061,23 @@ static void create_ao_raytree(MultiresBakeRender *bkr, MAOBakeData *ao_data) RayFace *face; CCGElem **grid_data; CCGKey key; - int num_grids, grid_size /*, face_side */, num_faces; + int grids_num, grid_size /*, face_side */, faces_num; int i; - num_grids = hidm->getNumGrids(hidm); + grids_num = hidm->getNumGrids(hidm); grid_size = hidm->getGridSize(hidm); grid_data = hidm->getGridData(hidm); hidm->getGridKey(hidm, &key); /* face_side = (grid_size << 1) - 1; */ /* UNUSED */ - num_faces = num_grids * (grid_size - 1) * (grid_size - 1); + faces_num = grids_num * (grid_size - 1) * (grid_size - 1); raytree = ao_data->raytree = RE_rayobject_create( - bkr->raytrace_structure, num_faces, bkr->octree_resolution); - face = ao_data->rayfaces = (RayFace *)MEM_callocN(num_faces * sizeof(RayFace), + bkr->raytrace_structure, faces_num, bkr->octree_resolution); + face = ao_data->rayfaces = (RayFace *)MEM_callocN(faces_num * sizeof(RayFace), "ObjectRen faces"); - for (i = 0; i < num_grids; i++) { + for (i = 0; i < grids_num; i++) { int x, y; for (x = 0; x < grid_size - 1; x++) { for (y = 0; y < grid_size - 1; y++) { diff --git a/source/blender/render/intern/pipeline.c b/source/blender/render/intern/pipeline.c index a6c2e9eb194..cf400bdfc77 100644 --- a/source/blender/render/intern/pipeline.c +++ b/source/blender/render/intern/pipeline.c @@ -2480,10 +2480,10 @@ bool RE_ReadRenderResult(Scene *scene, Scene *scenode) } void RE_layer_load_from_file( - RenderLayer *layer, ReportList *reports, const char *filename, int x, int y) + RenderLayer *layer, ReportList *reports, const char *filepath, int x, int y) { /* OCIO_TODO: assume layer was saved in default color space */ - ImBuf *ibuf = IMB_loadiffname(filename, IB_rect, NULL); + ImBuf *ibuf = IMB_loadiffname(filepath, IB_rect, NULL); RenderPass *rpass = NULL; /* multiview: since the API takes no 'view', we use the first combined pass found */ @@ -2498,7 +2498,7 @@ void RE_layer_load_from_file( RPT_ERROR, "%s: no Combined pass found in the render layer '%s'", __func__, - filename); + filepath); } if (ibuf && (ibuf->rect || ibuf->rect_float)) { @@ -2527,7 +2527,7 @@ void RE_layer_load_from_file( } else { BKE_reportf( - reports, RPT_ERROR, "%s: failed to allocate clip buffer '%s'", __func__, filename); + reports, RPT_ERROR, "%s: failed to allocate clip buffer '%s'", __func__, filepath); } } else { @@ -2535,21 +2535,21 @@ void RE_layer_load_from_file( RPT_ERROR, "%s: incorrect dimensions for partial copy '%s'", __func__, - filename); + filepath); } } IMB_freeImBuf(ibuf); } else { - BKE_reportf(reports, RPT_ERROR, "%s: failed to load '%s'", __func__, filename); + BKE_reportf(reports, RPT_ERROR, "%s: failed to load '%s'", __func__, filepath); } } -void RE_result_load_from_file(RenderResult *result, ReportList *reports, const char *filename) +void RE_result_load_from_file(RenderResult *result, ReportList *reports, const char *filepath) { - if (!render_result_exr_file_read_path(result, NULL, filename)) { - BKE_reportf(reports, RPT_ERROR, "%s: failed to load '%s'", __func__, filename); + if (!render_result_exr_file_read_path(result, NULL, filepath)) { + BKE_reportf(reports, RPT_ERROR, "%s: failed to load '%s'", __func__, filepath); return; } } diff --git a/source/blender/render/intern/render_result.c b/source/blender/render/intern/render_result.c index ea7fa961f0d..9f4aa642773 100644 --- a/source/blender/render/intern/render_result.c +++ b/source/blender/render/intern/render_result.c @@ -402,7 +402,7 @@ RenderResult *render_result_new(Render *re, render_layer_add_pass(rr, rl, 4, RE_PASSNAME_COMBINED, view, "RGBA", false); } - /* NOTE: this has to be in sync with `scene.c`. */ + /* NOTE: this has to be in sync with `scene.cc`. */ rl->layflag = SCE_LAY_FLAG_DEFAULT; rl->passflag = SCE_PASS_COMBINED; diff --git a/source/blender/render/intern/texture_margin.cc b/source/blender/render/intern/texture_margin.cc index adc11cd925e..d01c0dbea71 100644 --- a/source/blender/render/intern/texture_margin.cc +++ b/source/blender/render/intern/texture_margin.cc @@ -331,7 +331,7 @@ class TextureMarginMap { float destx, desty; int foundpoly; - float mindist = -1.f; + float mindist = -1.0f; /* Loop over all adjacent polygons and determine which edge is closest. * This could be optimized by only inspecting neighbors which are on the edge of an island. @@ -356,7 +356,7 @@ class TextureMarginMap { } } - return mindist >= 0.f; + return mindist >= 0.0f; } /** diff --git a/source/blender/sequencer/SEQ_animation.h b/source/blender/sequencer/SEQ_animation.h index 455e77fb4a3..f2c66393b65 100644 --- a/source/blender/sequencer/SEQ_animation.h +++ b/source/blender/sequencer/SEQ_animation.h @@ -19,6 +19,18 @@ struct Sequence; void SEQ_free_animdata(struct Scene *scene, struct Sequence *seq); void SEQ_offset_animdata(struct Scene *scene, struct Sequence *seq, int ofs); struct GSet *SEQ_fcurves_by_strip_get(const struct Sequence *seq, struct ListBase *fcurve_base); +/** + * Move all `F-curves` from `scene` to `list`. + */ +void SEQ_animation_backup_original(struct Scene *scene, struct ListBase *list); +/** + * Move all `F-curves` from `list` to `scene`. + */ +void SEQ_animation_restore_original(struct Scene *scene, struct ListBase *list); +/** + * Duplicate `F-curves` used by `seq` from `list` to `scene`. + */ +void SEQ_animation_duplicate(struct Scene *scene, struct Sequence *seq, struct ListBase *list); #ifdef __cplusplus } diff --git a/source/blender/sequencer/intern/animation.c b/source/blender/sequencer/intern/animation.c index 47453ceda2b..27f7316e042 100644 --- a/source/blender/sequencer/intern/animation.c +++ b/source/blender/sequencer/intern/animation.c @@ -104,3 +104,32 @@ void SEQ_free_animdata(Scene *scene, Sequence *seq) GSET_FOREACH_END(); BLI_gset_free(fcurves, NULL); } + +void SEQ_animation_backup_original(Scene *scene, ListBase *list) +{ + if (scene->adt == NULL || scene->adt->action == NULL || + BLI_listbase_is_empty(&scene->adt->action->curves)) { + return; + } + + BLI_movelisttolist(list, &scene->adt->action->curves); +} + +void SEQ_animation_restore_original(Scene *scene, ListBase *list) +{ + if (scene->adt == NULL || scene->adt->action == NULL || BLI_listbase_is_empty(list)) { + return; + } + + BLI_movelisttolist(&scene->adt->action->curves, list); +} + +void SEQ_animation_duplicate(Scene *scene, Sequence *seq, ListBase *list) +{ + GSet *fcurves = SEQ_fcurves_by_strip_get(seq, list); + GSET_FOREACH_BEGIN (FCurve *, fcu, fcurves) { + FCurve *fcu_cpy = BKE_fcurve_copy(fcu); + BLI_addtail(&scene->adt->action->curves, fcu_cpy); + } + GSET_FOREACH_END(); +} diff --git a/source/blender/sequencer/intern/disk_cache.c b/source/blender/sequencer/intern/disk_cache.c index 9216383d274..0fdaef61b65 100644 --- a/source/blender/sequencer/intern/disk_cache.c +++ b/source/blender/sequencer/intern/disk_cache.c @@ -160,10 +160,11 @@ static DiskCacheFile *seq_disk_cache_add_file_to_list(SeqDiskCache *disk_cache, static void seq_disk_cache_get_files(SeqDiskCache *disk_cache, char *path) { struct direntry *filelist, *fl; - uint nbr, i; + uint i; disk_cache->size_total = 0; - i = nbr = BLI_filelist_dir_contents(path, &filelist); + const int filelist_num = BLI_filelist_dir_contents(path, &filelist); + i = filelist_num; fl = filelist; while (i--) { /* Don't follow links. */ @@ -194,7 +195,7 @@ static void seq_disk_cache_get_files(SeqDiskCache *disk_cache, char *path) } fl++; } - BLI_filelist_free(filelist, nbr); + BLI_filelist_free(filelist, filelist_num); } static DiskCacheFile *seq_disk_cache_get_oldest_file(SeqDiskCache *disk_cache) diff --git a/source/blender/sequencer/intern/effects.c b/source/blender/sequencer/intern/effects.c index 8f7088b0c4b..a4ab7671eb0 100644 --- a/source/blender/sequencer/intern/effects.c +++ b/source/blender/sequencer/intern/effects.c @@ -1681,7 +1681,7 @@ static void do_wipe_effect_byte(Sequence *seq, for (int i = 0; i < y; i++) { for (int j = 0; j < x; j++) { - float check = check_zone(&wipezone, x, y, seq, fac); + float check = check_zone(&wipezone, j, i, seq, fac); if (check) { if (cp1) { float rt1[4], rt2[4], tempc[4]; @@ -1742,7 +1742,7 @@ static void do_wipe_effect_float( for (int i = 0; i < y; i++) { for (int j = 0; j < x; j++) { - float check = check_zone(&wipezone, x, y, seq, fac); + float check = check_zone(&wipezone, j, i, seq, fac); if (check) { if (rt1) { rt[0] = rt1[0] * check + rt2[0] * (1 - check); diff --git a/source/blender/sequencer/intern/strip_edit.c b/source/blender/sequencer/intern/strip_edit.c index 60f3f35314e..2f76b6240cf 100644 --- a/source/blender/sequencer/intern/strip_edit.c +++ b/source/blender/sequencer/intern/strip_edit.c @@ -457,11 +457,18 @@ Sequence *SEQ_edit_strip_split(Main *bmain, return NULL; } - /* Move strips in collection from seqbase to new ListBase. */ + /* Store `F-curves`, so original ones aren't renamed. */ + ListBase fcurves_original_backup = {NULL, NULL}; + SEQ_animation_backup_original(scene, &fcurves_original_backup); + ListBase left_strips = {NULL, NULL}; SEQ_ITERATOR_FOREACH (seq, collection) { + /* Move strips in collection from seqbase to new ListBase. */ BLI_remlink(seqbase, seq); BLI_addtail(&left_strips, seq); + + /* Duplicate curves from backup, so they can be renamed along with split strips. */ + SEQ_animation_duplicate(scene, seq, &fcurves_original_backup); } SEQ_collection_free(collection); @@ -511,6 +518,8 @@ Sequence *SEQ_edit_strip_split(Main *bmain, SEQ_ensure_unique_name(seq_rename, scene); } + SEQ_animation_restore_original(scene, &fcurves_original_backup); + return return_seq; } diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 7959c3d6f0b..0864627ebe3 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -740,14 +740,33 @@ bool WM_operator_last_properties_store(struct wmOperator *op); /* wm_operator_props.c */ void WM_operator_properties_confirm_or_exec(struct wmOperatorType *ot); + +/** Flags for #WM_operator_properties_filesel. */ +typedef enum eFileSel_Flag { + WM_FILESEL_RELPATH = 1 << 0, + WM_FILESEL_DIRECTORY = 1 << 1, + WM_FILESEL_FILENAME = 1 << 2, + WM_FILESEL_FILEPATH = 1 << 3, + WM_FILESEL_FILES = 1 << 4, + /** Show the properties sidebar by default. */ + WM_FILESEL_SHOW_PROPS = 1 << 5, +} eFileSel_Flag; +ENUM_OPERATORS(eFileSel_Flag, WM_FILESEL_SHOW_PROPS) + +/** Action for #WM_operator_properties_filesel. */ +typedef enum eFileSel_Action { + FILE_OPENFILE = 0, + FILE_SAVE = 1, +} eFileSel_Action; + /** * Default properties for file-select. */ void WM_operator_properties_filesel(struct wmOperatorType *ot, int filter, short type, - short action, - short flag, + eFileSel_Action action, + eFileSel_Flag flag, short display, short sort); /** @@ -841,16 +860,6 @@ void WM_operator_properties_checker_interval_from_op(struct wmOperator *op, bool WM_operator_properties_checker_interval_test(const struct CheckerIntervalParams *op_params, int depth); -/* flags for WM_operator_properties_filesel */ -#define WM_FILESEL_RELPATH (1 << 0) - -#define WM_FILESEL_DIRECTORY (1 << 1) -#define WM_FILESEL_FILENAME (1 << 2) -#define WM_FILESEL_FILEPATH (1 << 3) -#define WM_FILESEL_FILES (1 << 4) -/* Show the properties sidebar by default. */ -#define WM_FILESEL_SHOW_PROPS (1 << 5) - /** * Operator as a Python command (resulting string must be freed). * diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 790b08437bd..60ae4eccbbe 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1063,7 +1063,7 @@ static void wm_operator_finished(bContext *C, wmOperator *op, const bool repeat, if (hud_status != NOP) { if (hud_status == SET) { ScrArea *area = CTX_wm_area(C); - if (area) { + if (area && ((area->flag & AREA_FLAG_OFFSCREEN) == 0)) { ED_area_type_hud_ensure(C, area); } } diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 04ce7bcb520..caa3a493349 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -867,7 +867,7 @@ static void file_read_reports_finalize(BlendFileReadReport *bf_reports) RPT_WARNING, "Proxies have been removed from Blender (%d proxies were automatically converted " "to library overrides, %d proxies could not be converted and were cleared). " - "Please also consider re-saving any library .blend file with the newest Blender version.", + "Please also consider re-saving any library .blend file with the newest Blender version", bf_reports->count.proxies_to_lib_overrides_success, bf_reports->count.proxies_to_lib_overrides_failures); } @@ -1999,20 +1999,20 @@ void wm_autosave_timer(Main *bmain, wmWindowManager *wm, wmTimer *UNUSED(wt)) void wm_autosave_delete(void) { - char filename[FILE_MAX]; + char filepath[FILE_MAX]; - wm_autosave_location(filename); + wm_autosave_location(filepath); - if (BLI_exists(filename)) { + if (BLI_exists(filepath)) { char str[FILE_MAX]; BLI_join_dirfile(str, sizeof(str), BKE_tempdir_base(), BLENDER_QUIT_FILE); /* if global undo; remove tempsave, otherwise rename */ if (U.uiflag & USER_GLOBALUNDO) { - BLI_delete(filename, false, false); + BLI_delete(filepath, false, false); } else { - BLI_rename(filename, str); + BLI_rename(filepath, str); } } } @@ -2959,10 +2959,10 @@ static int wm_recover_auto_save_exec(bContext *C, wmOperator *op) static int wm_recover_auto_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - char filename[FILE_MAX]; + char filepath[FILE_MAX]; - wm_autosave_location(filename); - RNA_string_set(op->ptr, "filepath", filename); + wm_autosave_location(filepath); + RNA_string_set(op->ptr, "filepath", filepath); wm_open_init_use_scripts(op, true); WM_event_add_fileselect(C, op); diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 6a9776c6933..8d6741dcfb6 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -440,19 +440,19 @@ void WM_exit_ex(bContext *C, const bool do_python) if (undo_memfile != NULL) { /* save the undo state as quit.blend */ Main *bmain = CTX_data_main(C); - char filename[FILE_MAX]; + char filepath[FILE_MAX]; bool has_edited; const int fileflags = G.fileflags & ~G_FILE_COMPRESS; - BLI_join_dirfile(filename, sizeof(filename), BKE_tempdir_base(), BLENDER_QUIT_FILE); + BLI_join_dirfile(filepath, sizeof(filepath), BKE_tempdir_base(), BLENDER_QUIT_FILE); has_edited = ED_editors_flush_edits(bmain); if ((has_edited && BLO_write_file( - bmain, filename, fileflags, &(const struct BlendFileWriteParams){0}, NULL)) || - (BLO_memfile_write_file(undo_memfile, filename))) { - printf("Saved session recovery to '%s'\n", filename); + bmain, filepath, fileflags, &(const struct BlendFileWriteParams){0}, NULL)) || + (BLO_memfile_write_file(undo_memfile, filepath))) { + printf("Saved session recovery to '%s'\n", filepath); } } } diff --git a/source/blender/windowmanager/intern/wm_operator_props.c b/source/blender/windowmanager/intern/wm_operator_props.c index dacc17c2c1e..c048b64426a 100644 --- a/source/blender/windowmanager/intern/wm_operator_props.c +++ b/source/blender/windowmanager/intern/wm_operator_props.c @@ -58,12 +58,12 @@ static const EnumPropertyItem *wm_operator_properties_filesel_sort_items_itemf( } void WM_operator_properties_filesel(wmOperatorType *ot, - int filter, - short type, - short action, - short flag, - short display, - short sort) + const int filter, + const short type, + const eFileSel_Action action, + const eFileSel_Flag flag, + const short display, + const short sort) { PropertyRNA *prop; diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index c706e99b592..b45c638d7b9 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1991,7 +1991,7 @@ static void WM_OT_window_fullscreen_toggle(wmOperatorType *ot) { ot->name = "Toggle Window Fullscreen"; ot->idname = "WM_OT_window_fullscreen_toggle"; - ot->description = "Toggle the current window fullscreen"; + ot->description = "Toggle the current window full-screen"; ot->exec = wm_window_fullscreen_toggle_exec; ot->poll = WM_operator_winactive; diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c index 0d131ad207e..e1f5bb6377d 100644 --- a/source/creator/creator_args.c +++ b/source/creator/creator_args.c @@ -828,7 +828,7 @@ static int arg_handle_log_show_timestamp_set(int UNUSED(argc), } static const char arg_handle_log_file_set_doc[] = - "<filename>\n" + "<filepath>\n" "\tSet a file to output the log to."; static int arg_handle_log_file_set(int argc, const char **argv, void *UNUSED(data)) { @@ -1432,7 +1432,7 @@ static const char arg_handle_image_type_set_doc[] = "\t'TGA' 'RAWTGA' 'JPEG' 'IRIS' 'IRIZ' 'AVIRAW' 'AVIJPEG' 'PNG' 'BMP'\n" "\n" "\tFormats that can be compiled into Blender, not available on all systems:\n" - "\t'HDR' 'TIFF' 'OPEN_EXR' 'OPEN_EXR_MULTILAYER' 'MPEG' 'CINEON' 'DPX' 'DDS' 'JP2'"; + "\t'HDR' 'TIFF' 'OPEN_EXR' 'OPEN_EXR_MULTILAYER' 'MPEG' 'CINEON' 'DPX' 'DDS' 'JP2' 'WEBP'"; static int arg_handle_image_type_set(int argc, const char **argv, void *data) { bContext *C = data; @@ -1752,7 +1752,7 @@ static int arg_handle_frame_skip_set(int argc, const char **argv, void *data) } static const char arg_handle_python_file_run_doc[] = - "<filename>\n" + "<filepath>\n" "\tRun the given Python script file."; static int arg_handle_python_file_run(int argc, const char **argv, void *data) { @@ -1762,12 +1762,12 @@ static int arg_handle_python_file_run(int argc, const char **argv, void *data) /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */ if (argc > 1) { /* Make the path absolute because its needed for relative linked blends to be found */ - char filename[FILE_MAX]; - BLI_strncpy(filename, argv[1], sizeof(filename)); - BLI_path_abs_from_cwd(filename, sizeof(filename)); + char filepath[FILE_MAX]; + BLI_strncpy(filepath, argv[1], sizeof(filepath)); + BLI_path_abs_from_cwd(filepath, sizeof(filepath)); bool ok; - BPY_CTX_SETUP(ok = BPY_run_filepath(C, filename, NULL)); + BPY_CTX_SETUP(ok = BPY_run_filepath(C, filepath, NULL)); if (!ok && app_state.exit_code_on_error.python) { printf("\nError: script failed, file: '%s', exiting.\n", argv[1]); BPY_python_end(); @@ -1952,22 +1952,22 @@ static int arg_handle_load_file(int UNUSED(argc), const char **argv, void *data) bool success; /* Make the path absolute because its needed for relative linked blends to be found */ - char filename[FILE_MAX]; + char filepath[FILE_MAX]; /* NOTE: we could skip these, but so far we always tried to load these files. */ if (argv[0][0] == '-') { fprintf(stderr, "unknown argument, loading as file: %s\n", argv[0]); } - BLI_strncpy(filename, argv[0], sizeof(filename)); - BLI_path_slash_native(filename); - BLI_path_abs_from_cwd(filename, sizeof(filename)); - BLI_path_normalize(NULL, filename); + BLI_strncpy(filepath, argv[0], sizeof(filepath)); + BLI_path_slash_native(filepath); + BLI_path_abs_from_cwd(filepath, sizeof(filepath)); + BLI_path_normalize(NULL, filepath); /* load the file */ BKE_reports_init(&reports, RPT_PRINT); - WM_file_autoexec_init(filename); - success = WM_file_read(C, filename, &reports); + WM_file_autoexec_init(filepath); + success = WM_file_read(C, filepath, &reports); BKE_reports_clear(&reports); if (success) { @@ -1988,16 +1988,16 @@ static int arg_handle_load_file(int UNUSED(argc), const char **argv, void *data) return -1; } - if (BLO_has_bfile_extension(filename)) { + if (BLO_has_bfile_extension(filepath)) { /* Just pretend a file was loaded, so the user can press Save and it'll - * save at the filename from the CLI. */ - STRNCPY(G_MAIN->filepath, filename); - printf("... opened default scene instead; saving will write to: %s\n", filename); + * save at the filepath from the CLI. */ + STRNCPY(G_MAIN->filepath, filepath); + printf("... opened default scene instead; saving will write to: %s\n", filepath); } else { printf( "Error: argument has no '.blend' file extension, not using as new file, exiting! %s\n", - filename); + filepath); G.is_break = true; WM_exit(C); } |