Anim: thread remake_graph_transdata #119497
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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``).
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"); });
|
||||
})();
|
||||
|
|
|
@ -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 -%}
|
|
@ -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 %}
|
|
@ -0,0 +1,6 @@
|
|||
{%- extends "!page.html" -%}
|
||||
|
||||
{%- block footer -%}
|
||||
{{ super() }}
|
||||
{%- include "components/footer_contribute.html" -%}
|
||||
{%- endblock footer -%}
|
|
@ -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>
|
|
@ -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,4 +1,3 @@
|
|||
When updating a library remember to:
|
||||
|
||||
* Update the README.blender with the corresponding version.
|
||||
* Update the THIRD-PARTY-LICENSES.txt document
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) << ".";
|
||||
}
|
||||
|
||||
|
|
|
@ -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*/)
|
||||
|
|
|
@ -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) << ".";
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -113,15 +113,18 @@ BVHMetal::BVHMetal(const BVHParams ¶ms_,
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) << ".";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
Subproject commit dc33a8704935c49dd7a8cf49197fdf42ff52622d
|
|
@ -1 +1 @@
|
|||
Subproject commit c8dba5b39bfd6c25c789660b022034ff69062e7c
|
||||
Subproject commit a5521c85e03bfd1556ff1e63bf7163235c401497
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -10,6 +10,7 @@ __all__ = (
|
|||
"app",
|
||||
"context",
|
||||
"data",
|
||||
"msgbus",
|
||||
"ops",
|
||||
"path",
|
||||
"props",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"])
|
||||
|
|
|
@ -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'}
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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'}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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'}:
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue