Anim: thread remake_graph_transdata #119497

Merged
Christoph Lendenfeld merged 13 commits from ChrisLend/blender:thread_remake_transdata into main 2024-04-09 11:46:17 +02:00
412 changed files with 195020 additions and 6160 deletions
Showing only changes of commit 69b52d6176 - Show all commits

5
.gitmodules vendored
View File

@ -18,6 +18,11 @@
path = lib/windows_x64
url = https://projects.blender.org/blender/lib-windows_x64.git
branch = main
[submodule "lib/windows_arm64"]
update = none
path = lib/windows_arm64
url = https://projects.blender.org/blender/lib-windows_arm64.git
branch = main
[submodule "release/datafiles/assets"]
path = release/datafiles/assets
url = https://projects.blender.org/blender/blender-assets.git

View File

@ -529,9 +529,9 @@ set(MATERIALX_HASH fad8f4e19305fb2ee920cbff638f3560)
set(MATERIALX_HASH_TYPE MD5)
set(MATERIALX_FILE materialx-v${MATERIALX_VERSION}.tar.gz)
set(OIDN_VERSION 2.2.1)
set(OIDN_VERSION 2.2.2)
set(OIDN_URI https://github.com/OpenImageDenoise/oidn/releases/download/v${OIDN_VERSION}/oidn-${OIDN_VERSION}.src.tar.gz)
set(OIDN_HASH a1c5299b2b640a0e0569afcf405c82bf)
set(OIDN_HASH 40c04b0371334ab863230e99a587fd59)
set(OIDN_HASH_TYPE MD5)
set(OIDN_FILE oidn-${OIDN_VERSION}.src.tar.gz)

View File

@ -176,7 +176,6 @@ def main() -> None:
# Support version without a minor version "3" (add zero).
tuple((0, 0, 0))
)
python_version_str = "%d.%d" % python_version_number[:2]
# Get Blender version.
blender_version_str = str(make_utils.parse_blender_version())

View File

@ -1,6 +1,5 @@
"""
Using Python Argument Parsing
-----------------------------
**Using Python Argument Parsing**
This example shows how the Python ``argparse`` module can be used with a custom command.

View File

@ -1,6 +1,5 @@
"""
Custom Commands
---------------
**Custom Commands**
Registering commands makes it possible to conveniently expose command line
functionality via commands passed to (``-c`` / ``--command``).

View File

@ -9,4 +9,5 @@ requests==2.31.0
# Only needed to match the theme used for the official documentation.
# Without this theme, the default theme will be used.
sphinx_rtd_theme==1.3.0rc1
furo==2024.1.29
sphinx-basic-ng==1.0.0b2

View File

@ -252,8 +252,7 @@ def main():
name, tp = arg
tp_sub = None
else:
print(arg)
assert 0
assert False, "unreachable, unsupported 'arg' length found %d" % len(arg)
tp_str = ""
@ -322,8 +321,7 @@ def main():
# but think the idea is that that pointer is for any type?
tp_str = ":class:`bpy.types.bpy_struct`"
else:
print("Can't find", vars_dict_reverse[tp_sub])
assert 0
assert False, "unreachable, unknown type %r" % vars_dict_reverse[tp_sub]
elif tp == BMO_OP_SLOT_ELEMENT_BUF:
assert tp_sub is not None
@ -362,11 +360,9 @@ def main():
elif tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL:
tp_str += "unknown internal data, not compatible with python"
else:
print("Can't find", vars_dict_reverse[tp_sub])
assert 0
assert False, "unreachable, unknown type %r" % vars_dict_reverse[tp_sub]
else:
print("Can't find", vars_dict_reverse[tp])
assert 0
assert False, "unreachable, unknown type %r" % vars_dict_reverse[tp]
args_wash.append((name, default_value, tp_str, comment))
return args_wash

View File

@ -1929,22 +1929,30 @@ def write_sphinx_conf_py(basepath):
# The theme 'sphinx_rtd_theme' is no longer distributed with sphinx by default, only use when available.
fw(r"""
try:
__import__('sphinx_rtd_theme')
html_theme = 'sphinx_rtd_theme'
import furo
html_theme = "furo"
del furo
except ModuleNotFoundError:
pass
""")
if html_theme == "furo":
html_theme_options = {
"light_css_variables": {
"color-brand-primary": "#265787",
"color-brand-content": "#265787",
},
}
fw("if html_theme == 'sphinx_rtd_theme':\n")
fw(" html_theme_options = {\n")
fw(" 'display_version': False,\n")
# fw(" 'analytics_id': '',\n")
# fw(" 'collapse_navigation': True,\n")
fw(" 'sticky_navigation': False,\n")
fw(" 'navigation_depth': 1,\n")
fw(" 'includehidden': False,\n")
# fw(" 'titles_only': False\n")
fw(" }\n\n")
html_sidebars = {
"**": [
"sidebar/brand.html",
"sidebar/search.html",
"sidebar/scroll-start.html",
"sidebar/navigation.html",
"sidebar/scroll-end.html",
# "sidebar/variant-selector.html",
]
}
""")
# not helpful since the source is generated, adds to upload size.
fw("html_copy_source = False\n")
@ -1961,7 +1969,7 @@ except ModuleNotFoundError:
fw("html_logo = 'static/blender_logo.svg'\n")
# Disable default `last_updated` value, since this is the date of doc generation, not the one of the source commit.
fw("html_last_updated_fmt = None\n\n")
fw("if html_theme == 'sphinx_rtd_theme':\n")
fw("if html_theme == 'furo':\n")
fw(" html_css_files = ['css/version_switch.css']\n")
fw(" html_js_files = ['js/version_switch.js']\n")

View File

@ -1,19 +1,323 @@
/* Hide home icon in search area */
.wy-side-nav-search > a:hover {background: none; opacity: 0.9}
.wy-side-nav-search > a.icon::before {content: none}
/*
* This stylesheet is applied after the theme's default one,
* and thus any overrides or additions can be added here.
*
* More info:
* https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx.application.Sphinx.add_css_file
*/
.wy-nav-content {
max-width: 1000px !important;
body {
--sidebar-caption-font-size: var(--font-size--normal);
--toc-title-font-size: var(--font-size--normal);
--toc-font-size: var(--sidebar-item-font-size);
--admonition-font-size: var(--font-size--normal);
--admonition-title-font-size: var(--font-size--normal);
--color-api-name: #e87d0d;
}
/* Fix long titles on mobile */
h1, h2, h3, h4, h5, h6 {word-break: break-all}
h1,
h2,
h3 {
margin-top: 1.75rem;
margin-bottom: 1rem;
}
/* Temp fix for https://github.com/readthedocs/sphinx_rtd_theme/pull/1109 */
.hlist tr {
display: -ms-flexbox;
display: flex;
flex-flow: row wrap;
}
h1 {
font-size: 2em;
}
.hlist td {margin-right: auto}
h2 {
font-size: 1.5em;
}
h3 {
font-size: 1.25em;
}
h4,
h5,
h6,
.rubric {
margin-top: 1.25rem;
margin-bottom: 0.75rem;
font-size: 1.125em;
}
/* Reduce the margins on top/bottom of horizontal lines. */
hr.docutils {
margin: 1rem 0;
}
/* Slightly decrease text to make the text fit on one line */
.sidebar-brand-text {
font-size: 1.4rem;
}
.toctree-checkbox~label .icon svg {
transition: transform 0.25s ease-out;
}
/* Add more visual weight to definition terms */
dl dt {
font-weight: bold !important
}
/* Fixes to field list, see #104636 */
dl.field-list {
display: grid;
grid-template-columns: auto minmax(80%, 95%);
p {
margin-bottom: 0;
}
}
/* TABLE & FIGURE */
/* Cell's vertical align. */
/* use "valign" class for middle align */
table.docutils:not(.valign) td {
vertical-align: baseline;
}
/* Decrease whitespace above figure and add it below */
figure {
padding-bottom: 0.5rem;
}
figcaption {
margin-bottom: 0.5rem !important;
p {
margin-top: 0;
}
}
/* End TABLE & FIGURE. */
/* Force admonition to span the full width if close to a figure */
.admonition {
clear: both;
}
/* Use secondary font color for caption text */
figcaption,
caption {
color: var(--color-foreground-secondary);
font-size: var(--font-size--small)
}
/* A bit hacky, revert the themes styling of kbd */
kbd:not(.compound) {
all: revert;
}
/* Only style parent kbd elements instead of the individual children */
:not(dl.option-list)> :not(kbd):not(kbd)>kbd,
.menuselection {
background-color: var(--color-background-secondary);
border: 1px solid var(--color-foreground-border);
border-radius: .2rem;
box-shadow: 0 .0625rem 0 rgba(0, 0, 0, .2), inset 0 0 0 .125rem var(--color-background-secondary);
color: var(--color-foreground-primary);
display: inline-block;
margin: 0;
padding: 0 .2rem;
}
.highlight .nc,
.highlight .nn,
.highlight .gu {
text-decoration-line: none !important;
}
.caption .menuselection {
background-color: transparent;
border: none;
}
a {
text-decoration: none;
}
/* Quotes for Fig. "link". */
a[href^="#fig-"]::before {
content: "\201c";
}
a[href^="#fig-"]::after {
content: "\201d";
}
/* Mark external links. */
a.external {
filter: brightness(150%);
}
/* List blender.org as internal. */
.external[href^="https://www.blender.org"],
.external[href^="https://docs.blender.org"],
.external[href^="https://projects.blender.org"],
.external[href^="https://builder.blender.org"],
.external[href^="https://code.blender.org"],
.external[href^="https://translate.blender.org"],
.external[href^="https://fund.blender.org"],
.external[href^="blender_manual_html.zip"],
.external[href^="blender_manual_epub.zip"],
.external[href^="https://archive.blender.org"] {
filter: revert;
}
/* ".. container::" lead, block text float around image. */
.lead {
clear: both;
width: 100%;
}
/* Start reference admonition. */
.admonition.refbox {
border-color: rgb(50, 50, 50);
}
.admonition.refbox>.admonition-title {
background-color: rgba(50, 50, 50, 0.2);
border-color: rgb(50, 50, 50);
}
.admonition.refbox>.admonition-title::before {
background-color: var(--color-content-foreground);
}
/* 'refbox' field. */
.refbox .field-list .field-name,
.refbox .field-list .field-body {
padding: 0px;
}
.refbox dl dt {
font-weight: normal
}
/* End reference admonition. */
/* Applied on main index:sections. */
.global-index-toc {
display: none;
}
/* Start section cards. */
.toc-cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
grid-gap: 20px;
list-style-type: none;
margin-bottom: 24px;
}
.card {
border-radius: .3em;
user-select: none;
}
.card div.figure,
.card figure {
margin-bottom: 0px;
display: block;
}
.card img {
border-top-left-radius: .3em;
border-top-right-radius: .3em;
}
.card dl {
margin-bottom: 10px
}
.card dl dt>a {
display: block;
width: 100%;
margin-bottom: 10px;
}
.card dl dt a em,
.card dl dt a span {
font-weight: bold;
font-style: normal;
font-size: 1.3em;
}
.card dl dt {
padding: 0px 15px 0px !important
}
.card dl dd {
padding: 0px 15px 5px 15px;
font-style: normal;
margin: 0px;
color: var(--color-foreground-secondary);
font-size: 90%;
}
.card {
box-shadow: 0 .2rem .5rem rgba(0, 0, 0, .05), 0 0 .0625rem rgba(0, 0, 0, .1);
}
#getting-started .card {
box-shadow: none;
}
/* End section cards. */
/* Start custom toctree. */
/* Indent all lines following the first. */
.toctree-wrapper * a {
display: block;
padding-top: 0.25em;
}
.toctree-wrapper ul {
list-style: none;
padding-left: 0;
}
/* Underline provided by nested ul (not li). */
.toctree-wrapper * ul {
margin-bottom: 1rem !important;
border-top: solid var(--color-background-border) 1px;
padding-left: 2em;
}
/* End custom toctree. */
/* Start footer contribute link */
.footer-contribute {
display: block;
font-size: var(--font-size--small);
}
.bottom-of-page {
padding-bottom: 0;
}
.footer-contribute ul {
margin: 0;
padding: 0;
padding-bottom: 1rem
}
.footer-contribute li {
display: inline;
list-style-type: none;
padding-right: 1.5rem;
}
@media print {
.footer-contribute {
display: none;
}
}
/* End footer contribute link */

View File

@ -1,95 +1,98 @@
/* Override RTD theme */
.rst-versions {
display: none;
border-top: 0px;
overflow: visible;
}
.version-btn.vdeact {
cursor: default;
color: dimgray;
}
.version-btn.vdeact::after {
content: "";
}
#versionwrap {
margin: 0;
display: flex;
padding-top: 2px;
font-size: 90%;
padding-left: 0;
font-size: var(--sidebar-item-font-size);
justify-content: center;
flex-wrap: wrap;
}
#versionwrap>ul {
list-style: none;
}
#versionwrap>li {
display: flex;
width: 50%;
}
.version-btn {
display: inline-block;
background-color: #272525;
width: 140px;
background-color: var(--color-sidebar-background);
width: 100%;
text-align: center;
padding: 3px 10px;
margin: 0px 5px 4px;
vertical-align: middle;
color: #27AE60;
border: solid 1px #444444;
color: var(--color-link);
border: solid 1px var(--color-sidebar-background-border);
border-radius: 3px;
cursor: pointer;
z-index: 400;
transition: border-color 0.4s;
}
.version-btn::after {
content:"\f0d8";
display: inline;
font: normal normal normal 16px/1 FontAwesome;
color: #8d8c8c;
vertical-align: top;
padding-left: 0.5em;
}
.version-btn-open::after {
color: gray;
}
.version-btn:hover, .version-btn:focus {
.version-btn:hover,
.version-btn:focus {
border-color: #525252;
}
.version-btn-open {
color: gray;
border: solid 1px gray;
border: solid 1px var(--color-sidebar-background-border);
}
.version-btn.wait {
cursor: wait;
}
.version-btn.disabled {
cursor: not-allowed;
color: dimgray;
}
.version-dialog {
display: none;
position: absolute;
bottom: 28px;
width: 140px;
width: 50%;
margin: 0 5px;
padding-bottom: 4px;
background-color: #0003;
border-radius: 3px;
box-shadow: 0 0 6px #000C;
z-index: 999;
max-height: calc(100vh - 30px);
overflow-x: clip;
overflow-y: auto;
cursor: default;
}
.version-title {
padding: 5px;
color: black;
color: var(--color-content-foreground);
text-align: center;
font-size: 102%;
background-color: #27ae60;
border-bottom: solid 1.5px #444;
font-weight: 700;
background-color: var(--color-brand-primary);
border-bottom: solid 1.5px var(--color-sidebar-background-border);
}
.version-list {
padding-left: 0;
margin-top: 0;
margin-bottom: 4px;
text-align: center;
background-color: #000C;
border: solid 1px gray;
border: solid 1px var(--color-sidebar-background-border);
border-radius: 0px 0px 3px 3px;
}
.version-list a, .version-list span, .version-list li {
.version-list a,
.version-list span,
.version-list li {
position: relative;
display: block;
font-size: 98%;
@ -97,32 +100,21 @@
width: 100%;
margin: 0;
padding: 4px 0px;
color: #404040;
color: var(--color-sidebar-link-text);
}
.version-list li {
background-color: #ede9e9;
color: #404040;
background-color: var(--color-sidebar-background);
color: var(--color-sidebar-link-text);
padding: 1px;
}
.version-list li:hover, .version-list li a:focus {
background-color: #b9cfda;
.version-list li:hover,
.version-list li a:focus {
background-color: var(--color-background-hover);
}
.version-list li.selected, .version-list li.selected:hover {
background-color: #8d8c8c;
}
.version-list li.selected span {
cursor: default;
outline-color: red;
}
.version-arrow {
position: absolute;
width: 8px;
height: 8px;
left: 50%;
bottom: 4px;
margin-left: -4px;
transform: rotate(225deg);
background: #ede9e9;
border: 1px solid gray;
border-width: 1px 0 0 1px;
.version-list li.selected {
background: var(--color-sidebar-item-background--current);
font-weight: 700;
}

View File

@ -1,63 +1,60 @@
(function() { // switch: v1.2
(function() { // switch: v1.4
"use strict";
var versionsFileUrl = "https://docs.blender.org/PROD/versions.json"
var all_versions;
var Popover = function() {
function Popover(id)
class Popover {
constructor(id)
{
this.isOpen = false;
this.type = (id === "version-popover");
this.$btn = $('#' + id);
this.$dialog = this.$btn.next();
this.$list = this.$dialog.children("ul");
this.btn = document.querySelector('#' + id);
this.dialog = this.btn.nextElementSibling;
this.list = this.dialog.querySelector("ul");
this.sel = null;
this.beforeInit();
}
Popover.prototype = {
beforeInit : function() {
var that = this;
this.$btn.on("click", function(e) {
const that = this;
this.btnClickHandler = function(e) {
that.init();
e.preventDefault();
e.stopPropagation();
};
this.btnKeyHandler = function(e) {
if (that.btnKeyFilter(e)) {
that.init();
e.preventDefault();
e.stopPropagation();
});
this.$btn.on("keydown", function(e) {
if (that.btnKeyFilter(e)) {
that.init();
e.preventDefault();
e.stopPropagation();
}
});
},
init : function() {
this.$btn.off("click");
this.$btn.off("keydown");
}
};
this.btn.addEventListener("click", this.btnClickHandler);
this.btn.addEventListener("keydown", this.btnKeyHandler);
}
init()
{
this.btn.removeEventListener("click", this.btnClickHandler);
this.btn.removeEventListener("keydown", this.btnKeyHandler);
new Promise((resolve, reject) => {
if (all_versions === undefined) {
this.$btn.addClass("wait");
this.loadVL(this);
this.btn.classList.add("wait");
fetch(versionsFileUrl)
.then((response) => response.json())
.then((data) => {
all_versions = data;
resolve();
})
.catch(() => {
console.error("Version Switch Error: versions.json could not be loaded.");
this.btn.classList.remove("disabled");
});
}
else {
this.afterLoad();
resolve();
}
},
loadVL : function(that) {
$.getJSON(versionsFileUrl, function(data) {
all_versions = data;
that.afterLoad();
return true;
}).fail(function() {
console.log("Version Switch Error: versions.json could not be loaded.");
that.$btn.addClass("disabled");
return false;
});
},
afterLoad : function() {
var release = DOCUMENTATION_OPTIONS.VERSION;
}).then(() => {
let release = DOCUMENTATION_OPTIONS.VERSION;
const m = release.match(/\d\.\d+/g);
if (m) {
release = m[0];
@ -65,259 +62,274 @@ var Popover = function() {
this.warnOld(release, all_versions);
var version = this.getNamed(release);
var list = this.buildList(version);
const version = this.getNamed(release);
this.buildList(version);
this.$list.children(":first-child").remove();
this.$list.append(list);
var that = this;
this.$list.on("keydown", function(e) {
this.list.firstElementChild.remove();
const that = this;
this.list.addEventListener("keydown", function(e) {
that.keyMove(e);
});
this.$btn.removeClass("wait");
this.btn.classList.remove("wait");
this.btnOpenHandler();
this.$btn.on("mousedown", function(e) {
this.btn.addEventListener("mousedown", function(e) {
that.btnOpenHandler();
e.preventDefault()
});
this.$btn.on("keydown", function(e) {
this.btn.addEventListener("keydown", function(e) {
if (that.btnKeyFilter(e)) {
that.btnOpenHandler();
}
});
},
warnOld : function(release, all_versions) {
// Note this is effectively disabled now, two issues must fixed:
// * versions.js does not contain a current entry, because that leads to
// duplicate version numbers in the menu. These need to be deduplicated.
// * It only shows the warning after opening the menu to switch version
// when versions.js is loaded. This is too late to be useful.
var current = all_versions.current
if (!current)
{
// console.log("Version Switch Error: no 'current' in version.json.");
return;
}
const m = current.match(/\d\.\d+/g);
if (m) {
current = parseFloat(m[0]);
}
if (release < current) {
var currentURL = window.location.pathname.replace(release, current);
var warning = $('<div class="admonition warning"> ' +
'<p class="first admonition-title">Note</p> ' +
'<p class="last"> ' +
'You are not using the most up to date version of the documentation. ' +
'<a href="#"></a> is the newest version.' +
'</p>' +
'</div>');
warning.find('a').attr('href', currentURL).text(current);
var body = $("div.body");
if (!body.length) {
body = $("div.document");
}
body.prepend(warning);
}
},
buildList : function(v) {
var url = new URL(window.location.href);
let pathSplit = [ "", "api", v ];
if (url.pathname.startsWith("/api/")) {
pathSplit.push(url.pathname.split('/').slice(3).join('/'));
}
else {
pathSplit.push(url.pathname.substring(1));
}
if (this.type) {
var dyn = all_versions;
var cur = v;
}
var buf = [];
var that = this;
$.each(dyn, function(ix, title) {
buf.push("<li");
if (ix === cur) {
buf.push(
' class="selected" tabindex="-1" role="presentation"><span tabindex="-1" role="menuitem" aria-current="page">' +
title + '</spanp></li>');
}
else {
pathSplit[2 + that.type] = ix;
var href = new URL(url);
href.pathname = pathSplit.join('/');
buf.push(' tabindex="-1" role="presentation"><a href ="' + href + '" tabindex="-1">' +
title + '</a></li>');
}
});
return buf.join('');
},
getNamed : function(v) {
$.each(all_versions, function(ix, title) {
if (ix === "master" || ix === "main" || ix === "latest") {
var m = title.match(/\d\.\d[\w\d\.]*/)[0];
if (parseFloat(m) == v) {
v = ix;
return false;
}
}
});
return v;
},
dialogToggle : function(speed) {
var wasClose = !this.isOpen;
var that = this;
if (!this.isOpen) {
this.$btn.addClass("version-btn-open");
this.$btn.attr("aria-pressed", true);
this.$dialog.attr("aria-hidden", false);
this.$dialog.fadeIn(speed, function() {
that.$btn.parent().on("focusout", function(e) {
that.focusoutHandler();
e.stopImmediatePropagation();
})
that.$btn.parent().on("mouseleave", function(e) {
that.mouseoutHandler();
e.stopImmediatePropagation();
});
});
this.isOpen = true;
}
else {
this.$btn.removeClass("version-btn-open");
this.$btn.attr("aria-pressed", false);
this.$dialog.attr("aria-hidden", true);
this.$btn.parent().off("focusout");
this.$btn.parent().off("mouseleave");
this.$dialog.fadeOut(speed, function() {
if (this.$sel) {
this.$sel.attr("tabindex", -1);
}
that.$btn.attr("tabindex", 0);
if (document.activeElement !== null && document.activeElement !== document &&
document.activeElement !== document.body) {
that.$btn.focus();
}
});
this.isOpen = false;
}
if (wasClose) {
if (this.$sel) {
this.$sel.attr("tabindex", -1);
}
if (document.activeElement !== null && document.activeElement !== document &&
document.activeElement !== document.body) {
var $nw = this.listEnter();
$nw.attr("tabindex", 0);
$nw.focus();
this.$sel = $nw;
}
}
},
btnOpenHandler : function() {
this.dialogToggle(300);
},
focusoutHandler : function() {
var list = this.$list;
var that = this;
setTimeout(function() {
if (list.find(":focus").length === 0) {
that.dialogToggle(200);
}
}, 200);
},
mouseoutHandler : function() {
this.dialogToggle(200);
},
btnKeyFilter : function(e) {
if (e.ctrlKey || e.shiftKey) {
return false;
}
if (e.key === " " || e.key === "Enter" || (e.key === "ArrowDown" && e.altKey) ||
e.key === "ArrowDown" || e.key === "ArrowUp") {
return true;
}
return false;
},
keyMove : function(e) {
if (e.ctrlKey || e.shiftKey) {
return true;
}
var p = true;
var $nw = $(e.target);
switch (e.key) {
case "ArrowUp":
$nw = this.listPrev($nw);
break;
case "ArrowDown":
$nw = this.listNext($nw);
break;
case "Home":
$nw = this.listFirst();
break;
case "End":
$nw = this.listLast();
break;
case "Escape":
$nw = this.listExit();
break;
case "ArrowLeft":
$nw = this.listExit();
break;
case "ArrowRight":
$nw = this.listExit();
break;
default:
p = false;
}
if (p) {
$nw.attr("tabindex", 0);
$nw.focus();
if (this.$sel) {
this.$sel.attr("tabindex", -1);
}
this.$sel = $nw;
e.preventDefault();
e.stopPropagation();
}
},
listPrev : function($nw) {
if ($nw.parent().prev().length !== 0) {
return $nw.parent().prev().children(":first-child");
}
else {
return this.listLast();
}
},
listNext : function($nw) {
if ($nw.parent().next().length !== 0) {
return $nw.parent().next().children(":first-child");
}
else {
return this.listFirst();
}
},
listFirst : function() {
return this.$list.children(":first-child").children(":first-child");
},
listLast : function() {
return this.$list.children(":last-child").children(":first-child");
},
listExit : function() {
this.mouseoutHandler();
return this.$btn;
},
listEnter : function() {
return this.$list.children(":first-child").children(":first-child");
});
}
warnOld(release, all_versions)
{
// Note this is effectively disabled now, two issues must fixed:
// * versions.js does not contain a current entry, because that leads to
// duplicate version numbers in the menu. These need to be deduplicated.
// * It only shows the warning after opening the menu to switch version
// when versions.js is loaded. This is too late to be useful.
let current = all_versions.current
if (!current) {
// console.log("Version Switch Error: no 'current' in version.json.");
return;
}
};
return Popover
}();
const m = current.match(/\d\.\d+/g);
if (m) {
current = parseFloat(m[0]);
}
if (release < current) {
const currentURL = window.location.pathname.replace(release, current);
const warning =
document.querySelector("template#version-warning").firstElementChild.cloneNode(true);
const link = warning.querySelector('a');
link.setAttribute('href', currentURL);
link.textContent = current;
$(document).ready(function() {
var lng_popover = new Popover("version-popover");
});
let body = document.querySelector("div.body");
if (!body.length) {
body = document.querySelector("div.document");
}
body.prepend(warning);
}
}
buildList(v)
{
const url = new URL(window.location.href);
let pathSplit = [ "", "api", v ];
if (url.pathname.startsWith("/api/")) {
pathSplit.push(url.pathname.split('/').slice(4).join('/'));
}
else {
pathSplit.push(url.pathname.substring(1));
}
let dyn, cur;
if (this.type) {
dyn = all_versions;
cur = v;
}
const that = this;
const template = document.querySelector("template#version-entry").content;
for (let [ix, title] of Object.entries(dyn)) {
let clone;
if (ix === cur) {
clone = template.querySelector("li.selected").cloneNode(true);
clone.querySelector("span").innerHTML = title;
}
else {
pathSplit[1 + that.type] = ix;
let href = new URL(url);
href.pathname = pathSplit.join('/');
clone = template.firstElementChild.cloneNode(true);
const link = clone.querySelector("a");
link.href = href;
link.innerHTML = title;
}
that.list.append(clone);
};
return this.list;
}
getNamed(v)
{
for (let [ix, title] of Object.entries(all_versions)) {
if (ix === "master" || ix === "main" || ix === "latest") {
const m = title.match(/\d\.\d[\w\d\.]*/)[0];
if (parseFloat(m) == v) {
v = ix;
return false;
}
}
};
return v;
}
dialogToggle(speed)
{
const wasClose = !this.isOpen;
const that = this;
if (!this.isOpen) {
this.btn.classList.add("version-btn-open");
this.btn.setAttribute("aria-pressed", true);
this.dialog.setAttribute("aria-hidden", false);
this.dialog.style.display = "block";
this.dialog.animate({opacity : [ 0, 1 ], easing : [ 'ease-in', 'ease-out' ]}, speed)
.finished.then(() => {
this.focusoutHandlerPrime = function(e) {
that.focusoutHandler();
e.stopImmediatePropagation();
};
this.mouseoutHandlerPrime = function(e) {
that.mouseoutHandler();
e.stopImmediatePropagation();
};
this.btn.parentNode.addEventListener("focusout", this.focusoutHandlerPrime);
this.btn.parentNode.addEventListener("mouseleave", this.mouseoutHandlerPrime);
});
this.isOpen = true;
}
else {
this.btn.classList.remove("version-btn-open");
this.btn.setAttribute("aria-pressed", false);
this.dialog.setAttribute("aria-hidden", true);
this.btn.parentNode.removeEventListener("focusout", this.focusoutHandlerPrime);
this.btn.parentNode.removeEventListener("mouseleave", this.mouseoutHandlerPrime);
this.dialog.animate({opacity : [ 1, 0 ], easing : [ 'ease-in', 'ease-out' ]}, speed)
.finished.then(() => {
this.dialog.style.display = "none";
if (this.sel) {
this.sel.setAttribute("tabindex", -1);
}
this.btn.setAttribute("tabindex", 0);
if (document.activeElement !== null && document.activeElement !== document &&
document.activeElement !== document.body)
{
this.btn.focus();
}
});
this.isOpen = false;
}
if (wasClose) {
if (this.sel) {
this.sel.setAttribute("tabindex", -1);
}
if (document.activeElement !== null && document.activeElement !== document &&
document.activeElement !== document.body)
{
const nw = this.listEnter();
nw.setAttribute("tabindex", 0);
nw.focus();
this.sel = nw;
}
}
}
btnOpenHandler()
{
this.dialogToggle(300);
}
focusoutHandler()
{
const list = this.list;
const that = this;
setTimeout(function() {
if (!list.querySelector(":focus")) {
that.dialogToggle(200);
}
}, 200);
}
mouseoutHandler()
{
this.dialogToggle(200);
}
btnKeyFilter(e)
{
if (e.ctrlKey || e.shiftKey) {
return false;
}
if (e.key === " " || e.key === "Enter" || (e.key === "ArrowDown" && e.altKey) ||
e.key === "ArrowDown" || e.key === "ArrowUp")
{
return true;
}
return false;
}
keyMove(e)
{
if (e.ctrlKey || e.shiftKey) {
return true;
}
let nw = e.target;
switch (e.key) {
case "ArrowUp":
nw = this.listPrev(nw);
break;
case "ArrowDown":
nw = this.listNext(nw);
break;
case "Home":
nw = this.listFirst();
break;
case "End":
nw = this.listLast();
break;
case "Escape":
nw = this.listExit();
break;
case "ArrowLeft":
nw = this.listExit();
break;
case "ArrowRight":
nw = this.listExit();
break;
default:
return false;
}
nw.setAttribute("tabindex", 0);
nw.focus();
if (this.sel) {
this.sel.setAttribute("tabindex", -1);
}
this.sel = nw;
e.preventDefault();
e.stopPropagation();
}
listPrev(nw)
{
if (nw.parentNode.previousElementSibling.length !== 0) {
return nw.parentNode.previousElementSibling.firstElementChild;
}
else {
return this.listLast();
}
}
listNext(nw)
{
if (nw.parentNode.nextElementSibling.length !== 0) {
return nw.parentNode.nextElementSibling.firstElementChild;
}
else {
return this.listFirst();
}
}
listFirst()
{
return this.list.firstElementChild.firstElementChild;
}
listLast()
{
return this.list.lastElementChild.firstElementChild;
}
listExit()
{
this.mouseoutHandler();
return this.btn;
}
listEnter()
{
return this.list.firstElementChild.firstElementChild;
}
}
document.addEventListener('DOMContentLoaded', () => { new Popover("version-popover"); });
})();

View File

@ -0,0 +1,6 @@
{%- extends "!base.html" -%}
{%- block theme_scripts -%}
{{ super() }}
<script defer data-domain="docs.blender.org" src="https://analytics.blender.org/js/script.js"></script>
{%- endblock -%}

View File

@ -1,6 +1,3 @@
{# For the "Report Issue" button on the bottom of pages. #}
{%- extends "!footer.html" %}
{%- block extrafooter %}
{%- if not pagename in ("search", "404", "genindex") and hasdoc(pagename) %}
<div class="footer-contribute">
<ul>
@ -13,10 +10,9 @@
#}Permanent+Link%5D%28https%3A%2F%2Fdocs.blender.org%2F{#
#}api%2F{{ version }}%2F{{ pagename }}{{ file_suffix }}%29%0D%0A%0D%0A%2A%2A{#
#}Short+description+of+error%2A%2A%0D%0A%5B{#
#}Please+fill+out+a+short+description+of+the+error+here%5D%0D%0A"
class="fa fa-bug"> {{ _('Report issue on this page') }}</a>
#}Please+fill+out+a+short+description+of+the+error+here%5D%0D%0A" class="fa fa-bug"> {{ _('Report issue
on this page') }}</a>
</li>
</ul>
</div>
{%- endif %}
{% endblock %}
{%- endif %}

View File

@ -0,0 +1,6 @@
{%- extends "!page.html" -%}
{%- block footer -%}
{{ super() }}
{%- include "components/footer_contribute.html" -%}
{%- endblock footer -%}

View File

@ -0,0 +1,29 @@
<div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="document versions">
<ul id="versionwrap" role="presentation">
<li role="presentation">
<span id="version-popover" class="version-btn" tabindex="0" role="button" aria-label="versions selector"
aria-haspopup="true" aria-controls="version-vsnlist" aria-disabled="true">
{{ release }}
</span>
<div class="version-dialog" aria-hidden="true">
<div class="version-title">Versions</div>
<ul id="version-vsnlist" class="version-list" role="menu" aria-labelledby="version-popover" aria-hidden="true">
<li role="presentation">Loading...</li>
</ul>
</div>
</li>
<template id="version-entry">
<li tabindex="-1" role="presentation"><a tabindex="-1" role="menuitem"></a></li>
<li class="selected" tabindex="-1" role="presentation"><span tabindex="-1" aria-current="page"></span></li>
</template>
</ul>
<template id="version-warning">
<div class="admonition warning">
<p class="first admonition-title">Note</p>
<p class="last">
You are not using the most up to date version of the documentation.
<a href="#"></a> is the newest version.
</p>
</div>
</template>
</div>

View File

@ -1,19 +0,0 @@
<div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="document versions">
<ul id="versionwrap" role="presentation">
<li role="presentation">
<span id="version-popover" class="version-btn" tabindex="0" role="button"
aria-label="versions selector" aria-haspopup="true" aria-controls="version-vsnlist"
aria-disabled="true">
{{ release }}
</span>
<div class="version-dialog" aria-hidden="true">
<div class="version-arrow" aria-hidden="true"></div>
<div class="version-title">Versions</div>
<ul id="version-vsnlist" class="version-list" role="menu"
aria-labelledby="version-popover" aria-hidden="true">
<li role="presentation">Loading...</li>
</ul>
</div>
</li>
</ul>
</div>

1
extern/README vendored
View File

@ -1,4 +1,3 @@
When updating a library remember to:
* Update the README.blender with the corresponding version.
* Update the THIRD-PARTY-LICENSES.txt document

View File

@ -1594,14 +1594,15 @@ class CyclesPreferences(bpy.types.AddonPreferences):
compute_device_type = self.get_compute_device_type()
# We need non-CPU devices, used for rendering and supporting OIDN GPU denoising
for device in _cycles.available_devices(compute_device_type):
device_type = device[1]
if device_type == 'CPU':
continue
if compute_device_type != 'NONE':
for device in _cycles.available_devices(compute_device_type):
device_type = device[1]
if device_type == 'CPU':
continue
has_device_oidn_support = device[5]
if has_device_oidn_support and self.find_existing_device_entry(device).use:
return True
has_device_oidn_support = device[5]
if has_device_oidn_support and self.find_existing_device_entry(device).use:
return True
return False

View File

@ -29,7 +29,7 @@ BVHOptiX::~BVHOptiX()
{
/* Acceleration structure memory is delayed freed on device, since deleting the
* BVH may happen while still being used for rendering. */
device->release_optix_bvh(this);
device->release_bvh(this);
}
CCL_NAMESPACE_END

View File

@ -198,7 +198,7 @@ void device_cuda_info(vector<DeviceInfo> &devices)
VLOG_INFO << "Added device \"" << info.description << "\" with id \"" << info.id << "\".";
if (info.denoisers & DENOISER_OPENIMAGEDENOISE)
VLOG_INFO << "Device with id \"" << info.id << "\" is supporting "
VLOG_INFO << "Device with id \"" << info.id << "\" supports "
<< denoiserTypeToHumanReadable(DENOISER_OPENIMAGEDENOISE) << ".";
}

View File

@ -217,11 +217,10 @@ class Device {
/* Get OpenShadingLanguage memory buffer. */
virtual void *get_cpu_osl_memory();
/* acceleration structure building */
/* Acceleration structure building. */
virtual void build_bvh(BVH *bvh, Progress &progress, bool refit);
/* OptiX specific destructor. */
virtual void release_optix_bvh(BVH * /*bvh*/){};
/* Used by Metal and OptiX. */
virtual void release_bvh(BVH * /*bvh*/) {}
/* multi device */
virtual int device_number(Device * /*sub_device*/)

View File

@ -211,7 +211,7 @@ void device_hip_info(vector<DeviceInfo> &devices)
VLOG_INFO << "Added device \"" << info.description << "\" with id \"" << info.id << "\".";
if (info.denoisers & DENOISER_OPENIMAGEDENOISE)
VLOG_INFO << "Device with id \"" << info.id << "\" is supporting "
VLOG_INFO << "Device with id \"" << info.id << "\" supports "
<< denoiserTypeToHumanReadable(DENOISER_OPENIMAGEDENOISE) << ".";
}

View File

@ -28,9 +28,9 @@ class BVHMetal : public BVH {
API_AVAILABLE(macos(11.0))
vector<id<MTLAccelerationStructure>> unique_blas_array;
bool motion_blur = false;
Device *device = nullptr;
Stats &stats;
bool motion_blur = false;
bool build(Progress &progress, id<MTLDevice> device, id<MTLCommandQueue> queue, bool refit);

View File

@ -113,15 +113,18 @@ BVHMetal::BVHMetal(const BVHParams &params_,
const vector<Geometry *> &geometry_,
const vector<Object *> &objects_,
Device *device)
: BVH(params_, geometry_, objects_), stats(device->stats)
: BVH(params_, geometry_, objects_), device(device)
{
}
BVHMetal::~BVHMetal()
{
/* Clear point used by enqueueing. */
device->release_bvh(this);
if (@available(macos 12.0, *)) {
if (accel_struct) {
stats.mem_free(accel_struct.allocatedSize);
device->stats.mem_free(accel_struct.allocatedSize);
[accel_struct release];
}
@ -132,7 +135,7 @@ BVHMetal::~BVHMetal()
}
bool BVHMetal::build_BLAS_mesh(Progress &progress,
id<MTLDevice> device,
id<MTLDevice> mtl_device,
id<MTLCommandQueue> queue,
Geometry *const geom,
bool refit)
@ -163,7 +166,7 @@ bool BVHMetal::build_BLAS_mesh(Progress &progress,
}
MTLResourceOptions storage_mode;
if (device.hasUnifiedMemory) {
if (mtl_device.hasUnifiedMemory) {
storage_mode = MTLResourceStorageModeShared;
}
else {
@ -172,18 +175,19 @@ bool BVHMetal::build_BLAS_mesh(Progress &progress,
/* Upload the mesh data to the GPU */
id<MTLBuffer> posBuf = nil;
id<MTLBuffer> indexBuf = [device newBufferWithBytes:tris.data()
length:num_indices * sizeof(tris.data()[0])
options:storage_mode];
id<MTLBuffer> indexBuf = [mtl_device newBufferWithBytes:tris.data()
length:num_indices * sizeof(tris.data()[0])
options:storage_mode];
if (num_motion_steps == 1) {
posBuf = [device newBufferWithBytes:verts.data()
length:num_verts * sizeof(verts.data()[0])
options:storage_mode];
posBuf = [mtl_device newBufferWithBytes:verts.data()
length:num_verts * sizeof(verts.data()[0])
options:storage_mode];
}
else {
posBuf = [device newBufferWithLength:num_verts * num_motion_steps * sizeof(verts.data()[0])
options:storage_mode];
posBuf = [mtl_device
newBufferWithLength:num_verts * num_motion_steps * sizeof(verts.data()[0])
options:storage_mode];
float3 *dest_data = (float3 *)[posBuf contents];
size_t center_step = (num_motion_steps - 1) / 2;
for (size_t step = 0; step < num_motion_steps; ++step) {
@ -264,13 +268,14 @@ bool BVHMetal::build_BLAS_mesh(Progress &progress,
MTLAccelerationStructureUsagePreferFastBuild);
}
MTLAccelerationStructureSizes accelSizes = [device
MTLAccelerationStructureSizes accelSizes = [mtl_device
accelerationStructureSizesWithDescriptor:accelDesc];
id<MTLAccelerationStructure> accel_uncompressed = [device
id<MTLAccelerationStructure> accel_uncompressed = [mtl_device
newAccelerationStructureWithSize:accelSizes.accelerationStructureSize];
id<MTLBuffer> scratchBuf = [device newBufferWithLength:accelSizes.buildScratchBufferSize
options:MTLResourceStorageModePrivate];
id<MTLBuffer> sizeBuf = [device newBufferWithLength:8 options:MTLResourceStorageModeShared];
id<MTLBuffer> scratchBuf = [mtl_device newBufferWithLength:accelSizes.buildScratchBufferSize
options:MTLResourceStorageModePrivate];
id<MTLBuffer> sizeBuf = [mtl_device newBufferWithLength:8
options:MTLResourceStorageModeShared];
id<MTLCommandBuffer> accelCommands = [queue commandBuffer];
id<MTLAccelerationStructureCommandEncoder> accelEnc =
[accelCommands accelerationStructureCommandEncoder];
@ -314,14 +319,14 @@ bool BVHMetal::build_BLAS_mesh(Progress &progress,
id<MTLCommandBuffer> accelCommands = [queue commandBuffer];
id<MTLAccelerationStructureCommandEncoder> accelEnc =
[accelCommands accelerationStructureCommandEncoder];
id<MTLAccelerationStructure> accel = [device
id<MTLAccelerationStructure> accel = [mtl_device
newAccelerationStructureWithSize:compressed_size];
[accelEnc copyAndCompactAccelerationStructure:accel_uncompressed
toAccelerationStructure:accel];
[accelEnc endEncoding];
[accelCommands addCompletedHandler:^(id<MTLCommandBuffer> /*command_buffer*/) {
uint64_t allocated_size = [accel allocatedSize];
stats.mem_alloc(allocated_size);
device->stats.mem_alloc(allocated_size);
accel_struct = accel;
[accel_uncompressed release];
@ -336,7 +341,7 @@ bool BVHMetal::build_BLAS_mesh(Progress &progress,
accel_struct = accel_uncompressed;
uint64_t allocated_size = [accel_struct allocatedSize];
stats.mem_alloc(allocated_size);
device->stats.mem_alloc(allocated_size);
/* Signal that we've finished doing GPU acceleration struct build. */
g_bvh_build_throttler.release(wired_size);
@ -355,7 +360,7 @@ bool BVHMetal::build_BLAS_mesh(Progress &progress,
}
bool BVHMetal::build_BLAS_hair(Progress &progress,
id<MTLDevice> device,
id<MTLDevice> mtl_device,
id<MTLCommandQueue> queue,
Geometry *const geom,
bool refit)
@ -382,7 +387,7 @@ bool BVHMetal::build_BLAS_hair(Progress &progress,
}
MTLResourceOptions storage_mode;
if (device.hasUnifiedMemory) {
if (mtl_device.hasUnifiedMemory) {
storage_mode = MTLResourceStorageModeShared;
}
else {
@ -445,18 +450,18 @@ bool BVHMetal::build_BLAS_hair(Progress &progress,
}
/* Allocate and populate MTLBuffers for geometry. */
idxBuffer = [device newBufferWithBytes:idxData.data()
length:idxData.size() * sizeof(int)
options:storage_mode];
idxBuffer = [mtl_device newBufferWithBytes:idxData.data()
length:idxData.size() * sizeof(int)
options:storage_mode];
cpBuffer = [device newBufferWithBytes:cpData.data()
length:cpData.size() * sizeof(float3)
options:storage_mode];
radiusBuffer = [device newBufferWithBytes:radiusData.data()
length:radiusData.size() * sizeof(float)
cpBuffer = [mtl_device newBufferWithBytes:cpData.data()
length:cpData.size() * sizeof(float3)
options:storage_mode];
radiusBuffer = [mtl_device newBufferWithBytes:radiusData.data()
length:radiusData.size() * sizeof(float)
options:storage_mode];
std::vector<MTLMotionKeyframeData *> cp_ptrs;
std::vector<MTLMotionKeyframeData *> radius_ptrs;
cp_ptrs.reserve(num_motion_steps);
@ -541,18 +546,18 @@ bool BVHMetal::build_BLAS_hair(Progress &progress,
}
/* Allocate and populate MTLBuffers for geometry. */
idxBuffer = [device newBufferWithBytes:idxData.data()
length:idxData.size() * sizeof(int)
options:storage_mode];
idxBuffer = [mtl_device newBufferWithBytes:idxData.data()
length:idxData.size() * sizeof(int)
options:storage_mode];
cpBuffer = [device newBufferWithBytes:cpData.data()
length:cpData.size() * sizeof(float3)
options:storage_mode];
radiusBuffer = [device newBufferWithBytes:radiusData.data()
length:radiusData.size() * sizeof(float)
cpBuffer = [mtl_device newBufferWithBytes:cpData.data()
length:cpData.size() * sizeof(float3)
options:storage_mode];
radiusBuffer = [mtl_device newBufferWithBytes:radiusData.data()
length:radiusData.size() * sizeof(float)
options:storage_mode];
if (storage_mode == MTLResourceStorageModeManaged) {
[cpBuffer didModifyRange:NSMakeRange(0, cpBuffer.length)];
[idxBuffer didModifyRange:NSMakeRange(0, idxBuffer.length)];
@ -600,13 +605,14 @@ bool BVHMetal::build_BLAS_hair(Progress &progress,
}
accelDesc.usage |= MTLAccelerationStructureUsageExtendedLimits;
MTLAccelerationStructureSizes accelSizes = [device
MTLAccelerationStructureSizes accelSizes = [mtl_device
accelerationStructureSizesWithDescriptor:accelDesc];
id<MTLAccelerationStructure> accel_uncompressed = [device
id<MTLAccelerationStructure> accel_uncompressed = [mtl_device
newAccelerationStructureWithSize:accelSizes.accelerationStructureSize];
id<MTLBuffer> scratchBuf = [device newBufferWithLength:accelSizes.buildScratchBufferSize
options:MTLResourceStorageModePrivate];
id<MTLBuffer> sizeBuf = [device newBufferWithLength:8 options:MTLResourceStorageModeShared];
id<MTLBuffer> scratchBuf = [mtl_device newBufferWithLength:accelSizes.buildScratchBufferSize
options:MTLResourceStorageModePrivate];
id<MTLBuffer> sizeBuf = [mtl_device newBufferWithLength:8
options:MTLResourceStorageModeShared];
id<MTLCommandBuffer> accelCommands = [queue commandBuffer];
id<MTLAccelerationStructureCommandEncoder> accelEnc =
[accelCommands accelerationStructureCommandEncoder];
@ -651,14 +657,14 @@ bool BVHMetal::build_BLAS_hair(Progress &progress,
id<MTLCommandBuffer> accelCommands = [queue commandBuffer];
id<MTLAccelerationStructureCommandEncoder> accelEnc =
[accelCommands accelerationStructureCommandEncoder];
id<MTLAccelerationStructure> accel = [device
id<MTLAccelerationStructure> accel = [mtl_device
newAccelerationStructureWithSize:compressed_size];
[accelEnc copyAndCompactAccelerationStructure:accel_uncompressed
toAccelerationStructure:accel];
[accelEnc endEncoding];
[accelCommands addCompletedHandler:^(id<MTLCommandBuffer> /*command_buffer*/) {
uint64_t allocated_size = [accel allocatedSize];
stats.mem_alloc(allocated_size);
device->stats.mem_alloc(allocated_size);
accel_struct = accel;
[accel_uncompressed release];
@ -673,7 +679,7 @@ bool BVHMetal::build_BLAS_hair(Progress &progress,
accel_struct = accel_uncompressed;
uint64_t allocated_size = [accel_struct allocatedSize];
stats.mem_alloc(allocated_size);
device->stats.mem_alloc(allocated_size);
/* Signal that we've finished doing GPU acceleration struct build. */
g_bvh_build_throttler.release(wired_size);
@ -690,7 +696,7 @@ bool BVHMetal::build_BLAS_hair(Progress &progress,
}
# else /* MAC_OS_VERSION_14_0 */
(void)progress;
(void)device;
(void)mtl_device;
(void)queue;
(void)geom;
(void)(refit);
@ -699,7 +705,7 @@ bool BVHMetal::build_BLAS_hair(Progress &progress,
}
bool BVHMetal::build_BLAS_pointcloud(Progress &progress,
id<MTLDevice> device,
id<MTLDevice> mtl_device,
id<MTLCommandQueue> queue,
Geometry *const geom,
bool refit)
@ -732,7 +738,7 @@ bool BVHMetal::build_BLAS_pointcloud(Progress &progress,
const size_t num_aabbs = num_motion_steps * num_points;
MTLResourceOptions storage_mode;
if (device.hasUnifiedMemory) {
if (mtl_device.hasUnifiedMemory) {
storage_mode = MTLResourceStorageModeShared;
}
else {
@ -740,7 +746,7 @@ bool BVHMetal::build_BLAS_pointcloud(Progress &progress,
}
/* Allocate a GPU buffer for the AABB data and populate it */
id<MTLBuffer> aabbBuf = [device
id<MTLBuffer> aabbBuf = [mtl_device
newBufferWithLength:num_aabbs * sizeof(MTLAxisAlignedBoundingBox)
options:storage_mode];
MTLAxisAlignedBoundingBox *aabb_data = (MTLAxisAlignedBoundingBox *)[aabbBuf contents];
@ -848,13 +854,14 @@ bool BVHMetal::build_BLAS_pointcloud(Progress &progress,
MTLAccelerationStructureUsagePreferFastBuild);
}
MTLAccelerationStructureSizes accelSizes = [device
MTLAccelerationStructureSizes accelSizes = [mtl_device
accelerationStructureSizesWithDescriptor:accelDesc];
id<MTLAccelerationStructure> accel_uncompressed = [device
id<MTLAccelerationStructure> accel_uncompressed = [mtl_device
newAccelerationStructureWithSize:accelSizes.accelerationStructureSize];
id<MTLBuffer> scratchBuf = [device newBufferWithLength:accelSizes.buildScratchBufferSize
options:MTLResourceStorageModePrivate];
id<MTLBuffer> sizeBuf = [device newBufferWithLength:8 options:MTLResourceStorageModeShared];
id<MTLBuffer> scratchBuf = [mtl_device newBufferWithLength:accelSizes.buildScratchBufferSize
options:MTLResourceStorageModePrivate];
id<MTLBuffer> sizeBuf = [mtl_device newBufferWithLength:8
options:MTLResourceStorageModeShared];
id<MTLCommandBuffer> accelCommands = [queue commandBuffer];
id<MTLAccelerationStructureCommandEncoder> accelEnc =
[accelCommands accelerationStructureCommandEncoder];
@ -897,14 +904,14 @@ bool BVHMetal::build_BLAS_pointcloud(Progress &progress,
id<MTLCommandBuffer> accelCommands = [queue commandBuffer];
id<MTLAccelerationStructureCommandEncoder> accelEnc =
[accelCommands accelerationStructureCommandEncoder];
id<MTLAccelerationStructure> accel = [device
id<MTLAccelerationStructure> accel = [mtl_device
newAccelerationStructureWithSize:compressed_size];
[accelEnc copyAndCompactAccelerationStructure:accel_uncompressed
toAccelerationStructure:accel];
[accelEnc endEncoding];
[accelCommands addCompletedHandler:^(id<MTLCommandBuffer> /*command_buffer*/) {
uint64_t allocated_size = [accel allocatedSize];
stats.mem_alloc(allocated_size);
device->stats.mem_alloc(allocated_size);
accel_struct = accel;
[accel_uncompressed release];
@ -919,7 +926,7 @@ bool BVHMetal::build_BLAS_pointcloud(Progress &progress,
accel_struct = accel_uncompressed;
uint64_t allocated_size = [accel_struct allocatedSize];
stats.mem_alloc(allocated_size);
device->stats.mem_alloc(allocated_size);
/* Signal that we've finished doing GPU acceleration struct build. */
g_bvh_build_throttler.release(wired_size);
@ -937,7 +944,7 @@ bool BVHMetal::build_BLAS_pointcloud(Progress &progress,
}
bool BVHMetal::build_BLAS(Progress &progress,
id<MTLDevice> device,
id<MTLDevice> mtl_device,
id<MTLCommandQueue> queue,
bool refit)
{
@ -948,11 +955,11 @@ bool BVHMetal::build_BLAS(Progress &progress,
switch (geom->geometry_type) {
case Geometry::VOLUME:
case Geometry::MESH:
return build_BLAS_mesh(progress, device, queue, geom, refit);
return build_BLAS_mesh(progress, mtl_device, queue, geom, refit);
case Geometry::HAIR:
return build_BLAS_hair(progress, device, queue, geom, refit);
return build_BLAS_hair(progress, mtl_device, queue, geom, refit);
case Geometry::POINTCLOUD:
return build_BLAS_pointcloud(progress, device, queue, geom, refit);
return build_BLAS_pointcloud(progress, mtl_device, queue, geom, refit);
default:
return false;
}
@ -960,7 +967,7 @@ bool BVHMetal::build_BLAS(Progress &progress,
}
bool BVHMetal::build_TLAS(Progress &progress,
id<MTLDevice> device,
id<MTLDevice> mtl_device,
id<MTLCommandQueue> queue,
bool refit)
{
@ -969,14 +976,14 @@ bool BVHMetal::build_TLAS(Progress &progress,
if (@available(macos 12.0, *)) {
/* Defined inside available check, for return type to be available. */
auto make_null_BLAS = [](id<MTLDevice> device,
auto make_null_BLAS = [](id<MTLDevice> mtl_device,
id<MTLCommandQueue> queue) -> id<MTLAccelerationStructure> {
MTLResourceOptions storage_mode = MTLResourceStorageModeManaged;
if (device.hasUnifiedMemory) {
if (mtl_device.hasUnifiedMemory) {
storage_mode = MTLResourceStorageModeShared;
}
id<MTLBuffer> nullBuf = [device newBufferWithLength:sizeof(float3) options:storage_mode];
id<MTLBuffer> nullBuf = [mtl_device newBufferWithLength:sizeof(float3) options:storage_mode];
/* Create an acceleration structure. */
MTLAccelerationStructureTriangleGeometryDescriptor *geomDesc =
@ -997,13 +1004,14 @@ bool BVHMetal::build_TLAS(Progress &progress,
accelDesc.geometryDescriptors = @[ geomDesc ];
accelDesc.usage |= MTLAccelerationStructureUsageExtendedLimits;
MTLAccelerationStructureSizes accelSizes = [device
MTLAccelerationStructureSizes accelSizes = [mtl_device
accelerationStructureSizesWithDescriptor:accelDesc];
id<MTLAccelerationStructure> accel_struct = [device
id<MTLAccelerationStructure> accel_struct = [mtl_device
newAccelerationStructureWithSize:accelSizes.accelerationStructureSize];
id<MTLBuffer> scratchBuf = [device newBufferWithLength:accelSizes.buildScratchBufferSize
options:MTLResourceStorageModePrivate];
id<MTLBuffer> sizeBuf = [device newBufferWithLength:8 options:MTLResourceStorageModeShared];
id<MTLBuffer> scratchBuf = [mtl_device newBufferWithLength:accelSizes.buildScratchBufferSize
options:MTLResourceStorageModePrivate];
id<MTLBuffer> sizeBuf = [mtl_device newBufferWithLength:8
options:MTLResourceStorageModeShared];
id<MTLCommandBuffer> accelCommands = [queue commandBuffer];
id<MTLAccelerationStructureCommandEncoder> accelEnc =
[accelCommands accelerationStructureCommandEncoder];
@ -1070,7 +1078,7 @@ bool BVHMetal::build_TLAS(Progress &progress,
};
MTLResourceOptions storage_mode;
if (device.hasUnifiedMemory) {
if (mtl_device.hasUnifiedMemory) {
storage_mode = MTLResourceStorageModeShared;
}
else {
@ -1086,12 +1094,12 @@ bool BVHMetal::build_TLAS(Progress &progress,
}
/* Allocate a GPU buffer for the instance data and populate it */
id<MTLBuffer> instanceBuf = [device newBufferWithLength:num_instances * instance_size
options:storage_mode];
id<MTLBuffer> instanceBuf = [mtl_device newBufferWithLength:num_instances * instance_size
options:storage_mode];
id<MTLBuffer> motion_transforms_buf = nil;
MTLPackedFloat4x3 *motion_transforms = nullptr;
if (motion_blur && num_motion_transforms) {
motion_transforms_buf = [device
motion_transforms_buf = [mtl_device
newBufferWithLength:num_motion_transforms * sizeof(MTLPackedFloat4x3)
options:storage_mode];
motion_transforms = (MTLPackedFloat4x3 *)motion_transforms_buf.contents;
@ -1108,14 +1116,14 @@ bool BVHMetal::build_TLAS(Progress &progress,
Geometry const *geom = ob->get_geometry();
BVHMetal const *blas = static_cast<BVHMetal const *>(geom->bvh);
if (!blas || !blas->accel_struct) {
/* Place a degenerate instance, to ensure [[instance_id]] equals ob->get_device_index()
/* Place a degenerate instance, to ensure [[instance_id]] equals ob->get_mtl_device_index()
* in our intersection functions */
blas = nullptr;
/* Workaround for issue in macOS <= 14.1: Insert degenerate BLAS instead of zero-filling
* the descriptor. */
if (!null_BLAS) {
null_BLAS = make_null_BLAS(device, queue);
null_BLAS = make_null_BLAS(mtl_device, queue);
}
blas_array.push_back(null_BLAS);
}
@ -1259,12 +1267,12 @@ bool BVHMetal::build_TLAS(Progress &progress,
MTLAccelerationStructureUsagePreferFastBuild);
}
MTLAccelerationStructureSizes accelSizes = [device
MTLAccelerationStructureSizes accelSizes = [mtl_device
accelerationStructureSizesWithDescriptor:accelDesc];
id<MTLAccelerationStructure> accel = [device
id<MTLAccelerationStructure> accel = [mtl_device
newAccelerationStructureWithSize:accelSizes.accelerationStructureSize];
id<MTLBuffer> scratchBuf = [device newBufferWithLength:accelSizes.buildScratchBufferSize
options:MTLResourceStorageModePrivate];
id<MTLBuffer> scratchBuf = [mtl_device newBufferWithLength:accelSizes.buildScratchBufferSize
options:MTLResourceStorageModePrivate];
id<MTLCommandBuffer> accelCommands = [queue commandBuffer];
id<MTLAccelerationStructureCommandEncoder> accelEnc =
[accelCommands accelerationStructureCommandEncoder];
@ -1292,7 +1300,7 @@ bool BVHMetal::build_TLAS(Progress &progress,
[scratchBuf release];
uint64_t allocated_size = [accel allocatedSize];
stats.mem_alloc(allocated_size);
device->stats.mem_alloc(allocated_size);
/* Cache top and bottom-level acceleration structs */
accel_struct = accel;
@ -1309,7 +1317,7 @@ bool BVHMetal::build_TLAS(Progress &progress,
}
bool BVHMetal::build(Progress &progress,
id<MTLDevice> device,
id<MTLDevice> mtl_device,
id<MTLCommandQueue> queue,
bool refit)
{
@ -1319,7 +1327,7 @@ bool BVHMetal::build(Progress &progress,
}
else {
if (accel_struct) {
stats.mem_free(accel_struct.allocatedSize);
device->stats.mem_free(accel_struct.allocatedSize);
[accel_struct release];
accel_struct = nil;
}
@ -1328,10 +1336,10 @@ bool BVHMetal::build(Progress &progress,
@autoreleasepool {
if (!params.top_level) {
return build_BLAS(progress, device, queue, refit);
return build_BLAS(progress, mtl_device, queue, refit);
}
else {
return build_TLAS(progress, device, queue, refit);
return build_TLAS(progress, mtl_device, queue, refit);
}
}
}

View File

@ -89,7 +89,7 @@ void device_metal_info(vector<DeviceInfo> &devices)
VLOG_INFO << "Added device \"" << info.description << "\" with id \"" << info.id << "\".";
if (info.denoisers & DENOISER_OPENIMAGEDENOISE)
VLOG_INFO << "Device with id \"" << info.id << "\" is supporting "
VLOG_INFO << "Device with id \"" << info.id << "\" supports "
<< denoiserTypeToHumanReadable(DENOISER_OPENIMAGEDENOISE) << ".";
}
}

View File

@ -140,6 +140,8 @@ class MetalDevice : public Device {
virtual void build_bvh(BVH *bvh, Progress &progress, bool refit) override;
virtual void release_bvh(BVH *bvh) override;
virtual void optimize_for_scene(Scene *scene) override;
static void compile_and_load(int device_id, MetalPipelineType pso_type);

View File

@ -341,7 +341,7 @@ string MetalDevice::preprocess_source(MetalPipelineType pso_type,
}
# ifdef WITH_CYCLES_DEBUG
global_defines += "#define __KERNEL_DEBUG__\n";
global_defines += "#define WITH_CYCLES_DEBUG\n";
# endif
switch (device_vendor) {
@ -1443,6 +1443,13 @@ void MetalDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
}
}
void MetalDevice::release_bvh(BVH *bvh)
{
if (bvhMetalRT == bvh) {
bvhMetalRT = nullptr;
}
}
CCL_NAMESPACE_END
#endif

View File

@ -134,7 +134,7 @@ static void device_iterator_cb(
VLOG_INFO << "Added device \"" << info.description << "\" with id \"" << info.id << "\".";
if (info.denoisers & DENOISER_OPENIMAGEDENOISE)
VLOG_INFO << "Device with id \"" << info.id << "\" is supporting "
VLOG_INFO << "Device with id \"" << info.id << "\" supports "
<< denoiserTypeToHumanReadable(DENOISER_OPENIMAGEDENOISE) << ".";
}
#endif

View File

@ -1680,7 +1680,7 @@ void OptiXDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
}
}
void OptiXDevice::release_optix_bvh(BVH *bvh)
void OptiXDevice::release_bvh(BVH *bvh)
{
thread_scoped_lock lock(delayed_free_bvh_mutex);
/* Do delayed free of BVH memory, since geometry holding BVH might be deleted

View File

@ -106,7 +106,7 @@ class OptiXDevice : public CUDADevice {
void build_bvh(BVH *bvh, Progress &progress, bool refit) override;
void release_optix_bvh(BVH *bvh) override;
void release_bvh(BVH *bvh) override;
void free_bvh_memory_delayed();
void const_copy_to(const char *name, void *host, size_t size) override;

View File

@ -144,7 +144,7 @@ ccl_device_intersect bool scene_intersect(KernelGlobals kg,
return false;
}
#if defined(__KERNEL_DEBUG__)
#if defined(WITH_CYCLES_DEBUG)
if (is_null_instance_acceleration_structure(metal_ancillaries->accel_struct)) {
isect->t = ray->tmax;
isect->type = PRIMITIVE_NONE;
@ -281,7 +281,7 @@ ccl_device_intersect bool scene_intersect_local(KernelGlobals kg,
return false;
}
# if defined(__KERNEL_DEBUG__)
# if defined(WITH_CYCLES_DEBUG)
if (is_null_instance_acceleration_structure(metal_ancillaries->accel_struct)) {
if (local_isect) {
local_isect->num_hits = 0;
@ -383,7 +383,7 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals kg,
return false;
}
# if defined(__KERNEL_DEBUG__)
# if defined(WITH_CYCLES_DEBUG)
if (is_null_instance_acceleration_structure(metal_ancillaries->accel_struct)) {
kernel_assert(!"Invalid metal_ancillaries->accel_struct pointer");
return false;
@ -446,7 +446,7 @@ ccl_device_intersect bool scene_intersect_volume(KernelGlobals kg,
return false;
}
# if defined(__KERNEL_DEBUG__)
# if defined(WITH_CYCLES_DEBUG)
if (is_null_instance_acceleration_structure(metal_ancillaries->accel_struct)) {
kernel_assert(!"Invalid metal_ancillaries->accel_struct pointer");
return false;

View File

@ -280,6 +280,16 @@ ccl_device
kernel_assert(ls.pdf != 0.0f);
const bool is_transmission = dot(ls.D, sd->N) < 0.0f;
if (ls.prim != PRIM_NONE && ls.prim == sd->prim && ls.object == sd->object) {
/* Skip self intersection if light direction lies in the same hemisphere as the geometric
* normal. */
if (dot(ls.D, is_transmission ? -sd->Ng : sd->Ng) > 0.0f) {
return;
}
}
/* Evaluate light shader.
*
* TODO: can we reuse sd memory? In theory we can move this after
@ -292,8 +302,6 @@ ccl_device
Ray ray ccl_optional_struct_init;
BsdfEval bsdf_eval ccl_optional_struct_init;
const bool is_transmission = dot(ls.D, sd->N) < 0.0f;
int mnee_vertex_count = 0;
#ifdef __MNEE__
IF_KERNEL_FEATURE(MNEE)

View File

@ -313,32 +313,6 @@ ccl_device float volume_equiangular_pdf(ccl_private const Ray *ccl_restrict ray,
return pdf;
}
ccl_device float volume_equiangular_cdf(ccl_private const Ray *ccl_restrict ray,
const float3 light_P,
const float sample_t)
{
float delta = dot((light_P - ray->P), ray->D);
float D = safe_sqrtf(len_squared(light_P - ray->P) - delta * delta);
if (UNLIKELY(D == 0.0f)) {
return 0.0f;
}
const float tmin = ray->tmin;
const float tmax = ray->tmax;
const float t_ = sample_t - delta;
const float theta_a = atan2f(tmin - delta, D);
const float theta_b = atan2f(tmax - delta, D);
if (UNLIKELY(theta_b == theta_a)) {
return 0.0f;
}
const float theta_sample = atan2f(t_, D);
const float cdf = (theta_sample - theta_a) / (theta_b - theta_a);
return cdf;
}
/* Distance sampling */
ccl_device float volume_distance_sample(float max_t,

View File

@ -212,7 +212,7 @@ ccl_device_inline void surface_shader_prepare_closures(KernelGlobals kg,
/* BSDF */
#ifdef WITH_CYCLES_DEBUG
ccl_device_inline void surface_shader_validate_bsdf_sample(const KernelGlobals kg,
const ShaderClosure *sc,
ccl_private const ShaderClosure *sc,
const float3 wo,
const int org_label,
const float2 org_roughness,

View File

@ -311,7 +311,7 @@ ccl_device_inline bool area_light_eval(const ccl_global KernelLight *klight,
ls->pdf *= light_pdf_area_to_solid_angle(Ng, -ls->D, ls->t);
}
return ls->eval_fac > 0;
return in_volume_segment || ls->eval_fac > 0;
}
template<bool in_volume_segment>

View File

@ -9,11 +9,13 @@
CCL_NAMESPACE_BEGIN
/* Transform vector to spot light's local coordinate system. */
ccl_device float3 spot_light_to_local(const ccl_global KernelSpotLight *spot, const float3 ray)
ccl_device float3 spot_light_to_local(const ccl_global KernelLight *klight, const float3 ray)
{
return safe_normalize(make_float3(dot(ray, spot->scaled_axis_u),
dot(ray, spot->scaled_axis_v),
dot(ray, spot->dir * spot->inv_len_z)));
const Transform itfm = klight->itfm;
float3 transformed_ray = safe_normalize(transform_direction(&itfm, ray));
transformed_ray.z = -transformed_ray.z;
return transformed_ray;
}
/* Compute spot light attenuation of a ray given in local coordinate system. */
@ -58,7 +60,7 @@ ccl_device_inline bool spot_light_sample(const ccl_global KernelLight *klight,
ls->t = FLT_MAX;
if (d_sq > r_sq) {
/* Outside sphere. */
const float one_minus_cos_half_spot_spread = 1.0f - klight->spot.cos_half_spot_angle;
const float one_minus_cos_half_spot_spread = 1.0f - klight->spot.cos_half_larger_spread;
const float one_minus_cos_half_angle = sin_sqr_to_one_minus_cos(r_sq / d_sq);
if (in_volume_segment || one_minus_cos_half_angle < one_minus_cos_half_spot_spread) {
@ -92,7 +94,7 @@ ccl_device_inline bool spot_light_sample(const ccl_global KernelLight *klight,
}
/* Attenuation. */
const float3 local_ray = spot_light_to_local(&klight->spot, -ls->D);
const float3 local_ray = spot_light_to_local(klight, -ls->D);
if (d_sq > r_sq) {
ls->eval_fac *= spot_light_attenuation(&klight->spot, local_ray);
}
@ -128,7 +130,7 @@ ccl_device_inline bool spot_light_sample(const ccl_global KernelLight *klight,
ls->Ng = -ls->D;
/* Attenuation. */
const float3 local_ray = spot_light_to_local(&klight->spot, -ls->D);
const float3 local_ray = spot_light_to_local(klight, -ls->D);
ls->eval_fac *= spot_light_attenuation(&klight->spot, local_ray);
if (!in_volume_segment && ls->eval_fac == 0.0f) {
return false;
@ -145,7 +147,7 @@ ccl_device_inline bool spot_light_sample(const ccl_global KernelLight *klight,
return true;
}
ccl_device_forceinline float spot_light_pdf(const float cos_half_spread,
ccl_device_forceinline float spot_light_pdf(const ccl_global KernelSpotLight *spot,
const float d_sq,
const float r_sq,
const float3 N,
@ -153,7 +155,8 @@ ccl_device_forceinline float spot_light_pdf(const float cos_half_spread,
const uint32_t path_flag)
{
if (d_sq > r_sq) {
return M_1_2PI_F / min(sin_sqr_to_one_minus_cos(r_sq / d_sq), 1.0f - cos_half_spread);
return M_1_2PI_F /
min(sin_sqr_to_one_minus_cos(r_sq / d_sq), 1.0f - spot->cos_half_larger_spread);
}
const bool has_transmission = (path_flag & PATH_RAY_MIS_HAD_TRANSMISSION);
@ -181,7 +184,7 @@ ccl_device_forceinline void spot_light_mnee_sample_update(const ccl_global Kerne
/* NOTE : preserve pdf in area measure. */
const float jacobian_solid_angle_to_area = 0.5f * fabsf(d_sq - r_sq - t_sq) /
(radius * ls->t * t_sq);
ls->pdf = spot_light_pdf(klight->spot.cos_half_spot_angle, d_sq, r_sq, N, ls->D, path_flag) *
ls->pdf = spot_light_pdf(&klight->spot, d_sq, r_sq, N, ls->D, path_flag) *
jacobian_solid_angle_to_area;
ls->Ng = normalize(ls->P - klight->co);
@ -196,7 +199,7 @@ ccl_device_forceinline void spot_light_mnee_sample_update(const ccl_global Kerne
}
/* Attenuation. */
const float3 local_ray = spot_light_to_local(&klight->spot, -ls->D);
const float3 local_ray = spot_light_to_local(klight, -ls->D);
if (use_attenuation) {
ls->eval_fac *= spot_light_attenuation(&klight->spot, local_ray);
}
@ -232,7 +235,7 @@ ccl_device_inline bool spot_light_sample_from_intersection(
ls->eval_fac = klight->spot.eval_fac;
if (klight->spot.is_sphere) {
ls->pdf = spot_light_pdf(klight->spot.cos_half_spot_angle, d_sq, r_sq, N, ray_D, path_flag);
ls->pdf = spot_light_pdf(&klight->spot, d_sq, r_sq, N, ray_D, path_flag);
ls->Ng = normalize(ls->P - klight->co);
}
else {
@ -248,7 +251,7 @@ ccl_device_inline bool spot_light_sample_from_intersection(
}
/* Attenuation. */
const float3 local_ray = spot_light_to_local(&klight->spot, -ray_D);
const float3 local_ray = spot_light_to_local(klight, -ray_D);
if (!klight->spot.is_sphere || d_sq > r_sq) {
ls->eval_fac *= spot_light_attenuation(&klight->spot, local_ray);
}

View File

@ -146,7 +146,9 @@ ccl_device_forceinline bool triangle_light_sample(KernelGlobals kg,
ls->shader = kernel_data_fetch(tri_shader, prim);
const float distance_to_plane = dot(N0, V[0] - P) / dot(N0, N0);
const int ls_shader_flag = kernel_data_fetch(shaders, ls->shader & SHADER_MASK).flags;
if (!(ls_shader_flag & (distance_to_plane > 0 ? SD_MIS_BACK : SD_MIS_FRONT))) {
if (!in_volume_segment &&
!(ls_shader_flag & (distance_to_plane > 0 ? SD_MIS_BACK : SD_MIS_FRONT)))
{
return false;
}

View File

@ -1367,16 +1367,15 @@ typedef struct KernelCurveSegment {
static_assert_align(KernelCurveSegment, 8);
typedef struct KernelSpotLight {
packed_float3 scaled_axis_u;
float radius;
packed_float3 scaled_axis_v;
float eval_fac;
packed_float3 dir;
float radius;
float eval_fac;
float cos_half_spot_angle;
float half_cot_half_spot_angle;
float inv_len_z;
float spot_smooth;
int is_sphere;
/* For non-uniform object scaling, the actual spread might be different. */
float cos_half_larger_spread;
} KernelSpotLight;
/* PointLight is SpotLight with only radius and invarea being used. */

View File

@ -1346,23 +1346,22 @@ void LightManager::device_update_lights(Device *device, DeviceScene *dscene, Sce
klights[light_index].area.normalize_spread = normalize_spread;
}
if (light->light_type == LIGHT_SPOT) {
/* Scale axes to accommodate non-uniform scaling. */
float3 scaled_axis_u = light->get_axisu() / len_squared(light->get_axisu());
float3 scaled_axis_v = light->get_axisv() / len_squared(light->get_axisv());
float len_z;
/* Keep direction normalized. */
float3 dir = safe_normalize_len(light->get_dir(), &len_z);
const float cos_half_spot_angle = cosf(light->spot_angle * 0.5f);
const float spot_smooth = 1.0f / ((1.0f - cos_half_spot_angle) * light->spot_smooth);
const float tan_half_spot_angle = tanf(light->spot_angle * 0.5f);
float cos_half_spot_angle = cosf(light->spot_angle * 0.5f);
float spot_smooth = 1.0f / ((1.0f - cos_half_spot_angle) * light->spot_smooth);
const float len_w_sq = len_squared(light->get_dir());
const float len_u_sq = len_squared(light->get_axisu());
const float len_v_sq = len_squared(light->get_axisv());
const float tan_sq = sqr(tan_half_spot_angle);
klights[light_index].spot.scaled_axis_u = scaled_axis_u;
klights[light_index].spot.scaled_axis_v = scaled_axis_v;
klights[light_index].spot.dir = dir;
klights[light_index].spot.dir = safe_normalize(light->get_dir());
klights[light_index].spot.cos_half_spot_angle = cos_half_spot_angle;
klights[light_index].spot.half_cot_half_spot_angle = 0.5f / tanf(light->spot_angle * 0.5f);
klights[light_index].spot.inv_len_z = 1.0f / len_z;
klights[light_index].spot.half_cot_half_spot_angle = 0.5f / tan_half_spot_angle;
klights[light_index].spot.spot_smooth = spot_smooth;
/* Choose the angle which spans a larger cone. */
klights[light_index].spot.cos_half_larger_spread = inversesqrtf(
1.0f + tan_sq * fmaxf(len_u_sq, len_v_sq) / len_w_sq);
}
klights[light_index].shader_id = shader_id;

@ -1 +1 @@
Subproject commit d7827c77fe050a0e179fa0872c59dcbe71dc8595
Subproject commit d983ed32a1e760130ba31ad8a98a94ea943267a2

@ -1 +1 @@
Subproject commit 3d3ec946fc8808113204f6e8486c31ecee7dc804
Subproject commit f1caad00e45d3741f84e5e68197a420f0819bded

@ -1 +1 @@
Subproject commit b90554a2f217fff7204867f201a336b7bc52f6dc
Subproject commit c0ef4a3e1bcac58868b9b8d0d0b65236f65d6219

1
lib/windows_arm64 Submodule

@ -0,0 +1 @@
Subproject commit dc33a8704935c49dd7a8cf49197fdf42ff52622d

@ -1 +1 @@
Subproject commit c8dba5b39bfd6c25c789660b022034ff69062e7c
Subproject commit a5521c85e03bfd1556ff1e63bf7163235c401497

View File

@ -57,6 +57,7 @@ roles:
displays:
sRGB:
- !<View> {name: Standard, colorspace: sRGB}
- !<View> {name: Khronos PBR Neutral, colorspace: Khronos PBR Neutral sRGB}
- !<View> {name: AgX, colorspace: AgX Base sRGB}
- !<View> {name: Filmic, colorspace: Filmic sRGB}
- !<View> {name: Filmic Log, colorspace: Filmic Log}
@ -78,7 +79,7 @@ displays:
- !<View> {name: False Color, colorspace: AgX False Color Rec.2020}
- !<View> {name: Raw, colorspace: Non-Color}
active_displays: [sRGB, Display P3, Rec.1886, Rec.2020]
active_views: [Standard, AgX, Filmic, Filmic Log, False Color, Raw]
active_views: [Standard, Khronos PBR Neutral, AgX, Filmic, Filmic Log, False Color, Raw]
inactive_colorspaces: [Luminance Compensation Rec.2020, Luminance Compensation sRGB, Luminance Compensation P3, AgX False Color Rec.709, AgX False Color P3, AgX False Color Rec.1886, AgX False Color Rec.2020]
colorspaces:
@ -485,6 +486,21 @@ colorspaces:
- !<ColorSpaceTransform> {src: Linear CIE-XYZ E, dst: AgX False Color Rec.709}
- !<ColorSpaceTransform> {src: Rec.1886, dst: Rec.2020}
- !<ColorSpace>
name: Khronos PBR Neutral sRGB
family: Khronos PBR Neutral
equalitygroup:
bitdepth: 32f
description: |
Khronos PBR Neutral Image Encoding for sRGB Display
isdata: false
from_scene_reference: !<GroupTransform>
children:
- !<ColorSpaceTransform> {src: Linear CIE-XYZ E, dst: Linear Rec.709}
- !<AllocationTransform> {allocation: lg2, vars: [-9, 10]}
- !<FileTransform> {src: pbrNeutral.cube, interpolation: tetrahedral}
- !<ColorSpaceTransform> {src: Linear Rec.709, dst: sRGB}
looks:
- !<Look>
name: Very High Contrast
@ -744,4 +760,4 @@ looks:
style: log
contrast: {rgb: [0.7, 0.7, 0.7], master: 1}
saturation: 1.15
pivot: {contrast: -0.2}
pivot: {contrast: -0.2}

File diff suppressed because it is too large Load Diff

View File

@ -153,7 +153,7 @@ const UserDef U_default = {
.pressure_softness = 0.0,
.ndof_sensitivity = 4.0,
.ndof_orbit_sensitivity = 4.0,
.ndof_deadzone = 0.1,
.ndof_deadzone = 0.0,
.ndof_flag = (NDOF_MODE_ORBIT | NDOF_LOCK_HORIZON | NDOF_SHOULD_PAN | NDOF_SHOULD_ZOOM |
NDOF_SHOULD_ROTATE |
/* Software from the driver authors follows this convention

View File

@ -19,22 +19,24 @@ PERFORMANCE OF THIS SOFTWARE.
------
** Audaspace; version 1.4+ (ae29ce2) -- https://audaspace.github.io/
** Audaspace; version 0d18fe7 -- https://audaspace.github.io/
** Cuda Wrangler; version cbf465b -- https://github.com/CudaWrangler/cuew
** Draco; version 1.3.6 -- https://google.github.io/draco/
** Embree; version 4.1.0 -- https://github.com/embree/embree
** Intel(R) oneAPI DPC++ compiler; version 2022-12 --
https://github.com/intel/llvm#oneapi-dpc-compiler
** Intel® Open Path Guiding Library; version 0.6.0 -- http://www.openpgl.org/
** Intel® Open Path Guiding Library; version 0.5.0 -- http://www.openpgl.org/
** Mantaflow; version 0.13 -- http://mantaflow.com/
** materialX; version 1.38.6 --
** materialX; version 1.38.8 --
https://github.com/AcademySoftwareFoundation/MaterialX
** meson; version 0.63 -- https://github.com/mesonbuild/meson
** oneAPI Threading Building Block; version 2020_U3 --
https://software.intel.com/en-us/oneapi/onetbb
** OpenImageDenoise; version 1.4.3 -- https://www.openimagedenoise.org/
** OpenImageIO; version 2.4.15.0 -- http://www.openimageio.org
** OpenSSL; version 3.1.2 -- https://www.openssl.org/
** OpenCL Wrangler; version 27a6867 -- https://github.com/OpenCLWrangler/clew
** OpenImageDenoise; version 2.2.2 -- https://www.openimagedenoise.org/
** OpenImageIO; version 2.5.6.0 --
https://github.com/AcademySoftwareFoundation/OpenImageIO
** OpenSSL; version 3.1.5 -- 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 --
@ -42,7 +44,9 @@ https://github.com/SDLWrangler/sdlew
** ShaderC; version 2022.3 -- https://github.com/google/shaderc
** SYCL Unified Runtime ; version fd711c920acc4434cb52ff18b078c082d9d7f44d --
https://github.com/oneapi-src/unified-runtime
** Vulkan Loader; version 1.2.198 --
** Vulkan Headers; version 1.3.270 --
https://github.com/KhronosGroup/Vulkan-Headers
** Vulkan Loader; version 1.3.270 --
https://github.com/KhronosGroup/Vulkan-Loader
Apache License
@ -244,7 +248,7 @@ See the License for the specific language governing permissions and
limitations under the License.
* For Audaspace see also this required NOTICE:
Copyright © 2009-2023 Jörg Müller. All rights reserved.
Copyright © 2009-2020 Jörg Müller. All rights reserved.
* For Cuda Wrangler see also this required NOTICE:
Copyright 2011-2014 Blender Foundation
* For Draco see also this required NOTICE:
@ -290,6 +294,8 @@ limitations under the License.
Copyright 2015 The Shaderc Authors. All rights reserved.
* For SYCL Unified Runtime see also this required NOTICE:
Copyright (C) 2022-2023 Intel Corporation
* For Vulkan Headers see also this required NOTICE:
Copyright 2015-2023 The Khronos Group Inc.
* For Vulkan Loader see also this required NOTICE:
Copyright (c) 2019 The Khronos Group Inc.
Copyright (c) 2019 Valve Corporation
@ -391,22 +397,21 @@ Copyright (c) 2006, Google Inc.
All rights reserved.
** Imath; version 3.1.7 -- https://github.com/AcademySoftwareFoundation/Imath
Copyright Contributors to the OpenEXR Project. All rights reserved.
** ISPC; version 1.17.0 -- https://github.com/ispc/ispc
** ISPC; version 1.21.1 -- https://github.com/ispc/ispc
Copyright Intel Corporation
All rights reserved.
** NumPy; version 1.23.5 -- https://numpy.org/
** NumPy; version 1.24.3 -- https://numpy.org/
Copyright (c) 2005-2022, NumPy Developers.
All rights reserved.
** Ogg; version 1.3.5 -- https://www.xiph.org/ogg/
COPYRIGHT (C) 1994-2019 by the Xiph.Org Foundation https://www.xiph.org/
** Open Shading Language; version
1.13-dev-1a7670600c8b08c2443a78d03c8c27e9a1149140 --
https://github.com/imageworks/OpenShadingLanguage
** Open Shading Language; version 1.13.7.0 --
https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/
Copyright Contributors to the Open Shading Language project.
** OpenColorIO; version 2.2.0 --
** OpenColorIO; version 2.3.2 --
https://github.com/AcademySoftwareFoundation/OpenColorIO
Copyright Contributors to the OpenColorIO Project.
** OpenEXR; version 3.1.7 --
** OpenEXR; version 3.2.1 --
https://github.com/AcademySoftwareFoundation/openexr
Copyright Contributors to the OpenEXR Project. All rights reserved.
** Pystring; version 1.1.3 -- https://github.com/imageworks/pystring
@ -414,7 +419,7 @@ Copyright (c) 2008-2010, Sony Pictures Imageworks Inc
All rights reserved.
** Vorbis; version 1.3.7 -- https://xiph.org/vorbis/
Copyright (c) 2002-2020 Xiph.org Foundation
** VPX; version 1.11.0 -- https://github.com/webmproject/libvpx
** VPX; version 1.14.0 -- https://github.com/webmproject/libvpx
Copyright (c) 2010, The WebM Project authors. All rights reserved.
** WebP; version 1.3.2 -- https://github.com/webmproject/libwebp
Copyright (c) 2010, Google Inc. All rights reserved.
@ -913,7 +918,7 @@ Copyright (c) 2003, 2007-14 Matteo Frigo
Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
** GMP; version 6.2.1 -- https://gmplib.org/
Copyright 1996-2020 Free Software Foundation, Inc.
** OpenAL; version 1.21.1 -- http://openal-soft.org
** OpenAL; version 1.23.1 -- http://openal-soft.org
Copyright (c) 2015, Archontis Politis
Copyright (c) 2019, Christopher Robinson
@ -2804,7 +2809,7 @@ That's all there is to it!
------
** FFmpeg; version 6.0 -- http://ffmpeg.org/
** FFmpeg; version 6.1.1 -- http://ffmpeg.org/
Copyright: The FFmpeg contributors
https://github.com/FFmpeg/FFmpeg/blob/master/CREDITS
** Libsndfile; version 1.2.2 -- http://libsndfile.github.io/libsndfile/
@ -3433,6 +3438,33 @@ December 9, 2010
------
** libdeflate; version 1.18 -- https://github.com/ebiggers/libdeflate
Copyright 2016 Eric Biggers
Copyright 2016 Eric Biggers
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.
------
** vcintrinsics; version 782fbf7301dc73acaa049a4324c976ad94f587f7 --
https://github.com/intel/vc-intrinsics
Copyright (c) 2019 Intel Corporation
@ -3471,7 +3503,7 @@ Copyright © 2013 The Khronos Group Inc.
** Expat; version 2.5.0 -- https://github.com/libexpat/libexpat/
Copyright (c) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper
Copyright (c) 2001-2019 Expat maintainers
** Intel(R) Graphics Compute Runtime; version 22.38.24278 --
** Intel(R) Graphics Compute Runtime; version 23.43.27642.40 --
https://github.com/intel/compute-runtime
Copyright (C) 2021 Intel Corporation
** Intel(R) Graphics Memory Management Library; version 22.1.8 --
@ -3490,11 +3522,11 @@ Copyright (c) 2006, 2008 Junio C Hamano
Copyright © 2017-2018 Red Hat Inc.
Copyright © 2012 Collabora, Ltd.
Copyright © 2008 Kristian Høgsberg
** Libxml2; version 2.10.4 -- http://xmlsoft.org/
** Libxml2; version 2.12.3 -- http://xmlsoft.org/
Copyright (C) 1998-2012 Daniel Veillard. All Rights Reserved.
** Mesa 3D; version 21.1.5 -- https://www.mesa3d.org/
** Mesa 3D; version 23.3.0 -- https://www.mesa3d.org/
Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
** oneAPI Level Zero; version v1.8.8 --
** oneAPI Level Zero; version v1.15.8 --
https://github.com/oneapi-src/level-zero
Copyright (C) 2019-2021 Intel Corporation
** OPENCollada; version 1.6.68 -- https://github.com/KhronosGroup/OpenCOLLADA
@ -3506,11 +3538,12 @@ Copyright (c) 2018 Jingwei Huang, Yichao Zhou, Matthias Niessner,
Jonathan Shewchuk and Leonidas Guibas. All rights reserved.
** robin-map; version 0.6.2 -- https://github.com/Tessil/robin-map
Copyright (c) 2017 Thibaut Goetghebuer-Planchon <tessil@gmx.com>
** sse2neon; version 1.6.0 -- https://github.com/DLTcollab/sse2neon
** sse2neon; version cfaa59fc04fecb117c0a0f3fe9c82dece6f359ad --
https://github.com/DLTcollab/sse2neon
Copyright sse2neon contributors
** TinyGLTF; version 2.8.21 -- https://github.com/syoyo/tinygltf
** TinyGLTF; version 2.5.0 -- https://github.com/syoyo/tinygltf
Copyright (c) 2017 Syoyo Fujita, Aurélien Chatelain and many contributors
** Wayland protocols; version 1.31 --
** Wayland protocols; version 1.32 --
https://gitlab.freedesktop.org/wayland/wayland-protocols
Copyright © 2008-2013 Kristian Høgsberg
Copyright © 2010-2013 Intel Corporation
@ -3605,7 +3638,7 @@ PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
------
** OpenVDB; version 10.0.0 -- http://www.openvdb.org/
** OpenVDB; version 11.0.0 -- http://www.openvdb.org/
Copyright Contributors to the OpenVDB Project
Mozilla Public License Version 2.0
@ -4037,7 +4070,7 @@ IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
------
** The LLVM Compiler Infrastructure; version 12.0.0 --
** The LLVM Compiler Infrastructure; version 17.0.6 --
https://github.com/llvm/llvm-project/
University of Illinois/NCSA
Open Source License
@ -4063,9 +4096,9 @@ Software.
------
** OpenSubdiv; version 3.5.0 -- http://graphics.pixar.com/opensubdiv
** OpenSubdiv; version 3.6.0 -- http://graphics.pixar.com/opensubdiv
Copyright 2013 Pixar
** Universal Scene Description; version 23.05 -- http://www.openusd.org/
** Universal Scene Description; version 23.11 -- http://www.openusd.org/
Copyright 2016 Pixar
Licensed under the Apache License, Version 2.0 (the "Apache License") with the
@ -4110,7 +4143,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
------
** Boost C++ Libraries; version 1.80.0 -- https://www.boost.org/
** Boost C++ Libraries; version 1.82.0 -- https://www.boost.org/
The Boost license encourages both commercial and non-commercial use and does
not require attribution for binary use.
@ -4276,7 +4309,7 @@ MIT Expat
------
** Python; version 3.10.13 -- https://www.python.org
** Python; version 3.11.7 -- https://www.python.org
Copyright (c) 2001-2021 Python Software Foundation. All rights reserved.
A. HISTORY OF THE SOFTWARE
@ -4563,6 +4596,33 @@ PERFORMANCE OF THIS SOFTWARE.
------
** libffi; version 3.4.4 -- https://github.com/libffi/libffi/
libffi - Copyright (c) 1996-2024 Anthony Green, Red Hat, Inc and others.
libffi - Copyright (c) 1996-2024 Anthony Green, Red Hat, Inc and others.
See source files for details.
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.
------
** Flex; version 2.6.4 -- https://github.com/westes/flex
Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The Flex Project.

View File

@ -319,14 +319,29 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non
is_extension = module_name.startswith(_ext_base_pkg_idname_with_dot)
if handle_error is None:
def handle_error(_ex):
def handle_error(ex):
if isinstance(ex, ImportError):
# NOTE: checking "Add-on " prefix is rather weak,
# it's just a way to avoid the noise of a full trace-back when
# an add-on is simply missing on the file-system.
if (type(msg := ex.msg) is str) and msg.startswith("Add-on "):
print(msg)
return
import traceback
traceback.print_exc()
# reload if the mtime changes
mod = sys.modules.get(module_name)
# chances of the file _not_ existing are low, but it could be removed
if mod and os.path.exists(mod.__file__):
# Set to `mod.__file__` or None.
mod_file = None
if (
(mod is not None) and
(mod_file := mod.__file__) is not None and
os.path.exists(mod_file)
):
if getattr(mod, "__addon_enabled__", False):
# This is an unlikely situation,
@ -336,18 +351,15 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non
try:
mod.unregister()
except BaseException as ex:
print(
"Exception in module unregister():",
repr(getattr(mod, "__file__", module_name)),
)
print("Exception in module unregister():", (mod_file or module_name))
handle_error(ex)
return None
mod.__addon_enabled__ = False
mtime_orig = getattr(mod, "__time__", 0)
mtime_new = os.path.getmtime(mod.__file__)
mtime_new = os.path.getmtime(mod_file)
if mtime_orig != mtime_new:
print("module changed on disk:", repr(mod.__file__), "reloading...")
print("module changed on disk:", repr(mod_file), "reloading...")
try:
importlib.reload(mod)
@ -374,11 +386,20 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non
# Use instead of `__import__` so that sub-modules can eventually be supported.
# This is also documented to be the preferred way to import modules.
mod = importlib.import_module(module_name)
if mod.__file__ is None:
# This can happen when the addon has been removed but there are
# residual `.pyc` files left behind.
raise ImportError(name=module_name)
mod.__time__ = os.path.getmtime(mod.__file__)
if (mod_file := mod.__file__) is None:
# This can happen when:
# - The add-on has been removed but there are residual `.pyc` files left behind.
# - An extension is a directory that doesn't contain an `__init__.py` file.
#
# Include a message otherwise the "cause:" for failing to load the module is left blank.
# Include the `__path__` when available so there is a reference to the location that failed to load.
raise ImportError(
"module loaded with no associated file, __path__=%r, aborting!" % (
getattr(mod, "__path__", None)
),
name=module_name
)
mod.__time__ = os.path.getmtime(mod_file)
mod.__addon_enabled__ = False
except BaseException as ex:
# If the add-on doesn't exist, don't print full trace-back because the back-trace is in this case
@ -386,7 +407,7 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non
# Account for `ImportError` & `ModuleNotFoundError`.
if isinstance(ex, ImportError):
if ex.name == module_name:
print("Add-on not loaded: \"%s\", cause: %s" % (module_name, str(ex)))
ex.msg = "Add-on not loaded: \"%s\", cause: %s" % (module_name, str(ex))
# Issue with an add-on from an extension repository, report a useful message.
elif is_extension and module_name.startswith(ex.name + "."):
@ -396,22 +417,20 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non
None,
)
if repo is None:
print(
ex.msg = (
"Add-on not loaded: \"%s\", cause: extension repository \"%s\" doesn't exist" %
(module_name, repo_id)
)
elif not repo.enabled:
print(
ex.msg = (
"Add-on not loaded: \"%s\", cause: extension repository \"%s\" is disabled" %
(module_name, repo_id)
)
else:
# The repository exists and is enabled, it should have imported.
print("Add-on not loaded: \"%s\", cause: %s" % (module_name, str(ex)))
else:
handle_error(ex)
else:
handle_error(ex)
ex.msg = "Add-on not loaded: \"%s\", cause: %s" % (module_name, str(ex))
handle_error(ex)
if default_set:
_addon_remove(module_name)
@ -425,10 +444,13 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non
if bl_info is not None:
# Use `_init` to detect when `bl_info` was generated from the manifest, see: `_bl_info_from_extension`.
if type(bl_info) is dict and "_init" not in bl_info:
print(
"Add-on \"%s\" has a \"bl_info\" which will be ignored in favor of \"%s\"" %
(module_name, _ext_manifest_filename_toml)
)
# This print is noisy, hide behind a debug flag.
# Once `bl_info` is fully deprecated this should be changed to always print a warning.
if _bpy.app.debug_python:
print(
"Add-on \"%s\" has a \"bl_info\" which will be ignored in favor of \"%s\"" %
(module_name, _ext_manifest_filename_toml)
)
# Always remove as this is not expected to exist and will be lazily initialized.
del mod.bl_info
@ -443,10 +465,7 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non
try:
mod.register()
except BaseException as ex:
print(
"Exception in module register():",
getattr(mod, "__file__", module_name),
)
print("Exception in module register():", (mod_file or module_name))
handle_error(ex)
del sys.modules[module_name]
if default_set:
@ -490,7 +509,7 @@ def disable(module_name, *, default_set=False, handle_error=None):
# the add-on in the user preferences.
if mod and getattr(mod, "__addon_enabled__", False) is not False:
mod.__addon_enabled__ = False
mod.__addon_persistent = False
mod.__addon_persistent__ = False
try:
mod.unregister()
@ -503,7 +522,7 @@ def disable(module_name, *, default_set=False, handle_error=None):
print(
"addon_utils.disable: %s not %s" % (
module_name,
"disabled" if mod is None else "loaded")
"loaded" if mod is None else "enabled")
)
# could be in more than once, unlikely but better do this just in case.

View File

@ -10,6 +10,7 @@ __all__ = (
"app",
"context",
"data",
"msgbus",
"ops",
"path",
"props",

View File

@ -2,6 +2,10 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
__all__ = (
"ToolDef",
)
# Until we untangle ToolDef from bl_ui internals,
# use this module to document ToolDef.
from bl_ui.space_toolsystem_common import ToolDef

View File

@ -297,7 +297,7 @@ def axis_conversion(from_forward='Y', from_up='Z', to_forward='Y', to_up='Z'):
for i, axis_lut in enumerate(_axis_convert_lut):
if value in axis_lut:
return Matrix(_axis_convert_matrix[i])
assert 0
assert False, "unreachable"
def axis_conversion_ensure(operator, forward_attr, up_attr):

View File

@ -375,7 +375,7 @@ def draw_keymaps(context, layout):
rowsub.menu("USERPREF_MT_keyconfigs", text=text)
rowsub.operator("wm.keyconfig_preset_add", text="", icon='ADD')
rowsub.operator("wm.keyconfig_preset_add", text="", icon='REMOVE').remove_active = True
rowsub.operator("wm.keyconfig_preset_remove", text="", icon='REMOVE')
rowsub = split.row(align=True)
rowsub.operator("preferences.keyconfig_import", text="Import...", icon='IMPORT')

View File

@ -181,7 +181,7 @@ def write_sysinfo(filepath):
output.write("SDL: Blender was built without SDL support\n")
if bpy.app.background:
output.write("\nOpenGL: missing, background mode\n")
output.write("\nGPU: missing, background mode\n")
else:
output.write(title("GPU"))
output.write("renderer:\t%r\n" % gpu.platform.renderer_get())

View File

@ -768,7 +768,7 @@ def km_window(params):
("wm.search_menu", {"type": 'SPACE', "value": 'PRESS'}, None),
)
else:
assert False
assert False, "unreachable"
return keymap
@ -3530,7 +3530,7 @@ def km_frames(params):
("screen.animation_play", {"type": 'SPACE', "value": 'PRESS'}, None),
)
else:
assert False
assert False, "unreachable"
items.extend([
("screen.animation_play", {"type": 'SPACE', "value": 'PRESS', "shift": True, "ctrl": True},

View File

@ -147,8 +147,7 @@ class AddTorus(Operator, object_utils.AddObjectHelper):
)
major_radius: FloatProperty(
name="Major Radius",
description=("Radius from the origin to the "
"center of the cross sections"),
description="Radius from the origin to the center of the cross sections",
soft_min=0.0, soft_max=100.0,
min=0.0, max=10_000.0,
default=1.0,

View File

@ -529,6 +529,15 @@ class ARMATURE_OT_copy_bone_color_to_selected(Operator):
return {'FINISHED'}
def _armature_from_context(context):
pin_armature = getattr(context, 'armature', None)
if pin_armature:
return pin_armature
if context.object and context.object.type == 'ARMATURE':
return context.object.data
return None
class ARMATURE_OT_collection_show_all(Operator):
"""Show all bone collections"""
bl_idname = "armature.collection_show_all"
@ -537,10 +546,10 @@ class ARMATURE_OT_collection_show_all(Operator):
@classmethod
def poll(cls, context):
return context.object and context.object.type == 'ARMATURE' and context.object.data
return _armature_from_context(context) is not None
def execute(self, context):
arm = context.object.data
arm = _armature_from_context(context)
for bcoll in arm.collections_all:
bcoll.is_visible = True
return {'FINISHED'}
@ -554,15 +563,16 @@ class ARMATURE_OT_collection_unsolo_all(Operator):
@classmethod
def poll(cls, context):
if not (context.object and context.object.type == 'ARMATURE' and context.object.data):
armature = _armature_from_context(context)
if not armature:
return False
if not context.object.data.collections.is_solo_active:
if not armature.collections.is_solo_active:
cls.poll_message_set("None of the bone collections is marked 'solo'")
return False
return True
def execute(self, context):
arm = context.object.data
arm = _armature_from_context(context)
for bcoll in arm.collections_all:
bcoll.is_solo = False
return {'FINISHED'}
@ -578,16 +588,16 @@ class ARMATURE_OT_collection_remove_unused(Operator):
@classmethod
def poll(cls, context):
if not context.object or context.object.type != 'ARMATURE':
armature = _armature_from_context(context)
if not armature:
return False
arm = context.object.data
return len(arm.collections) > 0
return len(armature.collections) > 0
def execute(self, context):
if context.object.mode == 'EDIT':
if context.mode == 'EDIT_ARMATURE':
return self.execute_edit_mode(context)
armature = context.object.data
armature = _armature_from_context(context)
# Build a set of bone collections that don't contain any bones, and
# whose children also don't contain any bones.
@ -608,7 +618,7 @@ class ARMATURE_OT_collection_remove_unused(Operator):
# edit mode, because that has a completely separate list of edit bones.
# This is why edit mode needs separate handling.
armature = context.object.data
armature = _armature_from_context(context)
bcolls_with_bones = {
bcoll
for ebone in armature.edit_bones

View File

@ -760,8 +760,7 @@ class CLIP_OT_setup_tracking_scene(Operator):
def setup_space(space):
space.show_backdrop = True
CLIP_spaces_walk(context, True, 'NODE_EDITOR', 'NODE_EDITOR',
setup_space)
CLIP_spaces_walk(context, True, 'NODE_EDITOR', 'NODE_EDITOR', setup_space)
sc = context.space_data
scene = context.scene
@ -812,8 +811,7 @@ class CLIP_OT_setup_tracking_scene(Operator):
tree.links.new(movieclip.outputs["Image"], distortion.inputs["Image"])
if need_stabilization:
tree.links.new(distortion.outputs["Image"],
stabilize.inputs["Image"])
tree.links.new(distortion.outputs["Image"], stabilize.inputs["Image"])
tree.links.new(stabilize.outputs["Image"], scale.inputs["Image"])
else:
tree.links.new(distortion.outputs["Image"], scale.inputs["Image"])

View File

@ -42,8 +42,7 @@ class ConsoleExec(Operator):
if execute is not None:
return execute(context, self.interactive)
else:
print("Error: bpy.ops.console.execute_%s - not found" %
sc.language)
print("Error: bpy.ops.console.execute_%s - not found" % sc.language)
return {'FINISHED'}
@ -65,8 +64,7 @@ class ConsoleAutocomplete(Operator):
if autocomplete:
return autocomplete(context)
else:
print("Error: bpy.ops.console.autocomplete_%s - not found" %
sc.language)
print("Error: bpy.ops.console.autocomplete_%s - not found" % sc.language)
return {'FINISHED'}
@ -88,8 +86,7 @@ class ConsoleCopyAsScript(Operator):
if copy_as_script:
return copy_as_script(context)
else:
print("Error: copy_as_script - not found for %r" %
sc.language)
print("Error: copy_as_script - not found for %r" % sc.language)
return {'FINISHED'}
@ -115,8 +112,7 @@ class ConsoleBanner(Operator):
if banner:
return banner(context)
else:
print("Error: bpy.ops.console.banner_%s - not found" %
sc.language)
print("Error: bpy.ops.console.banner_%s - not found" % sc.language)
return {'FINISHED'}
@ -144,8 +140,7 @@ class ConsoleLanguage(Operator):
bpy.ops.console.banner()
# insert a new blank line
bpy.ops.console.history_append(text="", current_character=0,
remove_duplicates=True)
bpy.ops.console.history_append(text="", current_character=0, remove_duplicates=True)
return {'FINISHED'}

View File

@ -171,9 +171,7 @@ class MeshMirrorUV(Operator):
self.report({'WARNING'},
rpt_("%d mesh(es) with no active UV layer, "
"%d duplicates found in %d mesh(es), mirror may be incomplete")
% (total_no_active_UV,
total_duplicates,
meshes_with_duplicates))
% (total_no_active_UV, total_duplicates, meshes_with_duplicates))
elif total_no_active_UV:
self.report({'WARNING'},
rpt_("%d mesh(es) with no active UV layer")

View File

@ -58,8 +58,7 @@ class NodeAddOperator:
# convert mouse position to the View2D for later node placement
if context.region.type == 'WINDOW':
# convert mouse position to the View2D for later node placement
space.cursor_location_from_region(
event.mouse_region_x, event.mouse_region_y)
space.cursor_location_from_region(event.mouse_region_x, event.mouse_region_y)
else:
space.cursor_location = tree.view_center

View File

@ -223,8 +223,7 @@ class SubdivisionSet(Operator):
)
relative: BoolProperty(
name="Relative",
description=("Apply the subdivision surface level as an offset "
"relative to the current level"),
description="Apply the subdivision surface level as an offset relative to the current level",
default=False,
)
@ -288,8 +287,7 @@ class SubdivisionSet(Operator):
mod = obj.modifiers.new("Subdivision", 'SUBSURF')
mod.levels = level
except BaseException:
self.report({'WARNING'},
"Modifiers cannot be added to object: " + obj.name)
self.report({'WARNING'}, "Modifiers cannot be added to object: " + obj.name)
for obj in context.selected_editable_objects:
set_object_subd(obj)
@ -325,8 +323,7 @@ class ShapeTransfer(Operator):
)
use_clamp: BoolProperty(
name="Clamp Offset",
description=("Clamp the transformation to the distance each "
"vertex moves in the original shape"),
description="Clamp the transformation to the distance each vertex moves in the original shape",
default=False,
)
@ -447,8 +444,7 @@ class ShapeTransfer(Operator):
if use_clamp:
# clamp to the same movement as the original
# breaks copy between different scaled meshes.
len_from = (orig_shape_coords[i] -
orig_coords[i]).length
len_from = (orig_shape_coords[i] - orig_coords[i]).length
ofs = co - target_coords[i]
ofs.length = len_from
co = target_coords[i] + ofs

View File

@ -101,13 +101,7 @@ def worldspace_bounds_from_object_data(depsgraph, obj):
return Vector((left, front, up)), Vector((right, back, down))
def align_objects(context,
align_x,
align_y,
align_z,
align_mode,
relative_to,
bb_quality):
def align_objects(context, align_x, align_y, align_z, align_mode, relative_to, bb_quality):
depsgraph = context.evaluated_depsgraph_get()
scene = context.scene
@ -115,8 +109,7 @@ def align_objects(context,
cursor = scene.cursor.location
# We are accessing runtime data such as evaluated bounding box, so we need to
# be sure it is properly updated and valid (bounding box might be lost on operator
# redo).
# be sure it is properly updated and valid (bounding box might be lost on operator redo).
context.view_layer.update()
Left_Front_Up_SEL = [0.0, 0.0, 0.0]

View File

@ -277,9 +277,7 @@ class QuickExplode(ObjectModeOperator, Operator):
for obj in mesh_objects:
if obj.particle_systems:
self.report({'ERROR'},
rpt_("Object %r already has a "
"particle system") % obj.name)
self.report({'ERROR'}, rpt_("Object %r already has a " "particle system") % obj.name)
return {'CANCELLED'}
@ -518,8 +516,7 @@ class QuickSmoke(ObjectModeOperator, Operator):
# Add Principled Volume
node_principled = nodes.new(type='ShaderNodeVolumePrincipled')
node_principled.location = grid_location(4, 1)
links.new(node_principled.outputs["Volume"],
node_out.inputs["Volume"])
links.new(node_principled.outputs["Volume"], node_out.inputs["Volume"])
node_principled.inputs["Density"].default_value = 5.0

View File

@ -6,8 +6,7 @@ from bpy.types import Operator
from mathutils import Vector
def randomize_selected(context, seed, delta,
loc, rot, scale, scale_even, _scale_min):
def randomize_selected(context, seed, delta, loc, rot, scale, scale_even, _scale_min):
import random
from random import uniform
@ -100,8 +99,7 @@ class RandomizeLocRotSize(Operator):
)
use_delta: BoolProperty(
name="Transform Delta",
description=("Randomize delta transform values "
"instead of regular transform"),
description="Randomize delta transform values instead of regular transform",
default=False,
)
use_loc: BoolProperty(
@ -111,8 +109,7 @@ class RandomizeLocRotSize(Operator):
)
loc: FloatVectorProperty(
name="Location",
description=("Maximum distance the objects "
"can spread over each axis"),
description="Maximum distance the objects can spread over each axis",
min=-100.0,
max=100.0,
default=(0.0, 0.0, 0.0),
@ -174,8 +171,7 @@ class RandomizeLocRotSize(Operator):
# scale_min = self.scale_min
scale_min = 0
randomize_selected(context, seed, delta,
loc, rot, scale, scale_even, scale_min)
randomize_selected(context, seed, delta, loc, rot, scale, scale_even, scale_min)
return {'FINISHED'}

View File

@ -120,9 +120,7 @@ class AddPresetBase:
if is_xml:
import rna_xml
rna_xml.xml_file_write(context,
filepath,
preset_menu_class.preset_xml_map)
rna_xml.xml_file_write(context, filepath, preset_menu_class.preset_xml_map)
else:
def rna_recursive_attr_expand(value, rna_path_step, level):
@ -169,15 +167,10 @@ class AddPresetBase:
name = preset_menu_class.bl_label
# fairly sloppy but convenient.
filepath = bpy.utils.preset_find(name,
self.preset_subdir,
ext=ext)
filepath = bpy.utils.preset_find(name, self.preset_subdir, ext=ext)
if not filepath:
filepath = bpy.utils.preset_find(name,
self.preset_subdir,
display_name=True,
ext=ext)
filepath = bpy.utils.preset_find(name, self.preset_subdir, display_name=True, ext=ext)
if not filepath:
return {'CANCELLED'}
@ -257,9 +250,7 @@ class ExecutePreset(Operator):
elif ext == ".xml":
import rna_xml
rna_xml.xml_file_run(context,
filepath,
preset_class.preset_xml_map)
rna_xml.xml_file_run(context, filepath, preset_class.preset_xml_map)
if hasattr(preset_class, "post_cb"):
preset_class.post_cb(context)
@ -563,17 +554,44 @@ class AddPresetNodeColor(AddPresetBase, Operator):
class AddPresetInterfaceTheme(AddPresetBase, Operator):
"""Add or remove a theme preset"""
"""Add a custom theme to the preset list"""
bl_idname = "wm.interface_theme_preset_add"
bl_label = "Add Theme Preset"
bl_label = "Add Theme"
preset_menu = "USERPREF_MT_interface_theme_presets"
preset_subdir = "interface_theme"
class RemovePresetInterfaceTheme(AddPresetBase, Operator):
"""Remove a custom theme from the preset list"""
bl_idname = "wm.interface_theme_preset_remove"
bl_label = "Remove Theme"
preset_menu = "USERPREF_MT_interface_theme_presets"
preset_subdir = "interface_theme"
remove_active: BoolProperty(
default=True,
options={'HIDDEN', 'SKIP_SAVE'},
)
@classmethod
def poll(cls, context):
from bpy.utils import is_path_builtin
preset_menu_class = getattr(bpy.types, cls.preset_menu)
name = preset_menu_class.bl_label
filepath = bpy.utils.preset_find(name, cls.preset_subdir, ext=".xml")
if not bool(filepath) or is_path_builtin(filepath):
cls.poll_message_set("Built-in themes cannot be removed")
return False
return True
def invoke(self, context, event):
return context.window_manager.invoke_confirm(self, event, title="Remove Custom Theme", confirm_text="Delete")
class AddPresetKeyconfig(AddPresetBase, Operator):
"""Add or remove a Key-config Preset"""
"""Add a custom keymap configuration to the preset list"""
bl_idname = "wm.keyconfig_preset_add"
bl_label = "Add Keyconfig Preset"
bl_label = "Add Custom Keymap Configuration"
preset_menu = "USERPREF_MT_keyconfigs"
preset_subdir = "keyconfig"
@ -581,16 +599,43 @@ class AddPresetKeyconfig(AddPresetBase, Operator):
bpy.ops.preferences.keyconfig_export(filepath=filepath)
bpy.utils.keyconfig_set(filepath)
class RemovePresetKeyconfig(AddPresetBase, Operator):
"""Remove a custom keymap configuration from the preset list"""
bl_idname = "wm.keyconfig_preset_remove"
bl_label = "Remove Keymap Configuration"
preset_menu = "USERPREF_MT_keyconfigs"
preset_subdir = "keyconfig"
remove_active: BoolProperty(
default=True,
options={'HIDDEN', 'SKIP_SAVE'},
)
@classmethod
def poll(cls, context):
from bpy.utils import is_path_builtin
keyconfigs = bpy.context.window_manager.keyconfigs
preset_menu_class = getattr(bpy.types, cls.preset_menu)
name = keyconfigs.active.name
filepath = bpy.utils.preset_find(name, cls.preset_subdir, ext=".py")
if not bool(filepath) or is_path_builtin(filepath):
cls.poll_message_set("Built-in keymap configurations cannot be removed")
return False
return True
def pre_cb(self, context):
keyconfigs = bpy.context.window_manager.keyconfigs
if self.remove_active:
preset_menu_class = getattr(bpy.types, self.preset_menu)
preset_menu_class.bl_label = keyconfigs.active.name
preset_menu_class = getattr(bpy.types, self.preset_menu)
preset_menu_class.bl_label = keyconfigs.active.name
def post_cb(self, context):
keyconfigs = bpy.context.window_manager.keyconfigs
if self.remove_active:
keyconfigs.remove(keyconfigs.active)
keyconfigs.remove(keyconfigs.active)
def invoke(self, context, event):
return context.window_manager.invoke_confirm(
self, event, title="Remove Keymap Configuration", confirm_text="Delete")
class AddPresetOperator(AddPresetBase, Operator):
@ -811,7 +856,9 @@ classes = (
AddPresetFluid,
AddPresetHairDynamics,
AddPresetInterfaceTheme,
RemovePresetInterfaceTheme,
AddPresetKeyconfig,
RemovePresetKeyconfig,
AddPresetNodeColor,
AddPresetOperator,
AddPresetRender,

View File

@ -443,9 +443,13 @@ class PREFERENCES_OT_addon_enable(Operator):
def err_cb(ex):
import traceback
traceback.print_exc()
# The full trace-back in the UI is unwieldy and associated with unhandled exceptions.
# Only show a single exception instead of the full trace-back,
# developers can debug using information printed in the console.
nonlocal err_str
err_str = traceback.format_exc()
print(err_str)
err_str = str(ex)
mod = addon_utils.enable(self.module, default_set=True, handle_error=err_cb)

View File

@ -434,8 +434,7 @@ class RandomizeUVTransform(Operator):
)
loc: FloatVectorProperty(
name="Location",
description=("Maximum distance the objects "
"can spread over each axis"),
description="Maximum distance the objects can spread over each axis",
min=-100.0,
max=100.0,
size=2,

View File

@ -155,8 +155,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
return {'FINISHED'}
def execute(self, context):
return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(
self, context, False, self.dissolve_and_intersect)
return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(self, context, False, self.dissolve_and_intersect)
def invoke(self, context, _event):
return self.execute(context)

View File

@ -2084,8 +2084,7 @@ class WM_OT_properties_edit_value(Operator):
rna_item = eval("context.%s" % self.data_path)
if WM_OT_properties_edit.get_property_type(rna_item, self.property_name) == 'PYTHON':
self.eval_string = WM_OT_properties_edit.convert_custom_property_to_string(rna_item,
self.property_name)
self.eval_string = WM_OT_properties_edit.convert_custom_property_to_string(rna_item, self.property_name)
else:
self.eval_string = ""
@ -2960,7 +2959,7 @@ class WM_OT_batch_rename(Operator):
elif method == 'SUFFIX':
name = name + text
else:
assert 0
assert False, "unreachable"
elif ty == 'STRIP':
chars = action.strip_chars
@ -3005,9 +3004,9 @@ class WM_OT_batch_rename(Operator):
elif method == 'TITLE':
name = name.title()
else:
assert 0
assert False, "unreachable"
else:
assert 0
assert False, "unreachable"
return name
def _data_update(self, context):

View File

@ -24,10 +24,8 @@ class CollectionButtonsPanel:
def lineart_make_line_type_entry(col, line_type, text_disp, expand, search_from):
col.prop(line_type, "use", text=text_disp)
if line_type.use and expand:
col.prop_search(line_type, "layer", search_from,
"layers", icon='GREASEPENCIL')
col.prop_search(line_type, "material", search_from,
"materials", icon='SHADING_TEXTURE')
col.prop_search(line_type, "layer", search_from, "layers", icon='GREASEPENCIL')
col.prop_search(line_type, "material", search_from, "materials", icon='SHADING_TEXTURE')
class COLLECTION_PT_collection_flags(CollectionButtonsPanel, Panel):

View File

@ -87,20 +87,13 @@ class DATA_UL_bone_collections(UIList):
active_bone = armature.edit_bones.active or armature.bones.active
has_active_bone = active_bone and bcoll.name in active_bone.collections
layout.prop(bcoll, "name", text="", emboss=False,
icon='DOT' if has_active_bone else 'BLANK1')
layout.prop(bcoll, "name", text="", emboss=False, icon='DOT' if has_active_bone else 'BLANK1')
if armature.override_library:
icon = 'LIBRARY_DATA_OVERRIDE' if bcoll.is_local_override else 'BLANK1'
layout.prop(
bcoll,
"is_local_override",
text="",
emboss=False,
icon=icon)
layout.prop(bcoll, "is_local_override", text="", emboss=False, icon=icon)
layout.prop(bcoll, "is_visible", text="", emboss=False,
icon='HIDE_OFF' if bcoll.is_visible else 'HIDE_ON')
layout.prop(bcoll, "is_visible", text="", emboss=False, icon='HIDE_OFF' if bcoll.is_visible else 'HIDE_ON')
class DATA_PT_bone_collections(ArmatureButtonsPanel, Panel):

View File

@ -289,15 +289,12 @@ class BONE_PT_collections(BoneButtonsPanel, Panel):
# Sub-layout that's dimmed when the bone collection's own visibility flag doesn't matter.
sub_visible = row.row(align=True)
sub_visible.active = (not is_solo_active) and bcoll.is_visible_ancestors
sub_visible.prop(bcoll, "is_visible", text="",
icon='HIDE_OFF' if bcoll.is_visible else 'HIDE_ON')
sub_visible.prop(bcoll, "is_visible", text="", icon='HIDE_OFF' if bcoll.is_visible else 'HIDE_ON')
row.prop(bcoll, "is_solo", text="",
icon='SOLO_ON' if bcoll.is_solo else 'SOLO_OFF')
row.prop(bcoll, "is_solo", text="", icon='SOLO_ON' if bcoll.is_solo else 'SOLO_OFF')
# Unassignment operator, less safe so with a bit of spacing.
props = bcoll_row.operator("armature.collection_unassign_named",
text="", icon='X')
props = bcoll_row.operator("armature.collection_unassign_named", text="", icon='X')
props.name = bcoll.name
props.bone_name = bone.name
@ -410,8 +407,7 @@ class BONE_PT_display_custom_shape(BoneButtonsPanel, Panel):
sub.prop(pchan, "custom_shape_translation", text="Translation")
sub.prop(pchan, "custom_shape_rotation_euler", text="Rotation")
sub.prop_search(pchan, "custom_shape_transform",
ob.pose, "bones", text="Override Transform")
sub.prop_search(pchan, "custom_shape_transform", ob.pose, "bones", text="Override Transform")
sub.prop(pchan, "use_custom_shape_bone_size")
sub.separator()
@ -559,8 +555,7 @@ class BONE_PT_custom_props(BoneButtonsPanel, rna_prop_ui.PropertyPanel, Panel):
@classmethod
def _poll(cls, context):
context_path = cls._get_context_path(context)
rna_item, _context_member = rna_prop_ui.rna_idprop_context_value(
context, context_path, cls._property_type)
rna_item, _context_member = rna_prop_ui.rna_idprop_context_value(context, context_path, cls._property_type)
return bool(rna_item)
def draw(self, context):

View File

@ -156,8 +156,7 @@ class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel):
@classmethod
def poll(cls, context):
render = context.scene.render
return (super().poll(context) and render.use_multiview and
render.views_format == 'STEREO_3D')
return (super().poll(context) and render.use_multiview and render.views_format == 'STEREO_3D')
def draw(self, context):
layout = self.layout

View File

@ -119,6 +119,7 @@ class DATA_PT_EEVEE_light(DataButtonsPanel, Panel):
col.prop(light, "use_shadow", text="Cast Shadow")
col.prop(light, "shadow_softness_factor", text="Shadow Softness")
col.prop(light, "shadow_filter_radius", text="Filtering Radius")
col.prop(light, "shadow_resolution_scale", text="Resolution Scale")
if light.type == 'SUN':
col.prop(light, "shadow_trace_distance", text="Trace Distance")

View File

@ -637,8 +637,7 @@ class MESH_UL_color_attributes(UIList, ColorAttributesListBase):
sub = split.row()
sub.alignment = 'RIGHT'
sub.active = False
sub.label(text="%s%s" % (iface_(domain_name), iface_(data_type.name)),
translate=False)
sub.label(text="%s%s" % (iface_(domain_name), iface_(data_type.name)), translate=False)
active_render = _index == data.color_attributes.render_color_index

View File

@ -155,6 +155,7 @@ class OBJECT_MT_modifier_add_generate(ModifierAddMenu, Menu):
self.operator_modifier_add(layout, 'WIREFRAME')
if ob_type == 'GREASEPENCIL':
self.operator_modifier_add(layout, 'GREASE_PENCIL_ARRAY')
self.operator_modifier_add(layout, 'GREASE_PENCIL_BUILD')
self.operator_modifier_add(layout, 'GREASE_PENCIL_DASH')
self.operator_modifier_add(layout, 'GREASE_PENCIL_ENVELOPE')
self.operator_modifier_add(layout, 'GREASE_PENCIL_LENGTH')

View File

@ -754,8 +754,7 @@ class VIEWLAYER_PT_freestyle_linestyle_color(ViewLayerFreestyleLineStyle, Panel)
elif modifier.type == 'MATERIAL':
row = box.row()
row.prop(modifier, "material_attribute",
text="Material Attribute")
row.prop(modifier, "material_attribute", text="Material Attribute")
sub = box.column()
sub.prop(modifier, "use_ramp")
if modifier.material_attribute in {'LINE', 'DIFF', 'SPEC'}:

View File

@ -36,8 +36,7 @@ def draw_mask_context_menu(layout, _context):
class MASK_UL_layers(UIList):
def draw_item(self, _context, layout, _data, item, icon,
_active_data, _active_propname, _index):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
# assert(isinstance(item, bpy.types.MaskLayer)
mask = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
@ -204,8 +203,7 @@ class MASK_PT_point:
row = col.row()
row.prop(parent, "type", expand=True)
col.prop_search(parent, "parent", tracking,
"objects", icon='OBJECT_DATA', text="Object")
col.prop_search(parent, "parent", tracking, "objects", icon='OBJECT_DATA', text="Object")
tracks_list = "tracks" if parent.type == 'POINT_TRACK' else "plane_tracks"

View File

@ -391,8 +391,7 @@ class SmoothStrokePanel(BrushPanel):
brush = settings.brush
self.layout.use_property_split = False
self.layout.prop(brush, "use_smooth_stroke",
text=self.bl_label if self.is_popover else "")
self.layout.prop(brush, "use_smooth_stroke", text=self.bl_label if self.is_popover else "")
def draw(self, context):
layout = self.layout
@ -1344,8 +1343,7 @@ def brush_basic_gpencil_paint_settings(layout, context, brush, *, compact=False)
if gp_settings.use_pressure and not compact:
col = layout.column()
col.template_curve_mapping(gp_settings, "curve_sensitivity", brush=True,
use_negative_slope=True)
col.template_curve_mapping(gp_settings, "curve_sensitivity", brush=True, use_negative_slope=True)
row = layout.row(align=True)
row.prop(gp_settings, "pen_strength", slider=True)
@ -1353,8 +1351,7 @@ def brush_basic_gpencil_paint_settings(layout, context, brush, *, compact=False)
if gp_settings.use_strength_pressure and not compact:
col = layout.column()
col.template_curve_mapping(gp_settings, "curve_strength", brush=True,
use_negative_slope=True)
col.template_curve_mapping(gp_settings, "curve_strength", brush=True, use_negative_slope=True)
if brush.gpencil_tool == 'TINT':
row = layout.row(align=True)
@ -1415,8 +1412,7 @@ def brush_basic_grease_pencil_paint_settings(layout, context, brush, *, compact=
if brush.use_pressure_size and not compact:
col = layout.column()
col.template_curve_mapping(gp_settings, "curve_sensitivity", brush=True,
use_negative_slope=True)
col.template_curve_mapping(gp_settings, "curve_sensitivity", brush=True, use_negative_slope=True)
UnifiedPaintPanel.prop_unified(
layout,
@ -1431,8 +1427,7 @@ def brush_basic_grease_pencil_paint_settings(layout, context, brush, *, compact=
if brush.use_pressure_strength and not compact:
col = layout.column()
col.template_curve_mapping(gp_settings, "curve_strength", brush=True,
use_negative_slope=True)
col.template_curve_mapping(gp_settings, "curve_strength", brush=True, use_negative_slope=True)
if grease_pencil_tool == 'DRAW':
layout.prop(gp_settings, "active_smooth_factor")

View File

@ -87,9 +87,7 @@ class PARTICLE_MT_context_menu(Menu):
props.remove_target_particles = True
if psys is not None and psys.settings.type == 'HAIR':
layout.operator(
"curves.convert_from_particle_system",
text="Convert to Curves")
layout.operator("curves.convert_from_particle_system", text="Convert to Curves")
layout.separator()

View File

@ -113,7 +113,8 @@ class RENDER_PT_color_management_display_settings(RenderButtonsPanel, Panel):
col = layout.column(align=True)
sub = col.row()
sub.active = (not view.view_transform.startswith("Filmic") and not view.view_transform.startswith("AgX") and not
view.view_transform.startswith("False Color"))
view.view_transform.startswith("False Color") and not
view.view_transform.startswith("Khronos PBR Neutral"))
sub.prop(view, "use_hdr_view")
@ -197,6 +198,7 @@ class RENDER_PT_eevee_next_horizon_scan(RenderButtonsPanel, Panel):
col.prop(props, "horizon_quality", text="Precision")
col.prop(props, "horizon_thickness", text="Thickness")
col.prop(props, "horizon_bias", text="Bias")
col.prop(props, "horizon_resolution", text="Resolution")
class RENDER_PT_eevee_motion_blur(RenderButtonsPanel, Panel):
@ -725,6 +727,9 @@ class RENDER_PT_eevee_next_shadows(RenderButtonsPanel, Panel):
col = layout.column()
col.prop(props, "shadow_normal_bias", text="Normal Bias")
col = layout.column()
col.prop(props, "use_shadow_jittered_viewport", text="Jittered Transparency (Viewport)")
class RENDER_PT_eevee_sampling(RenderButtonsPanel, Panel):
bl_label = "Sampling"

View File

@ -151,8 +151,7 @@ class VIEWLAYER_PT_eevee_layer_passes_light(ViewLayerButtonsPanel, Panel):
col.prop(view_layer, "use_pass_emit", text="Emission")
col.prop(view_layer, "use_pass_environment")
col.prop(view_layer, "use_pass_shadow")
col.prop(view_layer, "use_pass_ambient_occlusion",
text="Ambient Occlusion")
col.prop(view_layer, "use_pass_ambient_occlusion", text="Ambient Occlusion")
class VIEWLAYER_PT_eevee_next_layer_passes_light(ViewLayerButtonsPanel, Panel):
@ -184,8 +183,7 @@ class VIEWLAYER_PT_eevee_next_layer_passes_light(ViewLayerButtonsPanel, Panel):
col.prop(view_layer, "use_pass_emit", text="Emission")
col.prop(view_layer, "use_pass_environment")
col.prop(view_layer, "use_pass_shadow")
col.prop(view_layer, "use_pass_ambient_occlusion",
text="Ambient Occlusion")
col.prop(view_layer, "use_pass_ambient_occlusion", text="Ambient Occlusion")
col = layout.column()
col.active = view_layer.use_pass_ambient_occlusion
@ -230,8 +228,7 @@ class ViewLayerAOVPanel(ViewLayerButtonsPanel, Panel):
row = layout.row()
col = row.column()
col.template_list("VIEWLAYER_UL_aov", "aovs", view_layer,
"aovs", view_layer, "active_aov_index", rows=3)
col.template_list("VIEWLAYER_UL_aov", "aovs", view_layer, "aovs", view_layer, "active_aov_index", rows=3)
col = row.column()
sub = col.column(align=True)
@ -240,8 +237,7 @@ class ViewLayerAOVPanel(ViewLayerButtonsPanel, Panel):
aov = view_layer.active_aov
if aov and not aov.is_valid:
layout.label(
text="Conflicts with another render pass with the same name", icon='ERROR')
layout.label(text="Conflicts with another render pass with the same name", icon='ERROR')
class VIEWLAYER_PT_layer_passes_aov(ViewLayerAOVPanel):
@ -271,8 +267,7 @@ class ViewLayerCryptomattePanel(ViewLayerButtonsPanel, Panel):
col.prop(view_layer, "pass_cryptomatte_depth", text="Levels")
if context.engine == 'BLENDER_EEVEE':
col.prop(view_layer, "use_pass_cryptomatte_accurate",
text="Accurate Mode")
col.prop(view_layer, "use_pass_cryptomatte_accurate", text="Accurate Mode")
class VIEWLAYER_PT_layer_passes_cryptomatte(ViewLayerCryptomattePanel, Panel):

View File

@ -121,7 +121,7 @@ class EEVEE_WORLD_PT_volume(WorldButtonsPanel, Panel):
bl_label = "Volume"
bl_translation_context = i18n_contexts.id_id
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_EEVEE'}
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT'}
@classmethod
def poll(cls, context):

View File

@ -17,8 +17,7 @@ from bl_ui.properties_grease_pencil_common import (
class CLIP_UL_tracking_objects(UIList):
def draw_item(self, _context, layout, _data, item, _icon,
_active_data, _active_propname, _index):
def draw_item(self, _context, layout, _data, item, _icon, _active_data, _active_propname, _index):
# assert(isinstance(item, bpy.types.MovieTrackingObject)
tobj = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
@ -142,8 +141,7 @@ class CLIP_HT_header(Header):
props = row.operator("clip.track_markers", text="", icon='TRACKING_BACKWARDS_SINGLE')
props.backwards = True
props.sequence = False
props = row.operator("clip.track_markers", text="",
icon='TRACKING_BACKWARDS')
props = row.operator("clip.track_markers", text="", icon='TRACKING_BACKWARDS')
props.backwards = True
props.sequence = True
props = row.operator("clip.track_markers", text="", icon='TRACKING_FORWARDS')
@ -171,9 +169,7 @@ class CLIP_HT_header(Header):
r = active_object.reconstruction
if r.is_valid and sc.view == 'CLIP':
layout.label(text=rpt_("Solve error: %.2f px") %
(r.average_error),
translate=False)
layout.label(text=rpt_("Solve error: %.2f px") % (r.average_error), translate=False)
row = layout.row()
row.prop(sc, "pivot_point", text="", icon_only=True)
@ -433,16 +429,12 @@ class CLIP_PT_tracking_settings(CLIP_PT_tracking_panel, Panel):
row = col.row(align=True)
row.use_property_split = False
row.prop(settings, "use_default_red_channel",
text="R", toggle=True)
row.prop(settings, "use_default_green_channel",
text="G", toggle=True)
row.prop(settings, "use_default_blue_channel",
text="B", toggle=True)
row.prop(settings, "use_default_red_channel", text="R", toggle=True)
row.prop(settings, "use_default_green_channel", text="G", toggle=True)
row.prop(settings, "use_default_blue_channel", text="B", toggle=True)
col.separator()
col.operator("clip.track_settings_as_default",
text="Copy from Active Track")
col.operator("clip.track_settings_as_default", text="Copy from Active Track")
class CLIP_PT_tracking_settings_extras(CLIP_PT_tracking_panel, Panel):
@ -486,8 +478,7 @@ class CLIP_PT_tools_tracking(CLIP_PT_tracking_panel, Panel):
props = row.operator("clip.track_markers", text="", icon='TRACKING_BACKWARDS_SINGLE')
props.backwards = True
props.sequence = False
props = row.operator("clip.track_markers", text="",
icon='TRACKING_BACKWARDS')
props = row.operator("clip.track_markers", text="", icon='TRACKING_BACKWARDS')
props.backwards = True
props.sequence = True
props = row.operator("clip.track_markers", text="", icon='TRACKING_FORWARDS')
@ -712,8 +703,7 @@ class CLIP_PT_objects(CLIP_PT_clip_view_panel, Panel):
tracking = sc.clip.tracking
row = layout.row()
row.template_list("CLIP_UL_tracking_objects", "", tracking, "objects",
tracking, "active_object_index", rows=1)
row.template_list("CLIP_UL_tracking_objects", "", tracking, "objects", tracking, "active_object_index", rows=1)
sub = row.column(align=True)
@ -765,8 +755,7 @@ class CLIP_PT_track(CLIP_PT_tracking_panel, Panel):
row.prop(act_track, "use_grayscale_preview", text="B/W", toggle=True)
row.separator()
row.prop(act_track, "use_alpha_preview",
text="", toggle=True, icon='IMAGE_ALPHA')
row.prop(act_track, "use_alpha_preview", text="", toggle=True, icon='IMAGE_ALPHA')
layout.prop(act_track, "weight")
layout.prop(act_track, "weight_stab")
@ -810,8 +799,7 @@ class CLIP_PT_plane_track(CLIP_PT_tracking_panel, Panel):
layout.prop(active_track, "name")
layout.prop(active_track, "use_auto_keying")
row = layout.row()
row.template_ID(
active_track, "image", new="image.new", open="image.open")
row.template_ID(active_track, "image", new="image.new", open="image.open")
row.menu("CLIP_MT_plane_track_image_context_menu", icon='DOWNARROW_HLT', text="")
row = layout.row()
@ -1642,10 +1630,8 @@ class CLIP_MT_tracking_context_menu(Menu):
layout.separator()
layout.operator("clip.disable_markers",
text="Disable Markers").action = 'DISABLE'
layout.operator("clip.disable_markers",
text="Enable Markers").action = 'ENABLE'
layout.operator("clip.disable_markers", text="Disable Markers").action = 'DISABLE'
layout.operator("clip.disable_markers", text="Enable Markers").action = 'ENABLE'
layout.separator()
@ -1655,8 +1641,7 @@ class CLIP_MT_tracking_context_menu(Menu):
layout.separator()
layout.operator("clip.lock_tracks", text="Lock Tracks").action = 'LOCK'
layout.operator("clip.lock_tracks",
text="Unlock Tracks").action = 'UNLOCK'
layout.operator("clip.lock_tracks", text="Unlock Tracks").action = 'UNLOCK'
layout.separator()

View File

@ -73,9 +73,7 @@ class CONSOLE_MT_language(Menu):
languages.sort()
for language in languages:
layout.operator("console.language",
text=language.title(),
translate=False).language = language
layout.operator("console.language", text=language.title(), translate=False).language = language
class CONSOLE_MT_console(Menu):

View File

@ -179,8 +179,7 @@ class DOPESHEET_PT_filters(DopesheetFilterPopoverBase, Panel):
if ds_mode in {'DOPESHEET', 'ACTION', 'GPENCIL'}:
layout.separator()
generic_filters_only = ds_mode != 'DOPESHEET'
DopesheetFilterPopoverBase.draw_search_filters(context, layout,
generic_filters_only=generic_filters_only)
DopesheetFilterPopoverBase.draw_search_filters(context, layout, generic_filters_only=generic_filters_only)
if ds_mode == 'DOPESHEET':
layout.separator()

View File

@ -142,12 +142,10 @@ class FILEBROWSER_PT_filter(FileBrowserPanel, Panel):
else:
row = col.row()
row.label(icon='FILE_BLEND')
row.prop(params, "use_filter_blender",
text=".blend Files", toggle=False)
row.prop(params, "use_filter_blender", text=".blend Files", toggle=False)
row = col.row()
row.label(icon='FILE_BACKUP')
row.prop(params, "use_filter_backup",
text="Backup .blend Files", toggle=False)
row.prop(params, "use_filter_backup", text="Backup .blend Files", toggle=False)
row = col.row()
row.label(icon='FILE_IMAGE')
row.prop(params, "use_filter_image", text="Image Files", toggle=False)
@ -156,8 +154,7 @@ class FILEBROWSER_PT_filter(FileBrowserPanel, Panel):
row.prop(params, "use_filter_movie", text="Movie Files", toggle=False)
row = col.row()
row.label(icon='FILE_SCRIPT')
row.prop(params, "use_filter_script",
text="Script Files", toggle=False)
row.prop(params, "use_filter_script", text="Script Files", toggle=False)
row = col.row()
row.label(icon='FILE_FONT')
row.prop(params, "use_filter_font", text="Font Files", toggle=False)
@ -176,8 +173,7 @@ class FILEBROWSER_PT_filter(FileBrowserPanel, Panel):
if is_lib_browser:
row = col.row()
row.label(icon='BLANK1') # Indentation
row.prop(params, "use_filter_blendid",
text="Blender IDs", toggle=False)
row.prop(params, "use_filter_blendid", text="Blender IDs", toggle=False)
if params.use_filter_blendid:
row = col.row()
row.label(icon='BLANK1') # Indentation
@ -281,10 +277,8 @@ class FILEBROWSER_MT_bookmarks_context_menu(Menu):
layout.operator("file.bookmark_cleanup", icon='X', text="Cleanup")
layout.separator()
layout.operator("file.bookmark_move", icon='TRIA_UP_BAR',
text="Move to Top").direction = 'TOP'
layout.operator("file.bookmark_move", icon='TRIA_DOWN_BAR',
text="Move to Bottom").direction = 'BOTTOM'
layout.operator("file.bookmark_move", icon='TRIA_UP_BAR', text="Move to Top").direction = 'TOP'
layout.operator("file.bookmark_move", icon='TRIA_DOWN_BAR', text="Move to Bottom").direction = 'BOTTOM'
class FILEBROWSER_PT_bookmarks_favorites(FileBrowserPanel, Panel):
@ -314,15 +308,12 @@ class FILEBROWSER_PT_bookmarks_favorites(FileBrowserPanel, Panel):
col = row.column(align=True)
col.operator("file.bookmark_add", icon='ADD', text="")
col.operator("file.bookmark_delete", icon='REMOVE', text="")
col.menu("FILEBROWSER_MT_bookmarks_context_menu",
icon='DOWNARROW_HLT', text="")
col.menu("FILEBROWSER_MT_bookmarks_context_menu", icon='DOWNARROW_HLT', text="")
if num_rows > 1:
col.separator()
col.operator("file.bookmark_move", icon='TRIA_UP',
text="").direction = 'UP'
col.operator("file.bookmark_move", icon='TRIA_DOWN',
text="").direction = 'DOWN'
col.operator("file.bookmark_move", icon='TRIA_UP', text="").direction = 'UP'
col.operator("file.bookmark_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
else:
layout.operator("file.bookmark_add", icon='ADD')
@ -553,10 +544,8 @@ class FILEBROWSER_MT_context_menu(FileBrowserMenu, Menu):
layout.separator()
layout.operator("file.filenum", text="Increase Number",
icon='ADD').increment = 1
layout.operator("file.filenum", text="Decrease Number",
icon='REMOVE').increment = -1
layout.operator("file.filenum", text="Increase Number", icon='ADD').increment = 1
layout.operator("file.filenum", text="Decrease Number", icon='REMOVE').increment = -1
layout.separator()

View File

@ -194,8 +194,7 @@ class IMAGE_MT_image(Menu):
ima = sima.image
show_render = sima.show_render
layout.operator("image.new", text="New",
text_ctxt=i18n_contexts.id_image)
layout.operator("image.new", text="New", text_ctxt=i18n_contexts.id_image)
layout.operator("image.open", text="Open...", icon='FILE_FOLDER')
layout.operator("image.read_viewlayers")

View File

@ -81,9 +81,7 @@ class INFO_MT_area(Menu):
layout.separator()
layout.operator("screen.screen_full_area")
layout.operator(
"screen.screen_full_area",
text="Toggle Fullscreen Area").use_hide_panels = True
layout.operator("screen.screen_full_area", text="Toggle Fullscreen Area").use_hide_panels = True
layout.operator("screen.area_dupli")
layout.separator()

View File

@ -223,8 +223,7 @@ class OUTLINER_MT_collection(Menu):
space = context.space_data
layout.operator("outliner.collection_new", text="New",
text_ctxt=i18n_contexts.id_collection).nested = True
layout.operator("outliner.collection_new", text="New", text_ctxt=i18n_contexts.id_collection).nested = True
layout.operator("outliner.collection_duplicate", text="Duplicate Collection")
layout.operator("outliner.collection_duplicate_linked", text="Duplicate Linked")
layout.operator("outliner.id_copy", text="Copy", icon='COPYDOWN')

View File

@ -31,14 +31,12 @@ class TEXT_HT_header(Header):
row.operator("text.resolve_conflict", text="", icon='QUESTION')
row = layout.row(align=True)
row.template_ID(st, "text", new="text.new",
unlink="text.unlink", open="text.open")
row.template_ID(st, "text", new="text.new", unlink="text.unlink", open="text.open")
if text:
is_osl = text.name.endswith((".osl", ".osl"))
if is_osl:
row.operator("node.shader_script_update",
text="", icon='FILE_REFRESH')
row.operator("node.shader_script_update", text="", icon='FILE_REFRESH')
else:
row = layout.row()
row.active = is_syntax_highlight_supported
@ -174,10 +172,8 @@ class TEXT_PT_find(Panel):
row = layout.row(align=True)
if not st.text:
row.active = False
row.prop(st, "use_match_case", text="Case",
text_ctxt=i18n_contexts.id_text, toggle=True)
row.prop(st, "use_find_wrap", text="Wrap",
text_ctxt=i18n_contexts.id_text, toggle=True)
row.prop(st, "use_match_case", text="Case", text_ctxt=i18n_contexts.id_text, toggle=True)
row.prop(st, "use_find_wrap", text="Wrap", text_ctxt=i18n_contexts.id_text, toggle=True)
row.prop(st, "use_find_all", text="All", toggle=True)
@ -253,8 +249,7 @@ class TEXT_MT_text(Menu):
st = context.space_data
text = st.text
layout.operator("text.new", text="New",
text_ctxt=i18n_contexts.id_text, icon='FILE_NEW')
layout.operator("text.new", text="New", text_ctxt=i18n_contexts.id_text, icon='FILE_NEW')
layout.operator("text.open", text="Open...", icon='FILE_FOLDER')
if text:

View File

@ -226,8 +226,7 @@ class ToolSelectPanelHelper:
@staticmethod
def _tool_class_from_space_type(space_type):
return next(
(cls for cls in ToolSelectPanelHelper.__subclasses__()
if cls.bl_space_type == space_type),
(cls for cls in ToolSelectPanelHelper.__subclasses__() if cls.bl_space_type == space_type),
None,
)

View File

@ -33,17 +33,9 @@ class TOPBAR_HT_upper_bar(Header):
layout.separator()
if not screen.show_fullscreen:
layout.template_ID_tabs(
window, "workspace",
new="workspace.add",
menu="TOPBAR_MT_workspace_menu",
)
layout.template_ID_tabs(window, "workspace", new="workspace.add", menu="TOPBAR_MT_workspace_menu")
else:
layout.operator(
"screen.back_to_previous",
icon='SCREEN_BACK',
text="Back to Previous",
)
layout.operator("screen.back_to_previous", icon='SCREEN_BACK', text="Back to Previous")
def draw_right(self, context):
layout = self.layout
@ -58,8 +50,7 @@ class TOPBAR_HT_upper_bar(Header):
layout.template_running_jobs()
# Active workspace view-layer is retrieved through window, not through workspace.
layout.template_ID(window, "scene", new="scene.new",
unlink="scene.delete")
layout.template_ID(window, "scene", new="scene.new", unlink="scene.delete")
row = layout.row(align=True)
row.template_search(
@ -84,11 +75,9 @@ class TOPBAR_PT_tool_settings_extra(Panel):
layout = self.layout
# Get the active tool
space_type, mode = ToolSelectPanelHelper._tool_key_from_context(
context)
space_type, mode = ToolSelectPanelHelper._tool_key_from_context(context)
cls = ToolSelectPanelHelper._tool_class_from_space_type(space_type)
item, tool, _ = cls._tool_get_active(
context, space_type, mode, with_icon=True)
item, tool, _ = cls._tool_get_active(context, space_type, mode, with_icon=True)
if item is None:
return
@ -110,8 +99,7 @@ class TOPBAR_PT_tool_fallback(Panel):
ToolSelectPanelHelper.draw_fallback_tool_items(layout, context)
if tool_settings.workspace_tool_type == 'FALLBACK':
tool = context.tool
ToolSelectPanelHelper.draw_active_tool_fallback(
context, layout, tool)
ToolSelectPanelHelper.draw_active_tool_fallback(context, layout, tool)
class TOPBAR_PT_gpencil_layers(Panel):
@ -156,8 +144,7 @@ class TOPBAR_PT_gpencil_layers(Panel):
srow = col.row(align=True)
srow.prop(gpl, "opacity", text="Opacity", slider=True)
srow.prop(gpl, "use_mask_layer", text="",
icon='CLIPUV_DEHLT' if gpl.use_mask_layer else 'CLIPUV_HLT')
srow.prop(gpl, "use_mask_layer", text="", icon='CLIPUV_DEHLT' if gpl.use_mask_layer else 'CLIPUV_HLT')
srow = col.row(align=True)
srow.prop(gpl, "use_lights", text="Lights")
@ -170,25 +157,20 @@ class TOPBAR_PT_gpencil_layers(Panel):
gpl = context.active_gpencil_layer
if gpl:
sub.menu("GPENCIL_MT_layer_context_menu",
icon='DOWNARROW_HLT', text="")
sub.menu("GPENCIL_MT_layer_context_menu", icon='DOWNARROW_HLT', text="")
if len(gpd.layers) > 1:
col.separator()
sub = col.column(align=True)
sub.operator("gpencil.layer_move",
icon='TRIA_UP', text="").type = 'UP'
sub.operator("gpencil.layer_move",
icon='TRIA_DOWN', text="").type = 'DOWN'
sub.operator("gpencil.layer_move", icon='TRIA_UP', text="").type = 'UP'
sub.operator("gpencil.layer_move", icon='TRIA_DOWN', text="").type = 'DOWN'
col.separator()
sub = col.column(align=True)
sub.operator("gpencil.layer_isolate", icon='HIDE_OFF',
text="").affect_visibility = True
sub.operator("gpencil.layer_isolate", icon='LOCKED',
text="").affect_visibility = False
sub.operator("gpencil.layer_isolate", icon='HIDE_OFF', text="").affect_visibility = True
sub.operator("gpencil.layer_isolate", icon='LOCKED', text="").affect_visibility = False
class TOPBAR_MT_editor_menus(Menu):
@ -224,8 +206,7 @@ class TOPBAR_MT_blender(Menu):
layout.separator()
layout.operator("preferences.app_template_install",
text="Install Application Template...")
layout.operator("preferences.app_template_install", text="Install Application Template...")
layout.separator()
@ -343,16 +324,11 @@ class TOPBAR_MT_file_new(Menu):
# Draw application templates.
if not use_more:
props = layout.operator(
"wm.read_homefile", text="General", icon=icon)
props = layout.operator("wm.read_homefile", text="General", icon=icon)
props.app_template = ""
for d in paths:
props = layout.operator(
"wm.read_homefile",
text=bpy.path.display_name(iface_(d)),
icon=icon,
)
props = layout.operator("wm.read_homefile", text=bpy.path.display_name(iface_(d)), icon=icon)
props.app_template = d
layout.operator_context = 'EXEC_DEFAULT'
@ -396,8 +372,7 @@ class TOPBAR_MT_file_defaults(Menu):
layout.operator("wm.save_homefile")
if app_template:
display_name = bpy.path.display_name(iface_(app_template))
props = layout.operator("wm.read_factory_settings",
text="Load Factory Blender Settings")
props = layout.operator("wm.read_factory_settings", text="Load Factory Blender Settings")
props.app_template = app_template
props = layout.operator("wm.read_factory_settings",
text=iface_("Load Factory %s Settings",
@ -435,8 +410,7 @@ class TOPBAR_MT_templates_more(Menu):
bl_label = "Templates"
def draw(self, context):
bpy.types.TOPBAR_MT_file_new.draw_ex(
self.layout, context, use_more=True)
bpy.types.TOPBAR_MT_file_new.draw_ex(self.layout, context, use_more=True)
class TOPBAR_MT_file_import(Menu):
@ -550,10 +524,8 @@ class TOPBAR_MT_render(Menu):
rd = context.scene.render
layout.operator("render.render", text="Render Image",
icon='RENDER_STILL').use_viewport = True
props = layout.operator(
"render.render", text="Render Animation", icon='RENDER_ANIMATION')
layout.operator("render.render", text="Render Image", icon='RENDER_STILL').use_viewport = True
props = layout.operator("render.render", text="Render Animation", icon='RENDER_ANIMATION')
props.animation = True
props.use_viewport = True
@ -612,8 +584,7 @@ class TOPBAR_MT_edit(Menu):
layout.separator()
layout.operator("screen.userpref_show",
text="Preferences...", icon='PREFERENCES')
layout.operator("screen.userpref_show", text="Preferences...", icon='PREFERENCES')
class TOPBAR_MT_window(Menu):
@ -634,10 +605,8 @@ class TOPBAR_MT_window(Menu):
layout.separator()
layout.operator("screen.workspace_cycle",
text="Next Workspace").direction = 'NEXT'
layout.operator("screen.workspace_cycle",
text="Previous Workspace").direction = 'PREV'
layout.operator("screen.workspace_cycle", text="Next Workspace").direction = 'NEXT'
layout.operator("screen.workspace_cycle", text="Previous Workspace").direction = 'PREV'
layout.separator()
@ -718,8 +687,7 @@ class TOPBAR_MT_file_context_menu(Menu):
layout.separator()
layout.operator("screen.userpref_show",
text="Preferences...", icon='PREFERENCES')
layout.operator("screen.userpref_show", text="Preferences...", icon='PREFERENCES')
class TOPBAR_MT_workspace_menu(Menu):
@ -728,26 +696,21 @@ class TOPBAR_MT_workspace_menu(Menu):
def draw(self, _context):
layout = self.layout
layout.operator("workspace.duplicate",
text="Duplicate", icon='DUPLICATE')
layout.operator("workspace.duplicate", text="Duplicate", icon='DUPLICATE')
if len(bpy.data.workspaces) > 1:
layout.operator("workspace.delete", text="Delete", icon='REMOVE')
layout.separator()
layout.operator("workspace.reorder_to_front",
text="Reorder to Front", icon='TRIA_LEFT_BAR')
layout.operator("workspace.reorder_to_back",
text="Reorder to Back", icon='TRIA_RIGHT_BAR')
layout.operator("workspace.reorder_to_front", text="Reorder to Front", icon='TRIA_LEFT_BAR')
layout.operator("workspace.reorder_to_back", text="Reorder to Back", icon='TRIA_RIGHT_BAR')
layout.separator()
# For key binding discoverability.
props = layout.operator("screen.workspace_cycle",
text="Previous Workspace")
props = layout.operator("screen.workspace_cycle", text="Previous Workspace")
props.direction = 'PREV'
props = layout.operator(
"screen.workspace_cycle", text="Next Workspace")
props = layout.operator("screen.workspace_cycle", text="Next Workspace")
props.direction = 'NEXT'
@ -762,8 +725,7 @@ class TOPBAR_PT_gpencil_primitive(Panel):
layout = self.layout
# Curve
layout.template_curve_mapping(
settings, "thickness_primitive_curve", brush=True)
layout.template_curve_mapping(settings, "thickness_primitive_curve", brush=True)
# Only a popover

View File

@ -876,7 +876,7 @@ class USERPREF_PT_theme(ThemePanel, Panel):
row = split.row(align=True)
row.menu("USERPREF_MT_interface_theme_presets", text=USERPREF_MT_interface_theme_presets.bl_label)
row.operator("wm.interface_theme_preset_add", text="", icon='ADD')
row.operator("wm.interface_theme_preset_add", text="", icon='REMOVE').remove_active = True
row.operator("wm.interface_theme_preset_remove", text="", icon='REMOVE')
row = split.row(align=True)
row.operator("preferences.theme_install", text="Install...", icon='IMPORT')
@ -1021,8 +1021,7 @@ class USERPREF_PT_theme_interface_transparent_checker(ThemePanel, CenterAlignMix
theme = context.preferences.themes[0]
ui = theme.user_interface
flow = layout.grid_flow(
row_major=False, columns=0, even_columns=True, even_rows=False, align=False)
flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False)
col = flow.column(align=True)
col.prop(ui, "transparent_checker_primary")
@ -2252,8 +2251,11 @@ class USERPREF_PT_addons(AddOnPanel, Panel):
prefs = context.preferences
use_extension_repos = prefs.experimental.use_extension_repos
if use_extension_repos and self.is_extended():
if (
prefs.view.show_developer_ui and
prefs.experimental.use_extension_repos and
self.is_extended()
):
# Rely on the draw function being appended to by the extensions add-on.
return
@ -2696,6 +2698,7 @@ class USERPREF_PT_experimental_prototypes(ExperimentalPanel, Panel):
({"property": "use_new_matrix_socket"}, ("blender/blender/issues/116067", "Matrix Socket")),
({"property": "enable_overlay_next"}, ("blender/blender/issues/102179", "#102179")),
({"property": "use_extension_repos"}, ("/blender/blender/issues/117286", "#117286")),
({"property": "use_extension_utils"}, ("/blender/blender/issues/117286", "#117286")),
),
)

View File

@ -843,8 +843,7 @@ class VIEW3D_HT_header(Header):
# Curve edit sub-mode.
row = layout.row(align=True)
row.prop(gpd, "use_curve_edit", text="",
icon='IPO_BEZIER')
row.prop(gpd, "use_curve_edit", text="", icon='IPO_BEZIER')
sub = row.row(align=True)
sub.active = gpd.use_curve_edit
sub.popover(
@ -974,8 +973,7 @@ class VIEW3D_HT_header(Header):
row.popover(panel="VIEW3D_PT_slots_projectpaint", icon=icon)
row.popover(
panel="VIEW3D_PT_mask",
icon=VIEW3D_HT_header._texture_mask_icon(
tool_settings.image_paint),
icon=VIEW3D_HT_header._texture_mask_icon(tool_settings.image_paint),
text="")
else:
# Transform settings depending on tool header visibility
@ -2680,7 +2678,7 @@ class VIEW3D_MT_image_add(Menu):
def draw(self, _context):
layout = self.layout
# Expliclitly set background mode on/off as operator will try to
# Explicitly set background mode on/off as operator will try to
# auto detect which mode to use otherwise.
layout.operator("object.empty_image_add", text="Reference", icon='IMAGE_REFERENCE').background = False
layout.operator("object.empty_image_add", text="Background", icon='IMAGE_BACKGROUND').background = True
@ -3138,9 +3136,7 @@ class VIEW3D_MT_object_apply(Menu):
text_ctxt=i18n_contexts.default,
).target = 'MESH'
layout.operator("object.duplicates_make_real")
layout.operator("object.parent_inverse_apply",
text="Parent Inverse",
text_ctxt=i18n_contexts.default)
layout.operator("object.parent_inverse_apply", text="Parent Inverse", text_ctxt=i18n_contexts.default)
layout.template_node_operator_asset_menu_items(catalog_path="Object/Apply")
@ -4113,8 +4109,7 @@ class VIEW3D_MT_bone_collections(Menu):
layout.separator()
layout.operator("armature.collection_show_all")
props = layout.operator("armature.collection_create_and_assign",
text="Assign to New Collection")
props = layout.operator("armature.collection_create_and_assign", text="Assign to New Collection")
props.name = "New Collection"
@ -4496,12 +4491,9 @@ class VIEW3D_MT_edit_mesh_context_menu(Menu):
col.separator()
col.operator("view3d.edit_mesh_extrude_move_normal",
text="Extrude Faces")
col.operator("view3d.edit_mesh_extrude_move_shrink_fatten",
text="Extrude Faces Along Normals")
col.operator("mesh.extrude_faces_move",
text="Extrude Individual Faces")
col.operator("view3d.edit_mesh_extrude_move_normal", text="Extrude Faces")
col.operator("view3d.edit_mesh_extrude_move_shrink_fatten", text="Extrude Faces Along Normals")
col.operator("mesh.extrude_faces_move", text="Extrude Individual Faces")
col.operator("mesh.inset")
col.operator("mesh.poke")
@ -4561,23 +4553,16 @@ class VIEW3D_MT_edit_mesh_extrude(Menu):
mesh = context.object.data
if mesh.total_face_sel:
layout.operator("view3d.edit_mesh_extrude_move_normal",
text="Extrude Faces")
layout.operator("view3d.edit_mesh_extrude_move_shrink_fatten",
text="Extrude Faces Along Normals")
layout.operator(
"mesh.extrude_faces_move",
text="Extrude Individual Faces")
layout.operator("view3d.edit_mesh_extrude_manifold_normal",
text="Extrude Manifold")
layout.operator("view3d.edit_mesh_extrude_move_normal", text="Extrude Faces")
layout.operator("view3d.edit_mesh_extrude_move_shrink_fatten", text="Extrude Faces Along Normals")
layout.operator("mesh.extrude_faces_move", text="Extrude Individual Faces")
layout.operator("view3d.edit_mesh_extrude_manifold_normal", text="Extrude Manifold")
if mesh.total_edge_sel and (select_mode[0] or select_mode[1]):
layout.operator("mesh.extrude_edges_move",
text="Extrude Edges")
layout.operator("mesh.extrude_edges_move", text="Extrude Edges")
if mesh.total_vert_sel and select_mode[0]:
layout.operator("mesh.extrude_vertices_move",
text="Extrude Vertices")
layout.operator("mesh.extrude_vertices_move", text="Extrude Vertices")
layout.separator()
@ -4742,10 +4727,8 @@ class VIEW3D_MT_edit_mesh_faces(Menu):
layout.operator_context = 'INVOKE_REGION_WIN'
layout.operator("view3d.edit_mesh_extrude_move_normal",
text="Extrude Faces")
layout.operator("view3d.edit_mesh_extrude_move_shrink_fatten",
text="Extrude Faces Along Normals")
layout.operator("view3d.edit_mesh_extrude_move_normal", text="Extrude Faces")
layout.operator("view3d.edit_mesh_extrude_move_shrink_fatten", text="Extrude Faces Along Normals")
layout.operator("mesh.extrude_faces_move", text="Extrude Individual Faces")
layout.separator()
@ -5665,8 +5648,7 @@ class VIEW3D_MT_edit_gpencil_stroke(Menu):
layout.separator()
layout.operator_menu_enum("gpencil.stroke_join", "type", text="Join",
text_ctxt=i18n_contexts.id_gpencil)
layout.operator_menu_enum("gpencil.stroke_join", "type", text="Join", text_ctxt=i18n_contexts.id_gpencil)
layout.separator()
@ -8156,8 +8138,7 @@ class VIEW3D_MT_gpencil_edit_context_menu(Menu):
# Removal Operators
col.operator("gpencil.stroke_merge_by_distance").use_unselected = True
col.operator_menu_enum("gpencil.stroke_join", "type", text="Join",
text_ctxt=i18n_contexts.id_gpencil)
col.operator_menu_enum("gpencil.stroke_join", "type", text="Join", text_ctxt=i18n_contexts.id_gpencil)
col.operator("gpencil.stroke_split", text="Split")
col.operator("gpencil.stroke_separate", text="Separate").mode = 'STROKE'

View File

@ -743,8 +743,7 @@ class VIEW3D_PT_stencil_projectpaint(Panel):
def draw_header(self, context):
ipaint = context.tool_settings.image_paint
self.layout.prop(ipaint, "use_stencil_layer",
text=self.bl_label if self.is_popover else "")
self.layout.prop(ipaint, "use_stencil_layer", text=self.bl_label if self.is_popover else "")
def draw(self, context):
layout = self.layout
@ -926,8 +925,7 @@ class VIEW3D_PT_tools_brush_falloff_frontface(View3DPaintPanel, Panel):
settings = self.paint_settings(context)
brush = settings.brush
self.layout.prop(brush, "use_frontface_falloff",
text=self.bl_label if self.is_popover else "")
self.layout.prop(brush, "use_frontface_falloff", text=self.bl_label if self.is_popover else "")
def draw(self, context):
settings = self.paint_settings(context)
@ -956,8 +954,7 @@ class VIEW3D_PT_tools_brush_falloff_normal(View3DPaintPanel, Panel):
tool_settings = context.tool_settings
ipaint = tool_settings.image_paint
self.layout.prop(ipaint, "use_normal_falloff",
text=self.bl_label if self.is_popover else "")
self.layout.prop(ipaint, "use_normal_falloff", text=self.bl_label if self.is_popover else "")
def draw(self, context):
tool_settings = context.tool_settings
@ -1406,8 +1403,7 @@ class VIEW3D_PT_tools_imagepaint_options_cavity(Panel):
tool_settings = context.tool_settings
ipaint = tool_settings.image_paint
self.layout.prop(ipaint, "use_cavity",
text=self.bl_label if self.is_popover else "")
self.layout.prop(ipaint, "use_cavity", text=self.bl_label if self.is_popover else "")
def draw(self, context):
layout = self.layout
@ -1417,8 +1413,7 @@ class VIEW3D_PT_tools_imagepaint_options_cavity(Panel):
layout.active = ipaint.use_cavity
layout.template_curve_mapping(ipaint, "cavity_curve", brush=True,
use_negative_slope=True)
layout.template_curve_mapping(ipaint, "cavity_curve", brush=True, use_negative_slope=True)
# TODO, move to space_view3d.py
@ -1706,8 +1701,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_advanced(View3DPanel, Panel):
elif brush.gpencil_tool == 'FILL':
row = col.row(align=True)
row.prop(gp_settings, "fill_draw_mode", text="Boundary",
text_ctxt=i18n_contexts.id_gpencil)
row.prop(gp_settings, "fill_draw_mode", text="Boundary", text_ctxt=i18n_contexts.id_gpencil)
row.prop(
gp_settings,
"show_fill_boundary",
@ -1771,8 +1765,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_stabilizer(Panel, View3DPanel):
brush = context.tool_settings.gpencil_paint.brush
gp_settings = brush.gpencil_settings
self.layout.use_property_split = False
self.layout.prop(gp_settings, "use_settings_stabilizer",
text=self.bl_label if self.is_popover else "")
self.layout.prop(gp_settings, "use_settings_stabilizer", text=self.bl_label if self.is_popover else "")
def draw(self, context):
layout = self.layout
@ -1805,8 +1798,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_post_processing(View3DPanel, Panel):
brush = context.tool_settings.gpencil_paint.brush
gp_settings = brush.gpencil_settings
self.layout.use_property_split = False
self.layout.prop(gp_settings, "use_settings_postprocess",
text=self.bl_label if self.is_popover else "")
self.layout.prop(gp_settings, "use_settings_postprocess", text=self.bl_label if self.is_popover else "")
def draw(self, context):
layout = self.layout
@ -1861,8 +1853,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel):
brush = context.tool_settings.gpencil_paint.brush
gp_settings = brush.gpencil_settings
self.layout.use_property_split = False
self.layout.prop(gp_settings, "use_settings_random",
text=self.bl_label if self.is_popover else "")
self.layout.prop(gp_settings, "use_settings_random", text=self.bl_label if self.is_popover else "")
def draw(self, context):
layout = self.layout
@ -1882,24 +1873,21 @@ class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel):
row.prop(gp_settings, "use_stroke_random_radius", text="", icon='GP_SELECT_STROKES')
row.prop(gp_settings, "use_random_press_radius", text="", icon='STYLUS_PRESSURE')
if gp_settings.use_random_press_radius and self.is_popover is False:
col.template_curve_mapping(gp_settings, "curve_random_pressure", brush=True,
use_negative_slope=True)
col.template_curve_mapping(gp_settings, "curve_random_pressure", brush=True, use_negative_slope=True)
row = col.row(align=True)
row.prop(gp_settings, "random_strength", text="Strength", slider=True)
row.prop(gp_settings, "use_stroke_random_strength", text="", icon='GP_SELECT_STROKES')
row.prop(gp_settings, "use_random_press_strength", text="", icon='STYLUS_PRESSURE')
if gp_settings.use_random_press_strength and self.is_popover is False:
col.template_curve_mapping(gp_settings, "curve_random_strength", brush=True,
use_negative_slope=True)
col.template_curve_mapping(gp_settings, "curve_random_strength", brush=True, use_negative_slope=True)
row = col.row(align=True)
row.prop(gp_settings, "uv_random", text="UV", slider=True)
row.prop(gp_settings, "use_stroke_random_uv", text="", icon='GP_SELECT_STROKES')
row.prop(gp_settings, "use_random_press_uv", text="", icon='STYLUS_PRESSURE')
if gp_settings.use_random_press_uv and self.is_popover is False:
col.template_curve_mapping(gp_settings, "curve_random_uv", brush=True,
use_negative_slope=True)
col.template_curve_mapping(gp_settings, "curve_random_uv", brush=True, use_negative_slope=True)
col.separator()
@ -1910,24 +1898,21 @@ class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel):
row.prop(gp_settings, "use_stroke_random_hue", text="", icon='GP_SELECT_STROKES')
row.prop(gp_settings, "use_random_press_hue", text="", icon='STYLUS_PRESSURE')
if gp_settings.use_random_press_hue and self.is_popover is False:
col1.template_curve_mapping(gp_settings, "curve_random_hue", brush=True,
use_negative_slope=True)
col1.template_curve_mapping(gp_settings, "curve_random_hue", brush=True, use_negative_slope=True)
row = col1.row(align=True)
row.prop(gp_settings, "random_saturation_factor", slider=True)
row.prop(gp_settings, "use_stroke_random_sat", text="", icon='GP_SELECT_STROKES')
row.prop(gp_settings, "use_random_press_sat", text="", icon='STYLUS_PRESSURE')
if gp_settings.use_random_press_sat and self.is_popover is False:
col1.template_curve_mapping(gp_settings, "curve_random_saturation", brush=True,
use_negative_slope=True)
col1.template_curve_mapping(gp_settings, "curve_random_saturation", brush=True, use_negative_slope=True)
row = col1.row(align=True)
row.prop(gp_settings, "random_value_factor", slider=True)
row.prop(gp_settings, "use_stroke_random_val", text="", icon='GP_SELECT_STROKES')
row.prop(gp_settings, "use_random_press_val", text="", icon='STYLUS_PRESSURE')
if gp_settings.use_random_press_val and self.is_popover is False:
col1.template_curve_mapping(gp_settings, "curve_random_value", brush=True,
use_negative_slope=True)
col1.template_curve_mapping(gp_settings, "curve_random_value", brush=True, use_negative_slope=True)
col.separator()
@ -1935,8 +1920,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel):
row.prop(gp_settings, "pen_jitter", slider=True)
row.prop(gp_settings, "use_jitter_pressure", text="", icon='STYLUS_PRESSURE')
if gp_settings.use_jitter_pressure and self.is_popover is False:
col.template_curve_mapping(gp_settings, "curve_jitter", brush=True,
use_negative_slope=True)
col.template_curve_mapping(gp_settings, "curve_jitter", brush=True, use_negative_slope=True)
class VIEW3D_PT_tools_grease_pencil_brush_paint_falloff(GreasePencilBrushFalloff, Panel, View3DPaintPanel):

View File

@ -29,6 +29,7 @@
#include "DNA_vec_types.h"
#include "BLI_listbase.h"
#include "BLI_math_bits.h"
#include "BLI_math_color_blend.h"
#include "BLI_math_matrix.h"
#include "BLI_path_util.h"
@ -344,6 +345,12 @@ void blf_batch_draw()
GPU_batch_program_set_builtin(g_batch.batch, GPU_SHADER_TEXT);
GPU_batch_texture_bind(g_batch.batch, "glyph", texture);
/* Setup texture width mask and shift, so that shader can avoid costly divisions. */
int tex_width = GPU_texture_width(texture);
BLI_assert_msg(is_power_of_2_i(tex_width), "Font texture width must be power of two");
int width_shift = 31 - bitscan_reverse_i(tex_width);
GPU_batch_uniform_1i(g_batch.batch, "glyph_tex_width_mask", tex_width - 1);
GPU_batch_uniform_1i(g_batch.batch, "glyph_tex_width_shift", width_shift);
GPU_batch_draw(g_batch.batch);
GPU_blend(GPU_BLEND_NONE);

View File

@ -29,7 +29,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 9
#define BLENDER_FILE_SUBVERSION 11
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and cancel loading the file, showing a warning to

View File

@ -110,7 +110,7 @@ enum eCbEvent {
BKE_CB_EVT_EXTENSION_REPOS_UPDATE_POST,
BKE_CB_EVT_EXTENSION_REPOS_SYNC,
BKE_CB_EVT_EXTENSION_REPOS_UPGRADE,
BKE_CB_EVT_EXTENSION_DROP_URL,
BKE_CB_EVT_EXTENSION_REPOS_FILES_CLEAR,
BKE_CB_EVT_TOT,
};

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