Eevee-Next: World Reflective Light #108149

Merged
Jeroen Bakker merged 33 commits from Jeroen-Bakker/blender:eevee-next-world-shader into main 2023-06-29 15:25:04 +02:00
5406 changed files with 33236 additions and 16943 deletions
Showing only changes of commit 2a2401dc0a - Show all commits

View File

@ -1,3 +1,5 @@
# SPDX-FileCopyrightText: 2023 Blender Foundation
#
# SPDX-License-Identifier: GPL-2.0-or-later
##################################################################################################

View File

@ -104,9 +104,9 @@
* merged in docs.
*/
/**
* \defgroup gui GUI
* \ingroup blender */
/** \defgroup gui GUI
* \ingroup blender
*/
/** \defgroup wm Window Manager
* \ingroup gui */

View File

@ -5,7 +5,7 @@
This script generates the blender.1 man page, embedding the help text
from the Blender executable itself. Invoke it as follows:
blender.1.py --blender <path-to-blender> --output <output-filename>
./blender.bin -b --python doc/manpage/blender.1.py -- --output <output-filename>
where <path-to-blender> is the path to the Blender executable,
and <output-filename> is where to write the generated man page.
@ -13,8 +13,8 @@ and <output-filename> is where to write the generated man page.
import argparse
import os
import subprocess
import time
import sys
from typing import (
Dict,
@ -28,61 +28,28 @@ def man_format(data: str) -> str:
return data
def blender_extract_info(blender_bin: str) -> Dict[str, str]:
def blender_extract_info() -> Dict[str, str]:
# Only use of `bpy` in this file.
import bpy # type: ignore
blender_help_text = bpy.app.help_text()
blender_version_text = bpy.app.version_string
blender_build_date_text = bpy.app.build_date
blender_env = {
"ASAN_OPTIONS": (
os.environ.get("ASAN_OPTIONS", "") +
":exitcode=0:check_initialization_order=0:strict_init_order=0"
).lstrip(":"),
}
blender_help = subprocess.run(
[blender_bin, "--help"],
env=blender_env,
check=True,
stdout=subprocess.PIPE,
).stdout.decode(encoding="utf-8")
blender_version_output = subprocess.run(
[blender_bin, "--version"],
env=blender_env,
check=True,
stdout=subprocess.PIPE,
).stdout.decode(encoding="utf-8")
# Extract information from the version string.
# Note that some internal modules may print errors (e.g. color management),
# check for each lines prefix to ensure these aren't included.
blender_version = ""
blender_date = ""
for l in blender_version_output.split("\n"):
if l.startswith("Blender "):
# Remove 'Blender' prefix.
blender_version = l.split(" ", 1)[1].strip()
elif l.lstrip().startswith("build date:"):
# Remove 'build date:' prefix.
blender_date = l.split(":", 1)[1].strip()
if blender_version and blender_date:
break
if not blender_date:
if blender_build_date_text == b'Unknown':
# Happens when built without WITH_BUILD_INFO e.g.
date_string = time.strftime("%B %d, %Y", time.gmtime(int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))))
blender_date = time.strftime("%B %d, %Y", time.gmtime(int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))))
else:
date_string = time.strftime("%B %d, %Y", time.strptime(blender_date, "%Y-%m-%d"))
blender_date = time.strftime("%B %d, %Y", time.strptime(blender_build_date_text, "%Y-%m-%d"))
return {
"help": blender_help,
"version": blender_version,
"date": date_string,
"help": blender_help_text,
"version": blender_version_text,
"date": blender_date,
}
def man_page_from_blender_help(fh: TextIO, blender_bin: str, verbose: bool) -> None:
if verbose:
print("Extracting help text:", blender_bin)
blender_info = blender_extract_info(blender_bin)
def man_page_from_blender_help(fh: TextIO, verbose: bool) -> None:
blender_info = blender_extract_info()
# Header Content.
fh.write(
@ -175,11 +142,6 @@ def create_argparse() -> argparse.ArgumentParser:
required=True,
help="The man page to write to."
)
parser.add_argument(
"--blender",
required=True,
help="Path to the blender binary."
)
parser.add_argument(
"--verbose",
default=False,
@ -192,15 +154,15 @@ def create_argparse() -> argparse.ArgumentParser:
def main() -> None:
argv = sys.argv[sys.argv.index("--") + 1:]
parser = create_argparse()
args = parser.parse_args()
args = parser.parse_args(argv)
blender_bin = args.blender
output_filename = args.output
verbose = args.verbose
with open(output_filename, "w", encoding="utf-8") as fh:
man_page_from_blender_help(fh, blender_bin, verbose)
man_page_from_blender_help(fh, verbose)
if verbose:
print("Written:", output_filename)

View File

@ -0,0 +1,10 @@
"""
Get the property associated with a hovered button.
Returns a tuple of the datablock, data path to the property, and array index.
"""
# Example inserting keyframe for the hovered property.
active_property = bpy.context.property
if active_property:
datablock, data_path, index = active_property
datablock.keyframe_insert(data_path=data_path, index=index, frame=1)

View File

@ -1202,6 +1202,7 @@ context_type_map = {
"particle_settings": ("ParticleSettings", False),
"particle_system": ("ParticleSystem", False),
"particle_system_editable": ("ParticleSystem", False),
"property": ("(:class:`bpy.types.ID`, :class:`string`, :class:`int`)", False),
"pointcloud": ("PointCloud", False),
"pose_bone": ("PoseBone", False),
"pose_object": ("Object", False),
@ -1347,7 +1348,11 @@ def pycontext2sphinx(basepath):
raise SystemExit(
"Error: context key %r not found in context_type_map; update %s" %
(member, __file__)) from None
fw(" :type: %s :class:`bpy.types.%s`\n\n" % ("sequence of " if is_seq else "", member_type))
if member_type.isidentifier():
member_type = ":class:`bpy.types.%s`" % member_type
fw(" :type: %s %s\n\n" % ("sequence of " if is_seq else "", member_type))
write_example_ref(" ", fw, "bpy.context." + member)
# Generate type-map:
# for member in sorted(unique_context_strings):

View File

@ -3,6 +3,7 @@
# Libs that adhere to strict flags
add_subdirectory(curve_fit_nd)
add_subdirectory(fmtlib)
# Otherwise we get warnings here that we cant fix in external projects
remove_strict_flags()

View File

@ -1,7 +1,7 @@
Project: fast_float
URL: https://github.com/fastfloat/fast_float
License: MIT
Upstream version: 4.0.0 (fbd5bd7, 2023 Mar 31)
Upstream version: 5.0.0 (f5a3e77, 2023 May 25)
Local modifications:
- Took only the fast_float.h header and the license/readme files

View File

@ -1,4 +1,8 @@
## fast_float number parsing library: 4x faster than strtod
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/fast_float.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:fast_float)
[![VS17-CI](https://github.com/fastfloat/fast_float/actions/workflows/vs17-ci.yml/badge.svg)](https://github.com/fastfloat/fast_float/actions/workflows/vs17-ci.yml)
[![Ubuntu 22.04 CI (GCC 11)](https://github.com/fastfloat/fast_float/actions/workflows/ubuntu22.yml/badge.svg)](https://github.com/fastfloat/fast_float/actions/workflows/ubuntu22.yml)
The fast_float library provides fast header-only implementations for the C++ from_chars
functions for `float` and `double` types. These functions convert ASCII strings representing
@ -93,6 +97,24 @@ constexpr double constexptest() {
}
```
## Non-ASCII Inputs
We also support UTF-16 and UTF-32 inputs, as well as ASCII/UTF-8, as in the following example:
``` C++
#include "fast_float/fast_float.h"
#include <iostream>
int main() {
const std::u16string input = u"3.1416 xyz ";
double result;
auto answer = fast_float::from_chars(input.data(), input.data()+input.size(), result);
if(answer.ec != std::errc()) { std::cerr << "parsing failure\n"; return EXIT_FAILURE; }
std::cout << "parsed the number " << result << std::endl;
return EXIT_SUCCESS;
}
```
## Using commas as decimal separator
@ -189,11 +211,11 @@ It can parse random floating-point numbers at a speed of 1 GB/s on some systems.
$ ./build/benchmarks/benchmark
# parsing random integers in the range [0,1)
volume = 2.09808 MB
netlib : 271.18 MB/s (+/- 1.2 %) 12.93 Mfloat/s
doubleconversion : 225.35 MB/s (+/- 1.2 %) 10.74 Mfloat/s
strtod : 190.94 MB/s (+/- 1.6 %) 9.10 Mfloat/s
abseil : 430.45 MB/s (+/- 2.2 %) 20.52 Mfloat/s
fastfloat : 1042.38 MB/s (+/- 9.9 %) 49.68 Mfloat/s
netlib : 271.18 MB/s (+/- 1.2 %) 12.93 Mfloat/s
doubleconversion : 225.35 MB/s (+/- 1.2 %) 10.74 Mfloat/s
strtod : 190.94 MB/s (+/- 1.6 %) 9.10 Mfloat/s
abseil : 430.45 MB/s (+/- 2.2 %) 20.52 Mfloat/s
fastfloat : 1042.38 MB/s (+/- 9.9 %) 49.68 Mfloat/s
```
See https://github.com/lemire/simple_fastfloat_benchmark for our benchmarking code.
@ -257,7 +279,7 @@ under the Apache 2.0 license.
<sup>
Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
2.0</a> or <a href="LICENSE-MIT">MIT license</a> or <a href="LICENSE-BOOST">BOOST license</a> .
</sup>
<br>
@ -265,5 +287,5 @@ Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
<sub>
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this repository by you, as defined in the Apache-2.0 license,
shall be dual licensed as above, without any additional terms or conditions.
shall be triple licensed as above, without any additional terms or conditions.
</sub>

File diff suppressed because it is too large Load Diff

20
extern/fmtlib/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,20 @@
# SPDX-License-Identifier: GPL-2.0-or-later
set(INC
include
)
set(INC_SYS
)
set(SRC
include/fmt/core.h
include/fmt/format-inl.h
include/fmt/format.h
src/format.cc
)
set(LIB
)
blender_add_lib(extern_fmtlib "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")

View File

@ -1,4 +1,4 @@
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

View File

@ -1,8 +1,12 @@
Project: {fmt}
URL: https://github.com/fmtlib/fmt
License: MIT
Upstream version: 8.1.1 (b6f4cea)
Upstream version: 10.0.0 (a0b8a92, 2023 May 10)
Local modifications:
- Took only files needed for Blender: LICENSE, README and include/fmt
folder's core.h, format-inl.h, format.h
- Took only files needed for Blender:
- LICENSE, README
- include/fmt: core.h, format-inl.h, format.h
- src/format.cc
- CMakeLists.txt is not from fmtlib, but
made for Blender codebase

View File

@ -1,5 +1,7 @@
{fmt}
=====
.. image:: https://user-images.githubusercontent.com/
576385/156254208-f5b743a9-88cf-439d-b0c0-923d53e8d551.png
:width: 25%
:alt: {fmt}
.. image:: https://github.com/fmtlib/fmt/workflows/linux/badge.svg
:target: https://github.com/fmtlib/fmt/actions?query=workflow%3Alinux
@ -10,9 +12,6 @@
.. 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?\
@ -26,12 +25,13 @@
**{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/.
If you like this project, please consider donating to one of the funds that
help victims of the war in Ukraine: https://www.stopputin.net/.
`Documentation <https://fmt.dev>`__
`Cheat Sheets <https://hackingcpp.com/cpp/libs/fmt.html>`__
Q&A: ask questions on `StackOverflow with the tag fmt
<https://stackoverflow.com/questions/tagged/fmt>`_.
@ -47,7 +47,8 @@ Features
* `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
round-trip guarantees using the `Dragonbox <https://github.com/jk-jeon/dragonbox>`_
algorithm
* Safe `printf implementation
<https://fmt.dev/latest/api.html#printf-formatting>`_ including the POSIX
extension for positional arguments
@ -123,7 +124,7 @@ Output::
Default format: 42s 100ms
strftime-like format: 03:15:30
**Print a container** (`run <https://godbolt.org/z/MjsY7c>`_)
**Print a container** (`run <https://godbolt.org/z/MxM1YqjE7>`_)
.. code:: c++
@ -191,24 +192,24 @@ 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
libc printf 0.91
libc++ std::ostream 2.49
{fmt} 9.1 fmt::print 0.74
Boost Format 1.80 boost::format 6.26
Folly Format folly::format 1.87
================= ============= ===========
{fmt} is the fastest of the benchmarked methods, ~35% faster than ``printf``.
{fmt} is the fastest of the benchmarked methods, ~20% 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
12.6.1 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>`_)
IEEE754 ``float`` and ``double`` 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>`_:
@ -322,8 +323,10 @@ Projects using this library
* `ccache <https://ccache.dev/>`_: a compiler cache
* `ClickHouse <https://github.com/ClickHouse/ClickHouse>`_: analytical database
* `ClickHouse <https://github.com/ClickHouse/ClickHouse>`_: an analytical database
management system
* `Contour <https://github.com/contour-terminal/contour/>`_: a modern terminal emulator
* `CUAUV <https://cuauv.org/>`_: Cornell University's autonomous underwater
vehicle
@ -341,9 +344,12 @@ Projects using this library
* `Folly <https://github.com/facebook/folly>`_: Facebook open-source library
* `GemRB <https://gemrb.org/>`_: a portable open-source implementation of
Biowares Infinity Engine
* `Grand Mountain Adventure
<https://store.steampowered.com/app/1247360/Grand_Mountain_Adventure/>`_:
A beautiful open-world ski & snowboarding game
a beautiful open-world ski & snowboarding game
* `HarpyWar/pvpgn <https://github.com/pvpgn/pvpgn-server>`_:
Player vs Player Gaming Network with tweaks
@ -357,6 +363,10 @@ Projects using this library
* `Knuth <https://kth.cash/>`_: high-performance Bitcoin full-node
* `libunicode <https://github.com/contour-terminal/libunicode/>`_: a modern C++17 Unicode library
* `MariaDB <https://mariadb.org/>`_: relational database management system
* `Microsoft Verona <https://github.com/microsoft/verona>`_:
research programming language for concurrent ownership
@ -410,6 +420,9 @@ Projects using this library
* `TrinityCore <https://github.com/TrinityCore/TrinityCore>`_: open-source
MMORPG framework
* `🐙 userver framework <https://userver.tech/>`_: open-source asynchronous
framework with a rich set of abstractions and database drivers
* `Windows Terminal <https://github.com/microsoft/terminal>`_: the new Windows
terminal
@ -520,8 +533,7 @@ 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.
<https://github.com/vitaut>`_) 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

43
extern/fmtlib/src/format.cc vendored Normal file
View File

@ -0,0 +1,43 @@
// Formatting library for C++
//
// Copyright (c) 2012 - 2016, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
#include "fmt/format-inl.h"
FMT_BEGIN_NAMESPACE
namespace detail {
template FMT_API auto dragonbox::to_decimal(float x) noexcept
-> dragonbox::decimal_fp<float>;
template FMT_API auto dragonbox::to_decimal(double x) noexcept
-> dragonbox::decimal_fp<double>;
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
template FMT_API locale_ref::locale_ref(const std::locale& loc);
template FMT_API auto locale_ref::get<std::locale>() const -> std::locale;
#endif
// Explicit instantiations for char.
template FMT_API auto thousands_sep_impl(locale_ref)
-> thousands_sep_result<char>;
template FMT_API auto decimal_point_impl(locale_ref) -> char;
template FMT_API void buffer<char>::append(const char*, const char*);
template FMT_API void vformat_to(buffer<char>&, string_view,
typename vformat_args<>::type, locale_ref);
// Explicit instantiations for wchar_t.
template FMT_API auto thousands_sep_impl(locale_ref)
-> thousands_sep_result<wchar_t>;
template FMT_API auto decimal_point_impl(locale_ref) -> wchar_t;
template FMT_API void buffer<wchar_t>::append(const wchar_t*, const wchar_t*);
} // namespace detail
FMT_END_NAMESPACE

View File

@ -9,4 +9,13 @@
#define VMA_IMPLEMENTATION
/*
* Disabling internal asserts of VMA.
*
* Blender can destroy logical device before all the resources are freed. This is because static
* resources are freed as a last step during quiting. As long as Vulkan isn't feature complete
* we don't want to change this behavior. So for now we just disable the asserts.
*/
#define VMA_ASSERT(test)
#include "vk_mem_alloc.h"

View File

@ -38,6 +38,8 @@ void BlenderSync::sync_light(BL::Object &b_parent,
}
}
light->name = b_light.name().c_str();
/* type */
switch (b_light.type()) {
case BL::Light::type_POINT: {

View File

@ -345,7 +345,9 @@ string MetalDevice::preprocess_source(MetalPipelineType pso_type,
case METAL_GPU_APPLE:
global_defines += "#define __KERNEL_METAL_APPLE__\n";
# ifdef WITH_NANOVDB
global_defines += "#define WITH_NANOVDB\n";
if (DebugFlags().metal.use_nanovdb) {
global_defines += "#define WITH_NANOVDB\n";
}
# endif
break;
}

View File

@ -681,7 +681,7 @@ void MetalKernelPipeline::compile()
__block bool compilation_finished = false;
__block string error_str;
if (loading_existing_archive) {
if (loading_existing_archive || !DebugFlags().metal.use_async_pso_creation) {
/* Use the blocking variant of newComputePipelineStateWithDescriptor if an archive exists on
* disk. It should load almost instantaneously, and will fail gracefully when loading a
* corrupt archive (unlike the async variant). */
@ -694,29 +694,6 @@ void MetalKernelPipeline::compile()
error_str = err ? err : "nil";
}
else {
/* TODO / MetalRT workaround:
* Workaround for a crash when addComputePipelineFunctionsWithDescriptor is called *after*
* newComputePipelineStateWithDescriptor with linked functions (i.e. with MetalRT enabled).
* Ideally we would like to call newComputePipelineStateWithDescriptor (async) first so we
* can bail out if needed, but we can stop the crash by flipping the order when there are
* linked functions. However when addComputePipelineFunctionsWithDescriptor is called first
* it will block while it builds the pipeline, offering no way of bailing out. */
auto addComputePipelineFunctionsWithDescriptor = [&]() {
if (creating_new_archive && ShaderCache::running) {
NSError *error;
if (![archive addComputePipelineFunctionsWithDescriptor:computePipelineStateDescriptor
error:&error])
{
NSString *errStr = [error localizedDescription];
metal_printf("Failed to add PSO to archive:\n%s\n",
errStr ? [errStr UTF8String] : "nil");
}
}
};
if (linked_functions) {
addComputePipelineFunctionsWithDescriptor();
}
/* Use the async variant of newComputePipelineStateWithDescriptor if no archive exists on
* disk. This allows us to respond to app shutdown. */
[mtlDevice
@ -744,10 +721,16 @@ void MetalKernelPipeline::compile()
while (ShaderCache::running && !compilation_finished) {
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
}
/* Add pipeline into the new archive (unless we did it earlier). */
if (pipeline && !linked_functions) {
addComputePipelineFunctionsWithDescriptor();
if (creating_new_archive && pipeline) {
/* Add pipeline into the new archive. */
NSError *error;
if (![archive addComputePipelineFunctionsWithDescriptor:computePipelineStateDescriptor
error:&error])
{
NSString *errStr = [error localizedDescription];
metal_printf("Failed to add PSO to archive:\n%s\n", errStr ? [errStr UTF8String] : "nil");
}
}

View File

@ -655,7 +655,7 @@ ccl_device_inline Spectrum bsdf_albedo(ccl_private const ShaderData *sd,
* extra overhead though. */
#if defined(__SVM__) || defined(__OSL__)
if (CLOSURE_IS_BSDF_MICROFACET(sc->type)) {
albedo *= microfacet_fresnel((ccl_private const MicrofacetBsdf *)sc, sd->wi, sc->N, false);
albedo *= bsdf_microfacet_estimate_fresnel(sd, (ccl_private const MicrofacetBsdf *)sc);
}
else if (sc->type == CLOSURE_BSDF_PRINCIPLED_SHEEN_ID) {
albedo *= ((ccl_private const PrincipledSheenBsdf *)sc)->avg_value;

View File

@ -262,19 +262,39 @@ ccl_device_forceinline Spectrum microfacet_fresnel(ccl_private const MicrofacetB
}
}
else if (bsdf->fresnel_type == MicrofacetFresnel::CONSTANT) {
kernel_assert(!refraction);
ccl_private FresnelConstant *fresnel = (ccl_private FresnelConstant *)bsdf->fresnel;
return fresnel->color;
/* CONSTANT is only used my MultiGGX, which doesn't call this function.
* Therefore, this case only happens when determining the albedo of a MultiGGX closure.
* In that case, return 1.0 since the constant color is already baked into the weight. */
return one_spectrum();
}
else {
return one_spectrum();
}
}
ccl_device_forceinline void bsdf_microfacet_adjust_weight(ccl_private const ShaderData *sd,
ccl_private MicrofacetBsdf *bsdf)
/* This function estimates the albedo of the BSDF (NOT including the bsdf->weight) as caused by
* the applied Fresnel model for the given view direction.
* The base microfacet model is assumed to have an albedo of 1, but e.g. a reflection-only
* closure with Fresnel applied can end up having a very low overall albedo.
* This is used to adjust the sample weight, as well as for the Diff/Gloss/Trans Color pass
* and the Denoising Albedo pass. */
ccl_device Spectrum bsdf_microfacet_estimate_fresnel(ccl_private const ShaderData *sd,
ccl_private const MicrofacetBsdf *bsdf)
{
bsdf->sample_weight *= average(microfacet_fresnel(bsdf, sd->wi, bsdf->N, false));
const bool is_glass = CLOSURE_IS_GLASS(bsdf->type);
const bool is_refractive = CLOSURE_IS_REFRACTIVE(bsdf->type);
Spectrum albedo = zero_spectrum();
if (!is_refractive || is_glass) {
/* BSDF has a reflective lobe. */
albedo += microfacet_fresnel(bsdf, sd->wi, bsdf->N, false);
}
if (is_refractive) {
/* BSDF has a refractive lobe (unless there's TIR). */
albedo += microfacet_fresnel(bsdf, sd->wi, bsdf->N, true);
}
return albedo;
}
/* Generalized Trowbridge-Reitz for clearcoat. */
@ -396,7 +416,7 @@ ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc,
* - Purely reflective closures can't have refraction.
* - Purely refractive closures can't have reflection.
*/
if ((cos_NI <= 0) || (alpha_x * alpha_y <= 1e-7f) || ((cos_NgO < 0.0f) != is_refraction) ||
if ((cos_NI <= 0) || (alpha_x * alpha_y <= 5e-7f) || ((cos_NgO < 0.0f) != is_refraction) ||
(is_refraction && !m_refractive) || (!is_refraction && m_refractive && !m_glass))
{
*pdf = 0.0f;
@ -478,7 +498,7 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc,
const bool m_refractive = CLOSURE_IS_REFRACTIVE(bsdf->type);
const float alpha_x = bsdf->alpha_x;
const float alpha_y = bsdf->alpha_y;
bool m_singular = (m_type == MicrofacetType::SHARP) || (alpha_x * alpha_y <= 1e-7f);
bool m_singular = (m_type == MicrofacetType::SHARP) || (alpha_x * alpha_y <= 5e-7f);
const float3 N = bsdf->N;
const float cos_NI = dot(N, wi);
@ -647,7 +667,7 @@ ccl_device void bsdf_microfacet_setup_fresnel_principledv1(
bsdf->fresnel_type = MicrofacetFresnel::PRINCIPLED_V1;
bsdf->fresnel = fresnel;
bsdf_microfacet_adjust_weight(sd, bsdf);
bsdf->sample_weight *= average(bsdf_microfacet_estimate_fresnel(sd, bsdf));
}
ccl_device void bsdf_microfacet_setup_fresnel_conductor(ccl_private MicrofacetBsdf *bsdf,
@ -656,7 +676,7 @@ ccl_device void bsdf_microfacet_setup_fresnel_conductor(ccl_private MicrofacetBs
{
bsdf->fresnel_type = MicrofacetFresnel::CONDUCTOR;
bsdf->fresnel = fresnel;
bsdf_microfacet_adjust_weight(sd, bsdf);
bsdf->sample_weight *= average(bsdf_microfacet_estimate_fresnel(sd, bsdf));
}
ccl_device void bsdf_microfacet_setup_fresnel_dielectric_tint(
@ -666,7 +686,7 @@ ccl_device void bsdf_microfacet_setup_fresnel_dielectric_tint(
{
bsdf->fresnel_type = MicrofacetFresnel::DIELECTRIC_TINT;
bsdf->fresnel = fresnel;
bsdf_microfacet_adjust_weight(sd, bsdf);
bsdf->sample_weight *= average(bsdf_microfacet_estimate_fresnel(sd, bsdf));
}
ccl_device void bsdf_microfacet_setup_fresnel_generalized_schlick(
@ -676,7 +696,7 @@ ccl_device void bsdf_microfacet_setup_fresnel_generalized_schlick(
{
bsdf->fresnel_type = MicrofacetFresnel::GENERALIZED_SCHLICK;
bsdf->fresnel = fresnel;
bsdf_microfacet_adjust_weight(sd, bsdf);
bsdf->sample_weight *= average(bsdf_microfacet_estimate_fresnel(sd, bsdf));
}
/* GGX microfacet with Smith shadow-masking from:
@ -711,8 +731,7 @@ ccl_device int bsdf_microfacet_ggx_clearcoat_setup(ccl_private MicrofacetBsdf *b
bsdf->fresnel_type = MicrofacetFresnel::DIELECTRIC;
bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID;
bsdf_microfacet_adjust_weight(sd, bsdf);
bsdf->sample_weight *= average(bsdf_microfacet_estimate_fresnel(sd, bsdf));
return SD_BSDF | SD_BSDF_HAS_EVAL;
}

View File

@ -407,8 +407,7 @@ ccl_device int bsdf_microfacet_multi_ggx_fresnel_setup(ccl_private MicrofacetBsd
bsdf->fresnel_type = MicrofacetFresnel::PRINCIPLED_V1;
bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID;
bsdf_microfacet_adjust_weight(sd, bsdf);
bsdf->sample_weight *= average(bsdf_microfacet_estimate_fresnel(sd, bsdf));
return bsdf_microfacet_multi_ggx_common_setup(bsdf);
}
@ -619,8 +618,7 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_fresnel_setup(ccl_private Microfa
bsdf->fresnel_type = MicrofacetFresnel::PRINCIPLED_V1;
bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
bsdf_microfacet_adjust_weight(sd, bsdf);
bsdf->sample_weight *= average(bsdf_microfacet_estimate_fresnel(sd, bsdf));
return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG;
}

View File

@ -36,7 +36,7 @@ KERNEL_STRUCT_MEMBER(background, int, map_res_x)
KERNEL_STRUCT_MEMBER(background, int, map_res_y)
/* Multiple importance sampling. */
KERNEL_STRUCT_MEMBER(background, int, use_mis)
/* Lightgroup. */
/* Light-group. */
KERNEL_STRUCT_MEMBER(background, int, lightgroup)
/* Light Index. */
KERNEL_STRUCT_MEMBER(background, int, light_index)

View File

@ -288,7 +288,7 @@ ccl_device_inline float object_pass_id(KernelGlobals kg, int object)
return kernel_data_fetch(objects, object).pass_id;
}
/* Lightgroup of lamp */
/* Light-group of lamp. */
ccl_device_inline int lamp_lightgroup(KernelGlobals kg, int lamp)
{
@ -298,7 +298,7 @@ ccl_device_inline int lamp_lightgroup(KernelGlobals kg, int lamp)
return kernel_data_fetch(lights, lamp).lightgroup;
}
/* Lightgroup of object */
/* Light-group of object. */
ccl_device_inline int object_lightgroup(KernelGlobals kg, int object)
{

View File

@ -32,6 +32,14 @@ ccl_device_inline void integrate_camera_sample(KernelGlobals kg,
path_rng_3D(kg, rng_hash, sample, PRNG_LENS_TIME) :
zero_float3();
/* We use x for time and y,z for lens because in practice with Sobol
* sampling this seems to give better convergence when an object is
* both motion blurred and out of focus, without significantly harming
* convergence for focal blur alone. This is a little surprising,
* because one would expect using x,y for lens (the 2d part) would be
* best, since x,y are the best stratified. Since it's not entirely
* clear why this is, this is probably worth revisiting at some point
* to investigate further. */
const float rand_time = rand_time_lens.x;
const float2 rand_lens = make_float2(rand_time_lens.y, rand_time_lens.z);

View File

@ -61,7 +61,7 @@ ccl_device int shadow_linking_pick_mesh_intersection(KernelGlobals kg,
if (set_membership != LIGHT_LINK_MASK_ALL) {
++num_hits;
if ((linked_isect->prim == PRIM_NONE) && (lcg_step_float(lcg_state) < 1.0f / num_hits)) {
if ((linked_isect->prim == PRIM_NONE) || (lcg_step_float(lcg_state) < 1.0f / num_hits)) {
*linked_isect = current_isect;
}
}

View File

@ -218,7 +218,7 @@ ccl_device void shadow_linking_shade(KernelGlobals kg,
/* Branch off shadow kernel. */
IntegratorShadowState shadow_state = integrate_direct_light_shadow_init_common(
kg, state, &ray, bsdf_spectrum, 0, light_group);
kg, state, &ray, bsdf_spectrum, light_group, 0);
/* The light is accumulated from the shade_surface kernel, which will make the clamping decision
* based on the actual value of the bounce. For the dedicated shadow ray we want to follow the

View File

@ -221,8 +221,8 @@ integrate_direct_light_shadow_init_common(KernelGlobals kg,
state, path, bounce);
}
/* Write Lightgroup, +1 as lightgroup is int but we need to encode into a uint8_t. */
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, lightgroup) = light_group;
/* Write Light-group, +1 as light-group is int but we need to encode into a uint8_t. */
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, lightgroup) = light_group + 1;
#ifdef __PATH_GUIDING__
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, unlit_throughput) = unlit_throughput;
@ -351,7 +351,7 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
const int light_group = ls.type != LIGHT_BACKGROUND ? ls.group :
kernel_data.background.lightgroup;
IntegratorShadowState shadow_state = integrate_direct_light_shadow_init_common(
kg, state, &ray, bsdf_eval_sum(&bsdf_eval), mnee_vertex_count, light_group);
kg, state, &ray, bsdf_eval_sum(&bsdf_eval), light_group, mnee_vertex_count);
if (is_transmission) {
#ifdef __VOLUME__

View File

@ -879,7 +879,7 @@ ccl_device_forceinline void integrate_volume_direct_light(
state, path, transmission_bounce);
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, throughput) = throughput_phase;
/* Write Lightgroup, +1 as lightgroup is int but we need to encode into a uint8_t. */
/* Write Light-group, +1 as light-group is int but we need to encode into a uint8_t. */
INTEGRATOR_STATE_WRITE(
shadow_state, shadow_path, lightgroup) = (ls.type != LIGHT_BACKGROUND) ?
ls.group + 1 :

View File

@ -498,17 +498,30 @@ ccl_device void light_tree_child_importance(KernelGlobals kg,
}
}
ccl_device void sample_resevoir(const int current_index,
const float current_weight,
ccl_private int &selected_index,
ccl_private float &selected_weight,
ccl_private float &total_weight,
ccl_private float &rand)
ccl_device void sample_reservoir(const int current_index,
const float current_weight,
ccl_private int &selected_index,
ccl_private float &selected_weight,
ccl_private float &total_weight,
ccl_private float &rand)
{
if (current_weight == 0.0f) {
return;
}
total_weight += current_weight;
/* When `-ffast-math` is used it is possible that the threshold is almost 1 but not quite.
* For this case we check the first assignment explicitly (instead of relying on the threshold to
* be 1, giving it certain probability). */
if (selected_index == -1) {
selected_index = current_index;
selected_weight = current_weight;
/* The threshold is expected to be 1 in this case with strict mathematics, so no need to divide
* the rand. In fact, division in such case could lead the rand to exceed 1 because of division
* by something smaller than 1. */
return;
}
float thresh = current_weight / total_weight;
if (rand <= thresh) {
selected_index = current_index;
@ -518,11 +531,13 @@ ccl_device void sample_resevoir(const int current_index,
else {
rand = (rand - thresh) / (1.0f - thresh);
}
kernel_assert(rand >= 0.0f && rand <= 1.0f);
return;
/* Ensure the `rand` is always within 0..1 range, which could be violated above when
* `-ffast-math` is used. */
rand = saturatef(rand);
}
/* Pick an emitter from a leaf node using resevoir sampling, keep two reservoirs for upper and
/* Pick an emitter from a leaf node using reservoir sampling, keep two reservoirs for upper and
* lower bounds. */
template<bool in_volume_segment>
ccl_device int light_tree_cluster_select_emitter(KernelGlobals kg,
@ -540,7 +555,7 @@ ccl_device int light_tree_cluster_select_emitter(KernelGlobals kg,
const ccl_global KernelLightTreeNode *knode = &kernel_data_fetch(light_tree_nodes, *node_index);
*node_index = -1;
/* Mark emitters with zero importance. Used for resevoir when total minimum importance = 0. */
/* Mark emitters with zero importance. Used for reservoir when total minimum importance = 0. */
kernel_assert(knode->num_emitters <= sizeof(uint) * 8);
uint has_importance = 0;
@ -556,12 +571,12 @@ ccl_device int light_tree_cluster_select_emitter(KernelGlobals kg,
light_tree_emitter_importance<in_volume_segment>(
kg, P, N_or_D, t, has_transmission, current_index, importance[0], importance[1]);
sample_resevoir(current_index,
importance[!sample_max],
selected_index,
selected_importance[!sample_max],
total_importance[!sample_max],
rand);
sample_reservoir(current_index,
importance[!sample_max],
selected_index,
selected_importance[!sample_max],
total_importance[!sample_max],
rand);
if (selected_index == current_index) {
selected_importance[sample_max] = importance[sample_max];
}
@ -584,12 +599,12 @@ ccl_device int light_tree_cluster_select_emitter(KernelGlobals kg,
selected_index = -1;
for (int i = 0; i < knode->num_emitters; i++) {
int current_index = knode->leaf.first_emitter + i;
sample_resevoir(current_index,
float(has_importance & 1),
selected_index,
selected_importance[1],
total_importance[1],
rand);
sample_reservoir(current_index,
float(has_importance & 1),
selected_index,
selected_importance[1],
total_importance[1],
rand);
has_importance >>= 1;
}
@ -730,7 +745,7 @@ ccl_device_noinline bool light_tree_sample(KernelGlobals kg,
float discard;
float total_prob = left_prob;
node_index = left_index;
sample_resevoir(
sample_reservoir(
right_index, 1.0f - left_prob, node_index, discard, total_prob, rand_selection);
pdf_leaf *= (node_index == left_index) ? left_prob : (1.0f - left_prob);
}

View File

@ -13,6 +13,20 @@ CCL_NAMESPACE_BEGIN
* this single threaded on a CPU for repeatable results. */
//#define __DEBUG_CORRELATION__
/*
* The `path_rng_*()` functions below use a shuffled scrambled Sobol
* sequence to generate their samples. Sobol samplers have a property
* that is worth being aware of when choosing how to use the sample
* dimensions:
*
* 1. In general, earlier sets of dimensions are better stratified. So
* prefer e.g. x,y over y,z over z,w for the things that are most
* important to sample well.
* 2. As a rule of thumb, dimensions that are closer to each other are
* better stratified than dimensions that are far. So prefer e.g.
* x,y over x,z.
*/
ccl_device_forceinline float path_rng_1D(KernelGlobals kg,
uint rng_hash,
int sample,

View File

@ -174,6 +174,24 @@ bool Light::has_contribution(Scene *scene)
return !is_zero(effective_shader->emission_estimate);
}
bool Light::has_light_linking() const
{
if (get_light_set_membership() != LIGHT_LINK_MASK_ALL) {
return true;
}
return false;
}
bool Light::has_shadow_linking() const
{
if (get_shadow_set_membership() != LIGHT_LINK_MASK_ALL) {
return true;
}
return false;
}
/* Light Manager */
LightManager::LightManager()
@ -685,7 +703,15 @@ static std::pair<int, LightTreeMeasure> light_tree_specialize_nodes_flatten(
}
assert(first_emitter != -1);
new_node.make_leaf(first_emitter, num_emitters);
/* Preserve the type of the node, so that the kernel can do proper decision when sampling node
* with multiple distant lights in it. */
if (node->is_leaf()) {
new_node.make_leaf(first_emitter, num_emitters);
}
else {
new_node.make_distant(first_emitter, num_emitters);
}
}
else {
assert(node->is_inner());

View File

@ -82,6 +82,10 @@ class Light : public Node {
/* Check whether the light has contribution the scene. */
bool has_contribution(Scene *scene);
/* Check whether this light participates in light or shadow linking. */
bool has_light_linking() const;
bool has_shadow_linking() const;
friend class LightManager;
friend class LightTree;
};

View File

@ -418,6 +418,11 @@ LightTreeNode *LightTree::build(Scene *scene, DeviceScene *dscene)
root_->light_link = root_->get_inner().children[left]->light_link +
root_->get_inner().children[right]->light_link;
/* Root nodes are never meant to be be shared, even if the local and distant lights are from the
* same light linking set. Attempting to sharing it will make it so the specialized tree will
* try to use the same root as the default tree. */
root_->light_link.shareable = false;
std::move(distant_lights_.begin(), distant_lights_.end(), std::back_inserter(emitters_));
return root_.get();

View File

@ -276,6 +276,7 @@ struct LightTreeNode {
__forceinline void add(const LightTreeEmitter &emitter)
{
measure.add(emitter.measure);
light_link.add(emitter.light_set_membership);
}
__forceinline Leaf &get_leaf()

View File

@ -403,6 +403,32 @@ bool Object::usable_as_light() const
return false;
}
bool Object::has_light_linking() const
{
if (get_receiver_light_set()) {
return true;
}
if (get_light_set_membership() != LIGHT_LINK_MASK_ALL) {
return true;
}
return false;
}
bool Object::has_shadow_linking() const
{
if (get_blocker_shadow_set()) {
return true;
}
if (get_shadow_set_membership() != LIGHT_LINK_MASK_ALL) {
return true;
}
return false;
}
/* Object Manager */
ObjectManager::ObjectManager()

View File

@ -113,6 +113,11 @@ class Object : public Node {
/* Check whether this object can be used as light-emissive. */
bool usable_as_light() const;
/* Check whether the object participates in light or shadow linking, either as a receiver/blocker
* or emitter. */
bool has_light_linking() const;
bool has_shadow_linking() const;
protected:
/* Specifies the position of the object in scene->objects and
* in the device vectors. Gets set in device_update. */

View File

@ -491,10 +491,10 @@ void Scene::update_kernel_features()
else if (geom->is_pointcloud()) {
kernel_features |= KERNEL_FEATURE_POINTCLOUD;
}
if (object->get_receiver_light_set()) {
if (object->has_light_linking()) {
kernel_features |= KERNEL_FEATURE_LIGHT_LINKING;
}
if (object->get_blocker_shadow_set()) {
if (object->has_shadow_linking()) {
kernel_features |= KERNEL_FEATURE_SHADOW_LINKING;
}
}
@ -503,6 +503,13 @@ void Scene::update_kernel_features()
if (light->get_use_caustics()) {
has_caustics_light = true;
}
if (light->has_light_linking()) {
kernel_features |= KERNEL_FEATURE_LIGHT_LINKING;
}
if (light->has_shadow_linking()) {
kernel_features |= KERNEL_FEATURE_SHADOW_LINKING;
}
}
dscene.data.integrator.use_caustics = false;

View File

@ -72,6 +72,12 @@ void DebugFlags::Metal::reset()
if (auto str = getenv("CYCLES_METAL_LOCAL_ATOMIC_SORT"))
use_local_atomic_sort = (atoi(str) != 0);
if (auto str = getenv("CYCLES_METAL_NANOVDB"))
use_nanovdb = (atoi(str) != 0);
if (auto str = getenv("CYCLES_METAL_ASYNC_PSO_CREATION"))
use_async_pso_creation = (atoi(str) != 0);
}
DebugFlags::OptiX::OptiX()

View File

@ -100,6 +100,12 @@ class DebugFlags {
/* Whether local atomic sorting is enabled or not. */
bool use_local_atomic_sort = true;
/* Whether nanovdb is enabled or not. */
bool use_nanovdb = true;
/* Whether async PSO creation is enabled or not. */
bool use_async_pso_creation = true;
};
/* Get instance of debug flags registry. */

View File

@ -1171,9 +1171,10 @@ class Octree {
return nleaf;
}
/** Locate a leaf
* WARNING: assuming this leaf already exists! */
/**
* Locate a leaf
* WARNING: assuming this leaf already exists!
*/
LeafNode *locateLeaf(int st[3])
{
Node *node = (Node *)root;

View File

@ -123,6 +123,17 @@ int64_t av_get_pts_from_frame(AVFrame *picture)
return timestamp_from_pts_or_dts(picture->pts, picture->pkt_dts);
}
/* Duration of the frame, in the same units as pts. 0 if unknown. */
FFMPEG_INLINE
int64_t av_get_frame_duration_in_pts_units(const AVFrame *picture)
{
#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(57, 30, 100)
return picture->pkt_duration;
#else
return picture->duration;
#endif
}
/* -------------------------------------------------------------------- */
/** \name Deinterlace code block
*

View File

@ -138,7 +138,6 @@ class GHOST_ContextCGL : public GHOST_Context {
bool m_useMetalForRendering = false;
NSView *m_metalView;
CAMetalLayer *m_metalLayer;
MTLCommandQueue *m_metalCmdQueue;
MTLRenderPipelineState *m_metalRenderPipeline;
bool m_ownsMetalDevice;
@ -182,6 +181,9 @@ class GHOST_ContextCGL : public GHOST_Context {
static NSOpenGLContext *s_sharedOpenGLContext;
static int s_sharedCount;
/* Single device queue for multiple contexts. */
static MTLCommandQueue *s_sharedMetalCommandQueue;
/* Metal functions */
void metalInit();
void metalFree();

View File

@ -43,6 +43,7 @@ static void ghost_fatal_error_dialog(const char *msg)
}
NSOpenGLContext *GHOST_ContextCGL::s_sharedOpenGLContext = nil;
MTLCommandQueue *GHOST_ContextCGL::s_sharedMetalCommandQueue = nil;
int GHOST_ContextCGL::s_sharedCount = 0;
GHOST_ContextCGL::GHOST_ContextCGL(bool stereoVisual,
@ -54,7 +55,6 @@ GHOST_ContextCGL::GHOST_ContextCGL(bool stereoVisual,
m_useMetalForRendering(type == GHOST_kDrawingContextTypeMetal),
m_metalView(metalView),
m_metalLayer(metalLayer),
m_metalCmdQueue(nil),
m_metalRenderPipeline(nil),
m_openGLView(openGLView),
m_openGLContext(nil),
@ -318,7 +318,7 @@ id<MTLTexture> GHOST_ContextCGL::metalOverlayTexture()
MTLCommandQueue *GHOST_ContextCGL::metalCommandQueue()
{
return m_metalCmdQueue;
return s_sharedMetalCommandQueue;
}
MTLDevice *GHOST_ContextCGL::metalDevice()
{
@ -530,10 +530,14 @@ void GHOST_ContextCGL::metalInit()
/* clang-format on */
id<MTLDevice> device = m_metalLayer.device;
/* Create a command queue for blit/present operation. */
m_metalCmdQueue = (MTLCommandQueue *)[device
newCommandQueueWithMaxCommandBufferCount:GHOST_ContextCGL::max_command_buffer_count];
[m_metalCmdQueue retain];
/* Create a command queue for blit/present operation. Note: All context should share a single
* command queue to ensure correct ordering of work submitted from multiple contexts. */
if (s_sharedMetalCommandQueue == nil) {
s_sharedMetalCommandQueue = (MTLCommandQueue *)[device
newCommandQueueWithMaxCommandBufferCount:GHOST_ContextCGL::max_command_buffer_count];
}
/* Ensure active GHOSTContext retains a reference to the shared context. */
[s_sharedMetalCommandQueue retain];
/* Create shaders for blit operation. */
NSString *source = @R"msl(
@ -616,9 +620,6 @@ void GHOST_ContextCGL::metalInit()
void GHOST_ContextCGL::metalFree()
{
if (m_metalCmdQueue) {
[m_metalCmdQueue release];
}
if (m_metalRenderPipeline) {
[m_metalRenderPipeline release];
}
@ -789,7 +790,7 @@ void GHOST_ContextCGL::metalUpdateFramebuffer()
overlayTex; //[(MTLTexture *)overlayTex retain];
/* Clear texture on create */
id<MTLCommandBuffer> cmdBuffer = [m_metalCmdQueue commandBuffer];
id<MTLCommandBuffer> cmdBuffer = [s_sharedMetalCommandQueue commandBuffer];
MTLRenderPassDescriptor *passDescriptor = [MTLRenderPassDescriptor renderPassDescriptor];
{
auto attachment = [passDescriptor.colorAttachments objectAtIndexedSubscript:0];
@ -854,7 +855,7 @@ void GHOST_ContextCGL::metalSwapBuffers()
}
if (!m_useMetalForRendering) {
id<MTLCommandBuffer> cmdBuffer = [m_metalCmdQueue commandBuffer];
id<MTLCommandBuffer> cmdBuffer = [s_sharedMetalCommandQueue commandBuffer];
{
assert(m_defaultFramebufferMetalTexture[current_swapchain_index].texture != nil);
id<MTLRenderCommandEncoder> enc = [cmdBuffer
@ -896,7 +897,7 @@ void GHOST_ContextCGL::initClear()
#if WITH_METAL
// TODO (mg_gpusw_apple) this path is never taken, this is legacy left from inital integration
// of metal and gl, the whole file should be cleaned up and stripped of the legacy path
id<MTLCommandBuffer> cmdBuffer = [m_metalCmdQueue commandBuffer];
id<MTLCommandBuffer> cmdBuffer = [s_sharedMetalCommandQueue commandBuffer];
MTLRenderPassDescriptor *passDescriptor = [MTLRenderPassDescriptor renderPassDescriptor];
{
auto attachment = [passDescriptor.colorAttachments objectAtIndexedSubscript:0];

View File

@ -429,8 +429,7 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG])
- (void)applicationWillTerminate:(NSNotification *)aNotification
{
#if 0
G.is_break = false; /* Let Cocoa perform the termination at the end. */
WM_exit(C);
WM_exit(C, EXIT_SUCCESS);
#endif
}

View File

@ -143,6 +143,11 @@ GHOST_SystemWin32::GHOST_SystemWin32()
* blurry scaling and enables WM_DPICHANGED to allow us to draw at proper DPI. */
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
/* Set App Id for the process so our console will be grouped on the Task Bar. */
UTF16_ENCODE(BLENDER_WIN_APPID);
SetCurrentProcessExplicitAppUserModelID(BLENDER_WIN_APPID_16);
UTF16_UN_ENCODE(BLENDER_WIN_APPID);
/* Check if current keyboard layout uses AltGr and save keylayout ID for
* specialized handling if keys like VK_OEM_*. I.e. french keylayout
* generates #VK_OEM_8 for their exclamation key (key left of right shift). */
@ -1867,9 +1872,10 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, uint msg, WPARAM wParam,
/* Mouse Tracking is now off. TrackMouseEvent restarts in MouseMove. */
window->m_mousePresent = false;
/* Auto-focus only occurs within Blender windows, not with _other_ applications. */
/* Auto-focus only occurs within Blender windows, not with _other_ applications. We are
* notified of change of focus from our console, but it returns null from GetFocus. */
HWND old_hwnd = ::GetFocus();
if (hwnd != old_hwnd) {
if (old_hwnd && hwnd != old_hwnd) {
HWND new_parent = ::GetParent(hwnd);
HWND old_parent = ::GetParent(old_hwnd);
if (hwnd == old_parent || old_hwnd == new_parent) {

View File

@ -34,8 +34,8 @@
#include <Eigen/SVD>
#if !defined(__MINGW64__)
# if defined(_WIN32) || defined(__APPLE__) || defined(__FreeBSD__) || \
defined(__NetBSD__) || defined(__HAIKU__)
# if defined(_WIN32) || defined(__APPLE__) || defined(__NetBSD__) || \
defined(__HAIKU__)
inline void sincos(double x, double* sinx, double* cosx) {
*sinx = sin(x);
*cosx = cos(x);

View File

@ -35,7 +35,6 @@ https://github.com/AcademySoftwareFoundation/MaterialX
https://software.intel.com/en-us/oneapi/onetbb
** OpenCL Wrangler; version 27a6867 -- https://github.com/OpenCLWrangler/clew
** OpenImageDenoise; version 1.4.3 -- https://www.openimagedenoise.org/
** OpenSSL; version 1.1.1q -- https://www.openssl.org/
** OpenXR SDK; version 1.0.17 -- https://khronos.org/openxr
** RangeTree; version 40ebed8aa209 -- https://github.com/ideasman42/rangetree-c
** SDL Extension Wrangler; version 15edf8e --
@ -269,9 +268,6 @@ limitations under the License.
Written by George van Venrooij
* For OpenImageDenoise see also this required NOTICE:
Copyright 2009-2020 Intel Corporation
* For OpenSSL see also this required NOTICE:
Copyright (c) 1998-2021 The OpenSSL Project
Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
* For OpenXR SDK see also this required NOTICE:
Copyright (c) 2017-2020 The Khronos Group Inc.
Copyright (c) 2017-2019 Valve Corporation
@ -4244,6 +4240,129 @@ MIT Expat
------
** OpenSSL; version 1.1.1q -- https://www.openssl.org/
Copyright (c) 1998-2021 The OpenSSL Project
Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
OpenSSL License
---------------
/* ====================================================================
* Copyright (c) 1998-2019 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
Original SSLeay License
-----------------------
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
------
** Python; version 3.10.9 -- https://www.python.org
Copyright (c) 2001-2021 Python Software Foundation. All rights reserved.

View File

@ -1,95 +1,33 @@
This version of Blender has been originally released at www.blender.org.
It is subject to the GNU GPL license, which is part of this download.
For more information please review the Blender source code distribution,
which should be available at the same location as where you obtained
this version.
IMPORTANT: PLEASE READ CAREFULLY BEFORE USING THE BLENDER SOFTWARE
This License Agreement for the Blender software ("License
Agreement") is an agreement between Stichting Blender Foundation,
Amsterdam, the Netherlands ("BF") and you (either an individual or a
legal entity) ("You") with respect to the software product which this
License Agreement accompanies (the "Software").
By installing, copying or otherwise using the Software, You agree to be
bound by the terms of this License Agreement.
1. Grant of License
Subject to the provisions of the GNU GPL license, BF grants You a
non-exclusive right to use the Software at any computer You own or use.
Artwork you create with the Software - whether it is images, movies,
exported 3d files or the .blend files themselves - is your sole
property, and can be licensed or sold under any conditions you prefer.
Blender, the free and open source 3D creation suite
Copyright (C) 2023 Blender Foundation
2. Permitted copying and electronic distribution of Software
You are hereby granted permission to copy and distribute the Software
without written agreement from BF. This entire License Agreement, and
the GPL-license.txt must appear in and/or accompany all copies of the
Software. The source code distribution, which can be found at the same
location where you obtained the Software, has to accompany all copies
of the Software as well.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
3. Disclaimer of Warranties
BF provides you with the Software "as is" and with all faults. BF
explicitly disclaims all warranties and guarantees and does not make any
representations with respect to the Software, whether express, implied,
or statutory, including, but not limited to any (if any) warranties of
or related to: fitness for a particular purpose, title,
non-infringement, lack of viruses, accuracy or completeness of
responses, results, lack of negligence or lack of workmanlike effort,
and correspondence to description. The entire risk arising out of use or
performance of the Software remains with You.
4. Limitation of Liability
In no event shall BF or its employees, agents or suppliers be liable
for any direct, indirect, consequential, incidental, special, punitive,
or other damages whatsoever (including, without limitation, damages for
loss of business profits, business interruption, loss of business
information, claims of third parties, damages as a result of injury to
any person, or any other loss) arising out of or in connection with the
license granted under this License Agreement or the use of or inability
to use the Software, even if BF has been advised of the possibility of
such damages.
5. User warning and indemnification
WARNING: use of the Software and use of any works that are (partially)
created with the Software (the "Works") may cause physical or
psychological reactions from You or from third parties, which may result
in damages, injuries, losses and/or other negative consequences. You
acknowledge that BF can not be held liable for any such damages,
injuries, losses and/or other negative consequences. You acknowledge
that it is your obligation to investigate, prevent and/or minimize such
reactions prior to having third parties use the Works.
You shall indemnify and hold harmless BF from and against all actions,
claims, demands, proceedings, losses, damages, costs, charges and
expenses, including but not limited to legal fees and expenses, arising
out of or in connection with (i) the use of the Software by You and (ii)
the use of any Works created with the Software by You or any third
parties.
6. Enforceability
If any provision of this License Agreement is held to be unenforceable
by a court of competent jurisdiction for any reason, such provision
shall be adapted or amended only to the extent necessary to make it
enforceable, and the remainder of the License Agreement shall remain in
effect.
7. Governing law and disputes
This License Agreement and all disputes arising from it will be governed
by the laws of The Netherlands. All disputes arising in connection with
this Agreement that cannot be settled amicably shall be brought before
the competent court in Amsterdam, the Netherlands, to which jurisdiction
BF and You hereby irrevocably consent.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
The Blender project uses code and libraries which are licensed under terms of
licenses which are compatible with the GNU GPL 3 or later.
The license of each individual Blender source file can be found in the first
few lines after "SPDX-License-Identifier:". The license text of every such
license can be found in license/.
The complete overview of copyright and licenses of third-party libraries used
by Blender can be found in THIRD-PARTY-LICENSES.txt.
Stichting Blender Foundation
Amsterdam

View File

@ -127,8 +127,10 @@ def clean_name(name, *, replace="_"):
Returns a name with characters replaced that
may cause problems under various circumstances,
such as writing to a file.
All characters besides A-Z/a-z, 0-9 are replaced with "_"
or the *replace* argument if defined.
:arg name: The path name.
:type name: string or bytes
:arg replace: The replacement for non-valid characters.
@ -233,6 +235,7 @@ def display_name_to_filepath(name):
"""
Performs the reverse of display_name using literal versions of characters
which aren't supported in a filepath.
:arg name: The display name to convert.
:type name: string
:return: The file path.
@ -247,6 +250,7 @@ def display_name_from_filepath(name):
"""
Returns the path stripped of directory and extension,
ensured to be utf8 compatible.
:arg name: The file path to convert.
:type name: string
:return: The display name.
@ -262,6 +266,7 @@ def resolve_ncase(path):
"""
Resolve a case insensitive path on a case sensitive system,
returning a string with the path if found else return the original path.
:arg path: The path name to resolve.
:type path: string
:return: The resolved path.
@ -390,6 +395,7 @@ def basename(path):
Equivalent to ``os.path.basename``, but skips a "//" prefix.
Use for Windows compatibility.
:return: The base name of the given path.
:rtype: string
"""
@ -399,6 +405,7 @@ def basename(path):
def native_pathsep(path):
"""
Replace the path separator with the systems native ``os.sep``.
:arg path: The path to replace.
:type path: string
:return: The path with system native separators.

View File

@ -382,6 +382,7 @@ def load():
use_alt_click_leader=kc_prefs.use_alt_click_leader,
use_pie_click_drag=kc_prefs.use_pie_click_drag,
use_file_single_click=kc_prefs.use_file_single_click,
experimental=prefs.experimental,
use_transform_navigation=kc_prefs.use_transform_navigation,
),
)

View File

@ -95,6 +95,8 @@ class Params:
# Since this means with RMB select enabled in edit-mode for e.g.
# `Ctrl-LMB` would be caught by box-select instead of add/extrude.
"tool_maybe_tweak_event",
# Access to bpy.context.preferences.experimental
"experimental",
# Changes some transformers modal key-map items to avoid conflicts with navigation operations
"use_transform_navigation",
)
@ -124,6 +126,7 @@ class Params:
use_file_single_click=False,
v3d_tilde_action='VIEW',
v3d_alt_mmb_drag_action='RELATIVE',
experimental=None,
use_transform_navigation=False,
):
from sys import platform
@ -225,6 +228,8 @@ class Params:
self.tool_maybe_tweak_event = {"type": self.tool_mouse, "value": self.tool_maybe_tweak_value}
self.use_transform_navigation = use_transform_navigation
self.experimental = experimental
# ------------------------------------------------------------------------------
# Constants
@ -3830,18 +3835,31 @@ def km_grease_pencil_stroke_paint_draw_brush(params):
{"items": items},
)
# Draw
if params.experimental and params.experimental.use_grease_pencil_version3:
items.extend([
("grease_pencil.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS'},
{"properties": [("mode", 'NORMAL')]}),
("grease_pencil.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
{"properties": [("mode", 'INVERT')]}),
("grease_pencil.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
{"properties": [("mode", 'SMOOTH')]}),
])
else:
items.extend([
("gpencil.draw", {"type": 'LEFTMOUSE', "value": 'PRESS'},
{"properties": [("mode", 'DRAW'), ("wait_for_input", False)]}),
("gpencil.draw", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
{"properties": [("mode", 'DRAW'), ("wait_for_input", False)]}),
# Draw - straight lines
("gpencil.draw", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True},
{"properties": [("mode", 'DRAW_STRAIGHT'), ("wait_for_input", False)]}),
# Erase
("gpencil.draw", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
{"properties": [("mode", 'ERASER'), ("wait_for_input", False)]}),
])
items.extend([
# Draw
("gpencil.draw", {"type": 'LEFTMOUSE', "value": 'PRESS'},
{"properties": [("mode", 'DRAW'), ("wait_for_input", False)]}),
("gpencil.draw", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
{"properties": [("mode", 'DRAW'), ("wait_for_input", False)]}),
# Draw - straight lines
("gpencil.draw", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True},
{"properties": [("mode", 'DRAW_STRAIGHT'), ("wait_for_input", False)]}),
# Erase
("gpencil.draw", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
{"properties": [("mode", 'ERASER'), ("wait_for_input", False)]}),
# Constrain Guides Speedlines
# Freehand
("gpencil.draw", {"type": 'O', "value": 'PRESS'}, None),

View File

@ -424,6 +424,7 @@ class NODE_MT_geometry_node_mesh_topology(Menu):
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "GeometryNodeCornersOfEdge")
node_add_menu.add_node_type(layout, "GeometryNodeCornersOfFace")
node_add_menu.add_node_type(layout, "GeometryNodeCornersOfVertex")
node_add_menu.add_node_type(layout, "GeometryNodeEdgesOfCorner")

View File

@ -500,6 +500,8 @@ class GreasePencilMaterialsPanel:
show_full_ui = (self.bl_space_type == 'PROPERTIES')
is_view3d = (self.bl_space_type == 'VIEW_3D')
is_grease_pencil_version3 = context.preferences.experimental.use_grease_pencil_version3
tool_settings = context.scene.tool_settings
gpencil_paint = tool_settings.gpencil_paint
brush = gpencil_paint.brush if gpencil_paint else None
@ -550,7 +552,7 @@ class GreasePencilMaterialsPanel:
icon_link = 'MESH_DATA' if slot.link == 'DATA' else 'OBJECT_DATA'
row.prop(slot, "link", icon=icon_link, icon_only=True)
if ob.data.use_stroke_edit_mode:
if not is_grease_pencil_version3 and ob.data.use_stroke_edit_mode:
row = layout.row(align=True)
row.operator("gpencil.stroke_change_color", text="Assign")
row.operator("gpencil.material_select", text="Select").deselect = False

View File

@ -1970,6 +1970,13 @@ class _defs_gpencil_paint:
@staticmethod
def generate_from_brushes(context):
if context and context.preferences.experimental.use_grease_pencil_version3:
return tuple([ToolDef.from_dict(dict(
idname="builtin_brush.draw",
label="Draw",
icon="brush.gpencil_draw.draw",
data_block='DRAW',
))])
return generate_from_enum_ex(
context,
idname_prefix="builtin_brush.",

View File

@ -476,7 +476,7 @@ class TOPBAR_MT_file_import(Menu):
if bpy.app.build_options.io_wavefront_obj:
self.layout.operator("wm.obj_import", text="Wavefront (.obj)")
if bpy.app.build_options.io_ply:
self.layout.operator("wm.ply_import", text="Stanford PLY (.ply) (experimental)")
self.layout.operator("wm.ply_import", text="Stanford PLY (.ply)")
if bpy.app.build_options.io_stl:
self.layout.operator("wm.stl_import", text="STL (.stl) (experimental)")
@ -506,7 +506,7 @@ class TOPBAR_MT_file_export(Menu):
if bpy.app.build_options.io_wavefront_obj:
self.layout.operator("wm.obj_export", text="Wavefront (.obj)")
if bpy.app.build_options.io_ply:
self.layout.operator("wm.ply_export", text="Stanford PLY (.ply) (experimental)")
self.layout.operator("wm.ply_export", text="Stanford PLY (.ply)")
class TOPBAR_MT_file_external_data(Menu):

View File

@ -2398,6 +2398,7 @@ class USERPREF_PT_experimental_prototypes(ExperimentalPanel, Panel):
({"property": "use_full_frame_compositor"}, ("blender/blender/issues/88150", "#88150")),
({"property": "enable_eevee_next"}, ("blender/blender/issues/93220", "#93220")),
({"property": "enable_workbench_next"}, ("blender/blender/issues/101619", "#101619")),
({"property": "use_grease_pencil_version3"}, ("blender/blender/projects/40", "Grease Pencil 3.0")),
({"property": "enable_overlay_next"}, ("blender/blender/issues/102179", "#102179")),
),
)

View File

@ -1981,7 +1981,7 @@ class VIEW3D_MT_paint_gpencil(Menu):
layout.operator("gpencil.vertex_color_brightness_contrast", text="Brightness/Contrast")
class VIEW3D_MT_select_gpencil(Menu):
class VIEW3D_MT_select_edit_gpencil(Menu):
bl_label = "Select"
def draw(self, context):
@ -2303,6 +2303,16 @@ class VIEW3D_MT_volume_add(Menu):
icon='OUTLINER_DATA_VOLUME')
class VIEW3D_MT_grease_pencil_add(Menu):
bl_idname = "VIEW3D_MT_grease_pencil_add"
bl_label = "Grease Pencil"
def draw(self, _context):
layout = self.layout
layout.operator("object.grease_pencil_add", text="Empty", icon='EMPTY_AXIS').type = 'EMPTY'
layout.operator("object.grease_pencil_add", text="Stroke", icon='STROKE').type = 'STROKE'
class VIEW3D_MT_add(Menu):
bl_label = "Add"
bl_translation_context = i18n_contexts.operator_default
@ -2328,7 +2338,14 @@ class VIEW3D_MT_add(Menu):
if context.preferences.experimental.use_new_point_cloud_type:
layout.operator("object.pointcloud_add", text="Point Cloud", icon='OUTLINER_OB_POINTCLOUD')
layout.menu("VIEW3D_MT_volume_add", text="Volume", text_ctxt=i18n_contexts.id_id, icon='OUTLINER_OB_VOLUME')
layout.operator_menu_enum("object.gpencil_add", "type", text="Grease Pencil", icon='OUTLINER_OB_GREASEPENCIL')
if context.preferences.experimental.use_grease_pencil_version3:
layout.menu("VIEW3D_MT_grease_pencil_add", text="Grease Pencil", icon='OUTLINER_OB_GREASEPENCIL')
else:
layout.operator_menu_enum(
"object.gpencil_add",
"type",
text="Grease Pencil",
icon='OUTLINER_OB_GREASEPENCIL')
layout.separator()
@ -5414,6 +5431,13 @@ class VIEW3D_MT_edit_gpencil_showhide(Menu):
layout.operator("gpencil.hide", text="Hide Inactive Layers").unselected = True
class VIEW3D_MT_edit_greasepencil(Menu):
bl_label = "Grease Pencil"
def draw(self, _context):
pass
class VIEW3D_MT_edit_curves(Menu):
bl_label = "Curves"
@ -8163,7 +8187,7 @@ classes = (
VIEW3D_MT_edit_lattice_context_menu,
VIEW3D_MT_select_edit_lattice,
VIEW3D_MT_select_edit_armature,
VIEW3D_MT_select_gpencil,
VIEW3D_MT_select_edit_gpencil,
VIEW3D_MT_select_paint_mask,
VIEW3D_MT_select_paint_mask_vertex,
VIEW3D_MT_edit_curves_select_more_less,
@ -8181,6 +8205,7 @@ classes = (
VIEW3D_MT_lightprobe_add,
VIEW3D_MT_camera_add,
VIEW3D_MT_volume_add,
VIEW3D_MT_grease_pencil_add,
VIEW3D_MT_add,
VIEW3D_MT_image_add,
VIEW3D_MT_object,
@ -8267,6 +8292,7 @@ classes = (
VIEW3D_MT_gpencil_simplify,
VIEW3D_MT_gpencil_autoweights,
VIEW3D_MT_gpencil_edit_context_menu,
VIEW3D_MT_edit_greasepencil,
VIEW3D_MT_edit_curve,
VIEW3D_MT_edit_curve_ctrlpoints,
VIEW3D_MT_edit_curve_segments,

View File

@ -1,5 +1,6 @@
# SPDX-FileCopyrightText: 2006 Blender Foundation
#
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright 2006 Blender Foundation
if(WITH_LEGACY_OPENGL)
add_definitions(-DWITH_LEGACY_OPENGL)

View File

@ -1,5 +1,6 @@
# SPDX-FileCopyrightText: 2006 Blender Foundation
#
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright 2006 Blender Foundation
set(SRC_DNA_INC
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_ID.h
@ -32,6 +33,7 @@ set(SRC_DNA_INC
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpencil_legacy_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpencil_modifier_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpu_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_grease_pencil_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

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system
@ -36,8 +38,10 @@ class AssetStorage;
*/
class AssetLibrary {
eAssetLibraryType library_type_;
/** The name this asset library will be displayed in the UI as. Will also be used as a weak way
* to identify an asset library (e.g. by #AssetWeakReference). */
/**
* The name this asset library will be displayed in the UI as. Will also be used as a weak way
* to identify an asset library (e.g. by #AssetWeakReference).
*/
std::string name_;
/** If this is an asset library on disk, the top-level directory path. Normalized using
* #normalize_directory_path(). Shared pointer so assets can safely point to it, and don't have
@ -45,7 +49,8 @@ class AssetLibrary {
* optimization is used). With thousands of assets this might make a reasonable difference. */
std::shared_ptr<std::string> root_path_;
/** Storage for assets (better said their representations) that are considered to be part of this
/**
* Storage for assets (better said their representations) that are considered to be part of this
* library. Assets are not automatically loaded into this when loading an asset library. Assets
* have to be loaded externally and added to this storage via #add_external_asset() or
* #add_local_id_asset(). So this really is arbitrary storage as far as #AssetLibrary is
@ -122,13 +127,15 @@ class AssetLibrary {
std::unique_ptr<AssetMetaData> metadata);
/** See #AssetLibrary::add_external_asset(). */
AssetRepresentation &add_local_id_asset(StringRef relative_asset_path, ID &id);
/** Remove an asset from the library that was added using #add_external_asset() or
/**
* Remove an asset from the library that was added using #add_external_asset() or
* #add_local_id_asset(). Can usually be expected to be constant time complexity (worst case may
* differ).
* \note This is save to call if \a asset is freed (dangling reference), will not perform any
* change then.
* \return True on success, false if the asset couldn't be found inside the library (also the
* case when the reference is dangling). */
* case when the reference is dangling).
*/
bool remove_asset(AssetRepresentation &asset);
/**
@ -143,7 +150,8 @@ class AssetLibrary {
*
* No-op if the catalog cannot be found. This could be the kind of "the
* catalog definition file is corrupt/lost" scenario that the simple name is
* meant to help recover from. */
* meant to help recover from.
*/
void refresh_catalog_simplename(AssetMetaData *asset_data);
void on_blend_save_handler_register();

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system
@ -30,8 +32,10 @@ class AssetLibrary;
class AssetRepresentation {
AssetIdentifier identifier_;
/** Indicate if this is a local or external asset, and as such, which of the union members below
* should be used. */
/**
* Indicate if this is a local or external asset, and as such, which of the union members below
* should be used.
*/
const bool is_local_id_ = false;
/** Asset library that owns this asset representation. */
const AssetLibrary *owner_asset_library_;
@ -53,8 +57,10 @@ class AssetRepresentation {
StringRef name,
std::unique_ptr<AssetMetaData> metadata,
const AssetLibrary &owner_asset_library);
/** Constructs an asset representation for an ID stored in the current file. This makes the asset
* local and fully editable. */
/**
* Constructs an asset representation for an ID stored in the current file. This makes the asset
* local and fully editable.
*/
AssetRepresentation(AssetIdentifier &&identifier,
ID &id,
const AssetLibrary &owner_asset_library);
@ -71,7 +77,8 @@ class AssetRepresentation {
const AssetIdentifier &get_identifier() const;
/** Create a weak reference for this asset that can be written to files, but can break under a
/**
* Create a weak reference for this asset that can be written to files, but can break under a
* number of conditions.
* A weak reference can only be created if an asset representation is owned by an asset library.
*/
@ -79,18 +86,23 @@ class AssetRepresentation {
StringRefNull get_name() const;
AssetMetaData &get_metadata() const;
/** Get the import method to use for this asset. A different one may be used if
/**
* Get the import method to use for this asset. A different one may be used if
* #may_override_import_method() returns true, otherwise, the returned value must be used. If
* there is no import method predefined for this asset no value is returned.
*/
std::optional<eAssetImportMethod> get_import_method() const;
/** Returns if this asset may be imported with an import method other than the one returned by
/**
* Returns if this asset may be imported with an import method other than the one returned by
* #get_import_method(). Also returns true if there is no predefined import method
* (when #get_import_method() returns no value). */
* (when #get_import_method() returns no value).
*/
bool may_override_import_method() const;
bool get_use_relative_path() const;
/** If this asset is stored inside this current file (#is_local_id() is true), this returns the
* ID's pointer, otherwise null. */
/**
* If this asset is stored inside this current file (#is_local_id() is true), this returns the
* ID's pointer, otherwise null.
*/
ID *local_id() const;
/** Returns if this asset is stored inside this current file, and as such fully editable. */
bool is_local_id() const;
@ -103,9 +115,11 @@ class AssetRepresentation {
struct AssetRepresentation;
std::string AS_asset_representation_full_path_get(const ::AssetRepresentation *asset);
/** Get the absolute path to the .blend file containing the given asset. String will be empty if
/**
* Get the absolute path to the .blend file containing the given asset. String will be empty if
* the asset could not be mapped to a valid .blend file path. Valid in this case also means that
* the file needs to exist on disk. */
* the file needs to exist on disk.
*/
std::string AS_asset_representation_full_library_path_get(const ::AssetRepresentation *asset);
std::optional<eAssetImportMethod> AS_asset_representation_import_method_get(
const ::AssetRepresentation *asset_handle);

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system

View File

@ -1,3 +1,5 @@
# SPDX-FileCopyrightText: 2023 Blender Foundation
#
# SPDX-License-Identifier: GPL-2.0-or-later
set(INC

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system

View File

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2020 Blender Foundation */
/* SPDX-FileCopyrightText: 2020 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "AS_asset_catalog_path.hh"

View File

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2020 Blender Foundation */
/* SPDX-FileCopyrightText: 2020 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "AS_asset_catalog.hh"
#include "AS_asset_catalog_tree.hh"

View File

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2020 Blender Foundation */
/* SPDX-FileCopyrightText: 2020 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "AS_asset_catalog.hh"
#include "AS_asset_catalog_tree.hh"

View File

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2020 Blender Foundation */
/* SPDX-FileCopyrightText: 2020 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "asset_library_service.hh"

View File

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2020 Blender Foundation */
/* SPDX-FileCopyrightText: 2020 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "AS_asset_catalog.hh"
#include "AS_asset_library.h"

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: Apache-2.0 */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: Apache-2.0 */
#pragma once

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "asset_library_service.hh"
#include "asset_library_test_common.hh"

View File

@ -1,5 +1,6 @@
# SPDX-FileCopyrightText: 2006 Blender Foundation
#
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright 2006 Blender Foundation
# -----------------------------------------------------------------------------
# Shared Thumbnail Extraction Logic

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup blendthumb

View File

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2008-2021 Blender Foundation */
/* SPDX-FileCopyrightText: 2008-2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup blendthumb

View File

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2008 Blender Foundation */
/* SPDX-FileCopyrightText: 2008 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup blendthumb

View File

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2008 Blender Foundation */
/* SPDX-FileCopyrightText: 2008 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup blendthumb

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup blendthumb

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup blendthumb

View File

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2009 Blender Foundation */
/* SPDX-FileCopyrightText: 2009 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup blf

Some files were not shown because too many files have changed in this diff Show More