Merge branch 'master' into sculpt-dev

This commit is contained in:
Joseph Eagar 2022-02-14 09:41:42 -08:00
commit 1591c9a978
649 changed files with 14245 additions and 11158 deletions

View File

@ -157,8 +157,9 @@ option(WITH_BLENDER "Build blender (disable to build only the blender player)" O
mark_as_advanced(WITH_BLENDER)
if(APPLE)
# Currently this causes a build error linking, disable.
set(WITH_BLENDER_THUMBNAILER OFF)
# In future, can be used with `quicklookthumbnailing/qlthumbnailreply` to create file
# thumbnails for say Finder. Turn it off for now.
option(WITH_BLENDER_THUMBNAILER "Build \"blender-thumbnailer\" thumbnail extraction utility" OFF)
elseif(WIN32)
option(WITH_BLENDER_THUMBNAILER "Build \"BlendThumb.dll\" helper for Windows explorer integration" ON)
else()

View File

@ -19,13 +19,10 @@
set(FREETYPE_EXTRA_ARGS
-DCMAKE_RELEASE_POSTFIX:STRING=2ST
-DCMAKE_DEBUG_POSTFIX:STRING=2ST_d
-DWITH_BZip2=OFF
-DWITH_HarfBuzz=OFF
-DFT_WITH_HARFBUZZ=OFF
-DFT_WITH_BZIP2=OFF
-DFT_WITH_BROTLI=ON
-DCMAKE_DISABLE_FIND_PACKAGE_HarfBuzz=TRUE
-DCMAKE_DISABLE_FIND_PACKAGE_BZip2=TRUE
-DFT_DISABLE_BZIP2=ON
-DFT_DISABLE_HARFBUZZ=ON
-DFT_DISABLE_PNG=ON
-DFT_REQUIRE_BROTLI=ON
-DPC_BROTLIDEC_INCLUDEDIR=${LIBDIR}/brotli/include
-DPC_BROTLIDEC_LIBDIR=${LIBDIR}/brotli/lib
)

View File

@ -83,9 +83,9 @@ else()
set(OPENEXR_VERSION_POSTFIX)
endif()
set(FREETYPE_VERSION 2.11.0)
set(FREETYPE_VERSION 2.11.1)
set(FREETYPE_URI http://prdownloads.sourceforge.net/freetype/freetype-${FREETYPE_VERSION}.tar.gz)
set(FREETYPE_HASH cf09172322f6b50cf8f568bf8fe14bde)
set(FREETYPE_HASH bd4e3b007474319909a6b79d50908e85)
set(FREETYPE_HASH_TYPE MD5)
set(FREETYPE_FILE freetype-${FREETYPE_VERSION}.tar.gz)

View File

@ -4036,14 +4036,14 @@ install_DEB() {
INFO "Forced Python building, as requested..."
_do_compile_python=true
else
check_package_version_ge_lt_DEB python3-dev $PYTHON_VERSION_MIN $PYTHON_VERSION_MEX
check_package_version_ge_lt_DEB python${PYTHON_VERSION_SHORT}-dev $PYTHON_VERSION_MIN $PYTHON_VERSION_MEX
if [ $? -eq 0 ]; then
PYTHON_VERSION_INSTALLED=$(echo `get_package_version_DEB python3-dev` | sed -r 's/^([0-9]+\.[0-9]+).*/\1/')
install_packages_DEB python3-dev
install_packages_DEB python${PYTHON_VERSION_SHORT}-dev
clean_Python
PRINT ""
PYTHON_VERSION_INSTALLED=$(echo `get_package_version_DEB python${PYTHON_VERSION_SHORT}-dev` | sed -r 's/^([0-9]+\.[0-9]+).*/\1/')
for module in "${PYTHON_MODULES_PACKAGES[@]}"
do
module=($module)
@ -4681,11 +4681,11 @@ install_RPM() {
else
check_package_version_ge_lt_RPM python3-devel $PYTHON_VERSION_MIN $PYTHON_VERSION_MEX
if [ $? -eq 0 ]; then
PYTHON_VERSION_INSTALLED=$(echo `get_package_version_RPM python3-devel` | sed -r 's/^([0-9]+\.[0-9]+).*/\1/')
install_packages_RPM python3-devel
clean_Python
PYTHON_VERSION_INSTALLED=$(echo `get_package_version_RPM python3-devel` | sed -r 's/^([0-9]+\.[0-9]+).*/\1/')
for module in "${PYTHON_MODULES_PACKAGES[@]}"
do
module=($module)
@ -5224,12 +5224,12 @@ install_ARCH() {
else
check_package_version_ge_lt_ARCH python $PYTHON_VERSION_MIN $PYTHON_VERSION_MEX
if [ $? -eq 0 ]; then
PYTHON_VERSION_INSTALLED=$(echo `get_package_version_ARCH python` | sed -r 's/^([0-9]+\.[0-9]+).*/\1/')
install_packages_ARCH python
clean_Python
PRINT ""
PYTHON_VERSION_INSTALLED=$(echo `get_package_version_ARCH python` | sed -r 's/^([0-9]+\.[0-9]+).*/\1/')
for module in "${PYTHON_MODULES_PACKAGES[@]}"
do
module=($module)

View File

@ -34,7 +34,7 @@ IF(NOT PYTHON_ROOT_DIR AND NOT $ENV{PYTHON_ROOT_DIR} STREQUAL "")
SET(PYTHON_ROOT_DIR $ENV{PYTHON_ROOT_DIR})
ENDIF()
SET(PYTHON_VERSION 3.9 CACHE STRING "Python Version (major and minor only)")
SET(PYTHON_VERSION 3.10 CACHE STRING "Python Version (major and minor only)")
MARK_AS_ADVANCED(PYTHON_VERSION)

View File

@ -22,7 +22,7 @@ Data Access
===========
The most common case for using the reference API is to find out how to access data in the blend-file.
Before going any further its best to be aware of ID data-blocks in Blender since you will often find properties
Before going any further it's best to be aware of ID data-blocks in Blender since you will often find properties
relative to them.
@ -55,9 +55,9 @@ Start by collecting the information where the data is located.
First find this setting in the interface ``Properties editor -> Object -> Transform -> Location``.
From the button context menu select *Online Python Reference*, this will link you to:
:class:`bpy.types.Object.location`.
Being an API reference, this link often gives little more information then the tooltip, though some of the pages
Being an API reference, this link often gives little more information than the tooltip, though some of the pages
include examples (normally at the top of the page).
But you now know that you have to use ``.location`` and that its an array of three floats.
But you now know that you have to use ``.location`` and that it's an array of three floats.
So the next step is to find out where to access objects, go down to the bottom of the page to the references section,
for objects there are many references, but one of the most common places to access objects is via the context.
@ -154,7 +154,7 @@ The tooltip includes :class:`bpy.types.SubsurfModifier.levels` but you want the
Note that the text copied won't include the ``bpy.data.collection["name"].`` component since its assumed that
you won't be doing collection look-ups on every access and typically you'll want to use the context rather
then access each :class:`bpy.types.ID` instance by name.
than access each :class:`bpy.types.ID` instance by name.
Type in the ID path into a Python console :mod:`bpy.context.active_object`.
Include the trailing dot and don't execute the code, yet.
@ -252,6 +252,6 @@ Each entry can be selected, then copied :kbd:`Ctrl-C`, usually to paste in the t
.. note::
Not all operators get registered for display,
zooming the view for example isn't so useful to repeat so its excluded from the output.
zooming the view for example isn't so useful to repeat so it's excluded from the output.
To display *every* operator that runs see :ref:`Show All Operators <info_show_all_operators>`.

View File

@ -229,7 +229,7 @@ removing the last items first, which is faster (as explained above):
This example shows a fast way of removing items,
for use in cases where you can alter the list order without breaking the scripts functionality.
for use in cases where you can alter the list order without breaking the script's functionality.
This works by swapping two list items, so the item you remove is always last:
.. code-block:: python
@ -278,7 +278,7 @@ Here are three ways of joining multiple strings into one string for writing.
This also applies to any area of your code that involves a lot of string joining:
String concatenation
This is the slowest option, do **not** use if you can avoid it, especially when writing data in a loop.
This is the slowest option, do **not** use this if you can avoid it, especially when writing data in a loop.
>>> file.write(str1 + " " + str2 + " " + str3 + "\n")
@ -288,7 +288,7 @@ String formatting
>>> file.write("%s %s %s\n" % (str1, str2, str3))
String joining
Use to join a list of strings (the list may be temporary). In the following example, the strings are joined with
Use this to join a list of strings (the list may be temporary). In the following example, the strings are joined with
a space " " in between, other examples are "" or ", ".
>>> file.write(" ".join((str1, str2, str3, "\n")))

View File

@ -12,7 +12,7 @@ that can be troublesome and avoid practices that are known to cause instability.
Using Operators
===============
Blender's operators are tools for users to access, that can access with Python too which is very useful.
Blender's operators are tools for users to access, that can be accessed with Python too which is very useful.
Still operators have limitations that can make them cumbersome to script.
The main limits are:
@ -20,13 +20,13 @@ The main limits are:
- Can't pass data such as objects, meshes or materials to operate on (operators use the context instead).
- The return value from calling an operator is the success (if it finished or was canceled),
in some cases it would be more logical from an API perspective to return the result of the operation.
- Operators poll function can fail where an API function would raise an exception giving details on exactly why.
- Operators' poll function can fail where an API function would raise an exception giving details on exactly why.
Why does an operator's poll fail?
---------------------------------
When calling an operator gives an error like this:
When calling an operator it gives an error like this:
>>> bpy.ops.action.clean(threshold=0.001)
RuntimeError: Operator bpy.ops.action.clean.poll() failed, context is incorrect
@ -49,9 +49,9 @@ you should be able to find the poll function with no knowledge of C.
.. note::
Blender does have the functionality for poll functions to describe why they fail,
but its currently not used much, if you're interested to help improve the API
but it's currently not used much, if you're interested to help improve the API
feel free to add calls to :class:`bpy.types.Operator.poll_message_set` (``CTX_wm_operator_poll_msg_set`` in C)
where its not obvious why poll fails, e.g:
where it's not obvious why poll fails, e.g:
>>> bpy.ops.gpencil.draw()
RuntimeError: Operator bpy.ops.gpencil.draw.poll() Failed to find Grease Pencil data to draw into
@ -107,7 +107,7 @@ In this case you need to call :class:`bpy.types.ViewLayer.update` after modifyin
Now all dependent data (child objects, modifiers, drivers, etc.)
has been recalculated and is available to the script within active view layer.
have been recalculated and are available to the script within the active view layer.
Can I redraw during script execution?
@ -116,13 +116,13 @@ Can I redraw during script execution?
The official answer to this is no, or... *"You don't want to do that"*.
To give some background on the topic:
While a script executes Blender waits for it to finish and is effectively locked until its done,
While a script executes, Blender waits for it to finish and is effectively locked until it's done;
while in this state Blender won't redraw or respond to user input.
Normally this is not such a problem because scripts distributed with Blender
tend not to run for an extended period of time,
nevertheless scripts *can* take a long time to complete and it would be nice to see progress in the viewport.
When tools lock Blender in a loop redraw are highly discouraged
Tools that lock Blender in a loop redraw are highly discouraged
since they conflict with Blender's ability to run multiple operators
at once and update different parts of the interface as the tool runs.
@ -130,7 +130,7 @@ So the solution here is to write a **modal** operator, which is an operator that
See the modal operator template in the text editor.
Modal operators execute on user input or setup their own timers to run frequently,
they can handle the events or pass through to be handled by the keymap or other modal operators.
Examples of a modal operators are Transform, Painting, Fly Navigation and File Select.
Examples of modal operators are Transform, Painting, Fly Navigation and File Select.
Writing modal operators takes more effort than a simple ``for`` loop
that contains draw calls but is more flexible and integrates better with Blender's design.
@ -240,7 +240,7 @@ Editing
Editing is where the three data types vary most.
- Polygons are very limited for editing,
changing materials and options like smooth works but for anything else
changing materials and options like smooth works, but for anything else
they are too inflexible and are only intended for storage.
- Tessfaces should not be used for editing geometry because doing so will cause existing n-gons to be tessellated.
- BMesh-faces are by far the best way to manipulate geometry.
@ -256,7 +256,7 @@ the choice mostly depends on whether the target format supports n-gons or not.
- Tessfaces work well for exporting to formats which don't support n-gons,
in fact this is the only place where their use is encouraged.
- BMesh-Faces can work for exporting too but may not be necessary if polygons can be used
since using BMesh gives some overhead because its not the native storage format in Object-Mode.
since using BMesh gives some overhead because it's not the native storage format in Object-Mode.
Edit Bones, Pose Bones, Bone... Bones
@ -348,7 +348,7 @@ Armature Mode Switching
While writing scripts that deal with armatures you may find you have to switch between modes,
when doing so take care when switching out of Edit-Mode not to keep references
to the edit bones or their head/tail vectors.
Further access to these will crash Blender so its important the script
Further access to these will crash Blender so it's important that the script
clearly separates sections of the code which operate in different modes.
This is mainly an issue with Edit-Mode since pose data can be manipulated without having to be in Pose-Mode,
@ -386,11 +386,11 @@ Or with name assignment:
Data names may not match the assigned values if they exceed the maximum length, are already used or an empty string.
Its better practice not to reference objects by names at all,
It's better practice not to reference objects by names at all,
once created you can store the data in a list, dictionary, on a class, etc;
there is rarely a reason to have to keep searching for the same data by name.
If you do need to use name references, its best to use a dictionary to maintain
If you do need to use name references, it's best to use a dictionary to maintain
a mapping between the names of the imported assets and the newly created data,
this way you don't run this risk of referencing existing data from the blend-file, or worse modifying it.
@ -414,11 +414,11 @@ Library Collisions
Blender keeps data names unique (:class:`bpy.types.ID.name`) so you can't name two objects,
meshes, scenes, etc., the same by accident.
However, when linking in library data from another blend-file naming collisions can occur,
so its best to avoid referencing data by name at all.
so it's best to avoid referencing data by name at all.
This can be tricky at times and not even Blender handles this correctly in some case
This can be tricky at times and not even Blender handles this correctly in some cases
(when selecting the modifier object for e.g. you can't select between multiple objects with the same name),
but its still good to try avoiding these problems in this area.
but it's still good to try avoiding these problems in this area.
If you need to select between local and library data, there is a feature in ``bpy.data`` members to allow for this.
.. code-block:: python
@ -467,11 +467,11 @@ writing a script in ``latin1`` or ``iso-8859-15``.
See `PEP 263 <https://www.python.org/dev/peps/pep-0263/>`__.
However, this complicates matters for Blender's Python API because ``.blend`` files don't have an explicit encoding.
To avoid the problem for Python integration and script authors we have decided all strings in blend-files
To avoid the problem for Python integration and script authors we have decided that all strings in blend-files
**must** be ``UTF-8``, ``ASCII`` compatible.
This means assigning strings with different encodings to an object names for instance will raise an error.
This means assigning strings with different encodings to an object name, for instance, will raise an error.
Paths are an exception to this rule since the existence of non-UTF-8 paths on user's file system cannot be ignored.
Paths are an exception to this rule since the existence of non-UTF-8 paths on the user's file system cannot be ignored.
This means seemingly harmless expressions can raise errors, e.g:
>>> print(bpy.data.filepath)
@ -505,7 +505,7 @@ to keep it short about encoding problems -- here are some suggestions:
.. note::
Sometimes it's preferable to avoid string encoding issues by using bytes instead of Python strings,
when reading some input its less trouble to read it as binary data
when reading some input it's less trouble to read it as binary data
though you will still need to decide how to treat any strings you want to use with Blender,
some importers do this.
@ -679,7 +679,7 @@ Undo/Redo
---------
For safety, you should assume that undo and redo always invalidates all :class:`bpy.types.ID`
instances (Object, Scene, Mesh, Light, etc.), as weel obviously as all of their sub-data.
instances (Object, Scene, Mesh, Light, etc.), as well obviously as all of their sub-data.
This example shows how you can tell undo changes the memory locations:
@ -716,7 +716,7 @@ Tools in Blender are not allowed to modify library data.
But Python does not enforce this restriction.
This can be useful in some cases, using a script to adjust material values for example.
But its also possible to use a script to make library data point to newly created local data,
But it's also possible to use a script to make library data point to newly created local data,
which is not supported since a call to undo will remove the local data
but leave the library referencing it and likely crash.

View File

@ -81,7 +81,7 @@ but reference an external file rather than including it directly.
Executing External Scripts
--------------------------
This is the equivalent to running the script directly, referencing a scripts path from a two line code block.
This is the equivalent to running the script directly, referencing a script's path from a two line code block.
.. code-block:: python
@ -124,7 +124,7 @@ small script which is often useful for testing different settings quickly.
The other issue with this is the script has to be in Python's module search path.
While this is not best practice -- for testing purposes you can extend the search path,
this following example adds the current blend-files directory to the search path
this following example adds the current blend-file's directory to the search path
and then loads the script as a module.
.. code-block:: python
@ -302,7 +302,7 @@ Python Safety (Build Option)
----------------------------
Since it's possible to access data which has been removed (see :doc:`Gotchas <info_gotcha>`),
can make it hard to track down the cause of crashes.
it can be hard to track down the cause of crashes.
To raise Python exceptions on accessing freed data (rather than crashing),
enable the CMake build option ``WITH_PYTHON_SAFETY``.
This enables data tracking which makes data access about two times slower

View File

@ -417,7 +417,8 @@ MODULE_GROUPING = {
BLENDER_REVISION = str(bpy.app.build_hash, 'utf_8')
# '2.83.0 Beta' or '2.83.0' or '2.83.1'
BLENDER_VERSION_DOTS = bpy.app.version_string
BLENDER_VERSION_STRING = bpy.app.version_string
BLENDER_VERSION_DOTS = "%d.%d" % (bpy.app.version[0], bpy.app.version[1])
if BLENDER_REVISION != "Unknown":
# SHA1 Git hash
@ -1724,11 +1725,11 @@ def write_sphinx_conf_py(basepath):
fw("import sys, os\n\n")
fw("extensions = ['sphinx.ext.intersphinx']\n\n")
fw("intersphinx_mapping = {'blender_manual': ('https://docs.blender.org/manual/en/dev/', None)}\n\n")
fw("project = 'Blender %s Python API'\n" % BLENDER_VERSION_DOTS)
fw("project = 'Blender %s Python API'\n" % BLENDER_VERSION_STRING)
fw("master_doc = 'index'\n")
fw("copyright = u'Blender Foundation'\n")
fw("version = '%s'\n" % BLENDER_VERSION_HASH)
fw("release = '%s'\n" % BLENDER_VERSION_HASH)
fw("version = '%s'\n" % BLENDER_VERSION_DOTS)
fw("release = '%s'\n" % BLENDER_VERSION_DOTS)
# Quiet file not in table-of-contents warnings.
fw("exclude_patterns = [\n")
@ -1749,6 +1750,7 @@ except ModuleNotFoundError:
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")
@ -1765,10 +1767,15 @@ except ModuleNotFoundError:
fw("html_show_search_summary = True\n")
fw("html_split_index = True\n")
fw("html_static_path = ['static']\n")
fw("templates_path = ['templates']\n")
fw("html_context = {'commit': '%s'}\n" % BLENDER_VERSION_HASH)
fw("html_extra_path = ['static/favicon.ico', 'static/blender_logo.svg']\n")
fw("html_favicon = 'static/favicon.ico'\n")
fw("html_logo = 'static/blender_logo.svg'\n")
fw("html_last_updated_fmt = '%m/%d/%Y'\n\n")
fw("if html_theme == 'sphinx_rtd_theme':\n")
fw(" html_css_files = ['css/version_switch.css']\n")
fw(" html_js_files = ['js/version_switch.js']\n")
# needed for latex, pdf gen
fw("latex_elements = {\n")
@ -2125,6 +2132,9 @@ def copy_theme_assets(basepath):
shutil.copytree(os.path.join(SCRIPT_DIR, "static"),
os.path.join(basepath, "static"),
copy_function=shutil.copy)
shutil.copytree(os.path.join(SCRIPT_DIR, "templates"),
os.path.join(basepath, "templates"),
copy_function=shutil.copy)
def rna2sphinx(basepath):

View File

@ -0,0 +1,127 @@
/* Override RTD theme */
.rst-versions {
border-top: 0px;
overflow: visible;
}
.version-btn.vdeact {
cursor: default;
color: dimgray;
}
.version-btn.vdeact::after {
content: "";
}
#versionwrap {
display: flex;
padding-top: 2px;
font-size: 90%;
justify-content: center;
flex-wrap: wrap;
}
.version-btn {
display: inline-block;
background-color: #272525;
width: 140px;
text-align: center;
padding: 3px 10px;
margin: 0px 5px 4px;
vertical-align: middle;
color: #27AE60;
border: solid 1px #444444;
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 {
border-color: #525252;
}
.version-btn-open {
color: gray;
border: solid 1px gray;
}
.version-btn.wait {
cursor: wait;
}
.version-btn.disabled {
cursor: not-allowed;
color: dimgray;
}
.version-dialog {
display: none;
position: absolute;
bottom: 28px;
width: 140px;
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-y: auto;
cursor: default;
}
.version-title {
padding: 5px;
color: black;
text-align: center;
font-size: 102%;
background-color: #27ae60;
border-bottom: solid 1.5px #444;
}
.version-list {
margin-bottom: 4px;
text-align: center;
background-color: #000C;
border: solid 1px gray;
border-radius: 0px 0px 3px 3px;
}
.version-list a, .version-list span, .version-list li {
position: relative;
display: block;
font-size: 98%;
line-height: 1.15;
width: 100%;
margin: 0;
padding: 4px 0px;
color: #404040;
}
.version-list li {
background-color: #ede9e9;
color: #404040;
padding: 1px;
}
.version-list li:hover, .version-list li a:focus {
background-color: #b9cfda;
}
.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;
}

View File

@ -0,0 +1,323 @@
(function() { // switch: v1.2
"use strict";
var versionsFileUrl = "https://docs.blender.org/PROD/versions.json"
var all_versions;
var Popover = function() {
function Popover(id)
{
this.isOpen = false;
this.type = (id === "version-popover");
this.$btn = $('#' + id);
this.$dialog = this.$btn.next();
this.$list = this.$dialog.children("ul");
this.sel = null;
this.beforeInit();
}
Popover.prototype = {
beforeInit : function() {
var that = this;
this.$btn.on("click", function(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");
if (all_versions === undefined) {
this.$btn.addClass("wait");
this.loadVL(this);
}
else {
this.afterLoad();
}
},
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;
const m = release.match(/\d\.\d+/g);
if (m) {
release = m[0];
}
this.warnOld(release, all_versions);
var version = this.getNamed(release);
var list = this.buildList(version);
this.$list.children(":first-child").remove();
this.$list.append(list);
var that = this;
this.$list.on("keydown", function(e) {
that.keyMove(e);
});
this.$btn.removeClass("wait");
this.btnOpenHandler();
this.$btn.on("mousedown", function(e) {
that.btnOpenHandler();
e.preventDefault()
});
this.$btn.on("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 === "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");
}
};
return Popover
}();
$(document).ready(function() {
var lng_popover = new Popover("version-popover");
});
})();

View File

@ -0,0 +1,17 @@
<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>

View File

@ -74,7 +74,7 @@ enum_panorama_types = (
"Similar to most fisheye modern lens, takes sensor dimensions into consideration"),
('MIRRORBALL', "Mirror Ball", "Uses the mirror ball mapping"),
('FISHEYE_LENS_POLYNOMIAL', "Fisheye Lens Polynomial",
"Defines the lens projection as polynomial to allow real world camera lenses to be mimicked."),
"Defines the lens projection as polynomial to allow real world camera lenses to be mimicked"),
)
enum_curve_shape = (
@ -901,27 +901,27 @@ class CyclesCameraSettings(bpy.types.PropertyGroup):
fisheye_polynomial_k0: FloatProperty(
name="Fisheye Polynomial K0",
description="Coefficient K0 of the lens polinomial",
description="Coefficient K0 of the lens polynomial",
default=camera.default_fisheye_polynomial[0], precision=6, step=0.1, subtype='ANGLE',
)
fisheye_polynomial_k1: FloatProperty(
name="Fisheye Polynomial K1",
description="Coefficient K1 of the lens polinomial",
description="Coefficient K1 of the lens polynomial",
default=camera.default_fisheye_polynomial[1], precision=6, step=0.1, subtype='ANGLE',
)
fisheye_polynomial_k2: FloatProperty(
name="Fisheye Polynomial K2",
description="Coefficient K2 of the lens polinomial",
description="Coefficient K2 of the lens polynomial",
default=camera.default_fisheye_polynomial[2], precision=6, step=0.1, subtype='ANGLE',
)
fisheye_polynomial_k3: FloatProperty(
name="Fisheye Polynomial K3",
description="Coefficient K3 of the lens polinomial",
description="Coefficient K3 of the lens polynomial",
default=camera.default_fisheye_polynomial[3], precision=6, step=0.1, subtype='ANGLE',
)
fisheye_polynomial_k4: FloatProperty(
name="Fisheye Polynomial K4",
description="Coefficient K4 of the lens polinomial",
description="Coefficient K4 of the lens polynomial",
default=camera.default_fisheye_polynomial[4], precision=6, step=0.1, subtype='ANGLE',
)

View File

@ -669,7 +669,7 @@ class CYCLES_RENDER_PT_performance_acceleration_structure(CyclesButtonsPanel, Pa
@classmethod
def poll(cls, context):
return not use_optix(context) or has_multi_device(context)
return not use_optix(context) or use_multi_device(context)
def draw(self, context):
import _cycles

View File

@ -14,6 +14,8 @@
* limitations under the License.
*/
#include <optional>
#include "blender/sync.h"
#include "blender/util.h"
@ -624,15 +626,36 @@ void BlenderSync::sync_particle_hair(
}
}
#ifdef WITH_HAIR_NODES
static float4 hair_point_as_float4(BL::HairPoint b_point)
#ifdef WITH_NEW_CURVES_TYPE
static std::optional<BL::FloatAttribute> find_curves_radius_attribute(BL::Curves b_curves)
{
float4 mP = float3_to_float4(get_float3(b_point.co()));
mP.w = b_point.radius();
for (BL::Attribute &b_attribute : b_curves.attributes) {
if (b_attribute.name() != "radius") {
continue;
}
if (b_attribute.domain() != BL::Attribute::domain_POINT) {
continue;
}
if (b_attribute.data_type() != BL::Attribute::data_type_FLOAT) {
continue;
}
return BL::FloatAttribute{b_attribute};
}
return std::nullopt;
}
static float4 hair_point_as_float4(BL::Curves b_curves,
std::optional<BL::FloatAttribute> b_attr_radius,
const int index)
{
float4 mP = float3_to_float4(get_float3(b_curves.position_data[index].vector()));
mP.w = b_attr_radius ? b_attr_radius->data[index].value() : 0.0f;
return mP;
}
static float4 interpolate_hair_points(BL::Hair b_hair,
static float4 interpolate_hair_points(BL::Curves b_curves,
std::optional<BL::FloatAttribute> b_attr_radius,
const int first_point_index,
const int num_points,
const float step)
@ -641,12 +664,12 @@ static float4 interpolate_hair_points(BL::Hair b_hair,
const int point_a = clamp((int)curve_t, 0, num_points - 1);
const int point_b = min(point_a + 1, num_points - 1);
const float t = curve_t - (float)point_a;
return lerp(hair_point_as_float4(b_hair.points[first_point_index + point_a]),
hair_point_as_float4(b_hair.points[first_point_index + point_b]),
return lerp(hair_point_as_float4(b_curves, b_attr_radius, first_point_index + point_a),
hair_point_as_float4(b_curves, b_attr_radius, first_point_index + point_b),
t);
}
static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
static void export_hair_curves(Scene *scene, Hair *hair, BL::Curves b_curves)
{
/* TODO: optimize so we can straight memcpy arrays from Blender? */
@ -666,17 +689,19 @@ static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
}
/* Reserve memory. */
const int num_keys = b_hair.points.length();
const int num_curves = b_hair.curves.length();
const int num_keys = b_curves.points.length();
const int num_curves = b_curves.curves.length();
hair->reserve_curves(num_curves, num_keys);
std::optional<BL::FloatAttribute> b_attr_radius = find_curves_radius_attribute(b_curves);
/* Export curves and points. */
vector<float> points_length;
for (BL::HairCurve &b_curve : b_hair.curves) {
const int first_point_index = b_curve.first_point_index();
const int num_points = b_curve.num_points();
for (int i = 0; i < num_curves; i++) {
const int first_point_index = b_curves.curve_offset_data[i].value();
const int num_points = b_curves.curve_offset_data[i + 1].value() - first_point_index;
float3 prev_co = zero_float3();
float length = 0.0f;
@ -687,10 +712,9 @@ static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
/* Position and radius. */
for (int i = 0; i < num_points; i++) {
BL::HairPoint b_point = b_hair.points[first_point_index + i];
const float3 co = get_float3(b_point.co());
const float radius = b_point.radius();
const float3 co = get_float3(b_curves.position_data[first_point_index + i].vector());
const float radius = b_attr_radius ? b_attr_radius->data[first_point_index + i].value() :
0.0f;
hair->add_curve_key(co, radius);
if (attr_intercept) {
@ -715,7 +739,7 @@ static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
/* Random number per curve. */
if (attr_random != NULL) {
attr_random->add(hash_uint2_to_float(b_curve.index(), 0));
attr_random->add(hash_uint2_to_float(i, 0));
}
/* Curve. */
@ -724,7 +748,7 @@ static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
}
}
static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_step)
static void export_hair_curves_motion(Hair *hair, BL::Curves b_curves, int motion_step)
{
/* Find or add attribute. */
Attribute *attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
@ -737,14 +761,17 @@ static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_st
/* Export motion keys. */
const int num_keys = hair->get_curve_keys().size();
const int num_curves = b_curves.curves.length();
float4 *mP = attr_mP->data_float4() + motion_step * num_keys;
bool have_motion = false;
int num_motion_keys = 0;
int curve_index = 0;
for (BL::HairCurve &b_curve : b_hair.curves) {
const int first_point_index = b_curve.first_point_index();
const int num_points = b_curve.num_points();
std::optional<BL::FloatAttribute> b_attr_radius = find_curves_radius_attribute(b_curves);
for (int i = 0; i < num_curves; i++) {
const int first_point_index = b_curves.curve_offset_data[i].value();
const int num_points = b_curves.curve_offset_data[i + 1].value() - first_point_index;
Hair::Curve curve = hair->get_curve(curve_index);
curve_index++;
@ -755,7 +782,7 @@ static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_st
int point_index = first_point_index + i;
if (point_index < num_keys) {
mP[num_motion_keys] = hair_point_as_float4(b_hair.points[point_index]);
mP[num_motion_keys] = hair_point_as_float4(b_curves, b_attr_radius, point_index);
num_motion_keys++;
if (!have_motion) {
@ -774,7 +801,8 @@ static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_st
const float step_size = curve.num_keys > 1 ? 1.0f / (curve.num_keys - 1) : 0.0f;
for (int i = 0; i < curve.num_keys; i++) {
const float step = i * step_size;
mP[num_motion_keys] = interpolate_hair_points(b_hair, first_point_index, num_points, step);
mP[num_motion_keys] = interpolate_hair_points(
b_curves, b_attr_radius, first_point_index, num_points, step);
num_motion_keys++;
}
have_motion = true;
@ -791,12 +819,12 @@ static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_st
void BlenderSync::sync_hair(Hair *hair, BObjectInfo &b_ob_info, bool motion, int motion_step)
{
/* Convert Blender hair to Cycles curves. */
BL::Hair b_hair(b_ob_info.object_data);
BL::Curves b_curves(b_ob_info.object_data);
if (motion) {
export_hair_curves_motion(hair, b_hair, motion_step);
export_hair_curves_motion(hair, b_curves, motion_step);
}
else {
export_hair_curves(scene, hair, b_hair);
export_hair_curves(scene, hair, b_curves);
}
}
#else
@ -819,8 +847,8 @@ void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, H
new_hair.set_used_shaders(used_shaders);
if (view_layer.use_hair) {
#ifdef WITH_HAIR_NODES
if (b_ob_info.object_data.is_a(&RNA_Hair)) {
#ifdef WITH_NEW_CURVES_TYPE
if (b_ob_info.object_data.is_a(&RNA_Curves)) {
/* Hair object. */
sync_hair(&new_hair, b_ob_info, false);
}
@ -873,8 +901,8 @@ void BlenderSync::sync_hair_motion(BL::Depsgraph b_depsgraph,
/* Export deformed coordinates. */
if (ccl::BKE_object_is_deform_modified(b_ob_info, b_scene, preview)) {
#ifdef WITH_HAIR_NODES
if (b_ob_info.object_data.is_a(&RNA_Hair)) {
#ifdef WITH_NEW_CURVES_TYPE
if (b_ob_info.object_data.is_a(&RNA_Curves)) {
/* Hair object. */
sync_hair(hair, b_ob_info, true, motion_step);
return;

View File

@ -32,8 +32,8 @@ CCL_NAMESPACE_BEGIN
static Geometry::Type determine_geom_type(BObjectInfo &b_ob_info, bool use_particle_hair)
{
#ifdef WITH_HAIR_NODES
if (b_ob_info.object_data.is_a(&RNA_Hair) || use_particle_hair) {
#ifdef WITH_NEW_CURVES_TYPE
if (b_ob_info.object_data.is_a(&RNA_Curves) || use_particle_hair) {
#else
if (use_particle_hair) {
#endif
@ -231,8 +231,8 @@ void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph,
if (progress.get_cancel())
return;
#ifdef WITH_HAIR_NODES
if (b_ob_info.object_data.is_a(&RNA_Hair) || use_particle_hair) {
#ifdef WITH_NEW_CURVES_TYPE
if (b_ob_info.object_data.is_a(&RNA_Curves) || use_particle_hair) {
#else
if (use_particle_hair) {
#endif

View File

@ -72,7 +72,7 @@ bool BlenderSync::object_is_geometry(BObjectInfo &b_ob_info)
BL::Object::type_enum type = b_ob_info.iter_object.type();
if (type == BL::Object::type_VOLUME || type == BL::Object::type_HAIR ||
if (type == BL::Object::type_VOLUME || type == BL::Object::type_CURVES ||
type == BL::Object::type_POINTCLOUD) {
/* Will be exported attached to mesh. */
return true;
@ -97,7 +97,7 @@ bool BlenderSync::object_can_have_geometry(BL::Object &b_ob)
case BL::Object::type_SURFACE:
case BL::Object::type_META:
case BL::Object::type_FONT:
case BL::Object::type_HAIR:
case BL::Object::type_CURVES:
case BL::Object::type_POINTCLOUD:
case BL::Object::type_VOLUME:
return true;

View File

@ -142,6 +142,7 @@ class BVHParams {
top_level = false;
bvh_layout = BVH_LAYOUT_BVH2;
use_compact_structure = true;
use_unaligned_nodes = false;
num_motion_curve_steps = 0;

View File

@ -905,8 +905,8 @@ void HIPDevice::tex_alloc(device_texture &mem)
address_mode = hipAddressModeClamp;
break;
case EXTENSION_CLIP:
// TODO : (Arya) setting this to Mode Clamp instead of Mode Border because it's unsupported
// in hip
/* TODO(@arya): setting this to Mode Clamp instead of Mode Border
* because it's unsupported in HIP. */
address_mode = hipAddressModeClamp;
break;
default:

View File

@ -157,7 +157,7 @@ bool ShaderEval::eval_gpu(Device *device,
queue->init_execution();
/* Execute work on GPU in chunk, so we can cancel.
* TODO : query appropriate size from device.*/
* TODO: query appropriate size from device. */
const int32_t chunk_size = 65536;
device_ptr d_input = input.device_pointer;

View File

@ -193,17 +193,24 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
const uint16_t transparent_bounce = INTEGRATOR_STATE(state, path, transparent_bounce);
uint32_t shadow_flag = INTEGRATOR_STATE(state, path, flag);
shadow_flag |= (is_light) ? PATH_RAY_SHADOW_FOR_LIGHT : 0;
shadow_flag |= (shadow_flag & PATH_RAY_ANY_PASS) ? 0 : PATH_RAY_SURFACE_PASS;
const float3 throughput = INTEGRATOR_STATE(state, path, throughput) * bsdf_eval_sum(&bsdf_eval);
if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
const packed_float3 pass_diffuse_weight =
(bounce == 0) ? packed_float3(bsdf_eval_pass_diffuse_weight(&bsdf_eval)) :
INTEGRATOR_STATE(state, path, pass_diffuse_weight);
const packed_float3 pass_glossy_weight = (bounce == 0) ?
packed_float3(
bsdf_eval_pass_glossy_weight(&bsdf_eval)) :
INTEGRATOR_STATE(state, path, pass_glossy_weight);
packed_float3 pass_diffuse_weight;
packed_float3 pass_glossy_weight;
if (shadow_flag & PATH_RAY_ANY_PASS) {
/* Indirect bounce, use weights from earlier surface or volume bounce. */
pass_diffuse_weight = INTEGRATOR_STATE(state, path, pass_diffuse_weight);
pass_glossy_weight = INTEGRATOR_STATE(state, path, pass_glossy_weight);
}
else {
/* Direct light, use BSDFs at this bounce. */
shadow_flag |= PATH_RAY_SURFACE_PASS;
pass_diffuse_weight = packed_float3(bsdf_eval_pass_diffuse_weight(&bsdf_eval));
pass_glossy_weight = packed_float3(bsdf_eval_pass_glossy_weight(&bsdf_eval));
}
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, pass_diffuse_weight) = pass_diffuse_weight;
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, pass_glossy_weight) = pass_glossy_weight;
}

View File

@ -801,16 +801,26 @@ ccl_device_forceinline void integrate_volume_direct_light(
const uint16_t transparent_bounce = INTEGRATOR_STATE(state, path, transparent_bounce);
uint32_t shadow_flag = INTEGRATOR_STATE(state, path, flag);
shadow_flag |= (is_light) ? PATH_RAY_SHADOW_FOR_LIGHT : 0;
shadow_flag |= (shadow_flag & PATH_RAY_ANY_PASS) ? 0 : PATH_RAY_VOLUME_PASS;
const float3 throughput_phase = throughput * bsdf_eval_sum(&phase_eval);
if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
const packed_float3 pass_diffuse_weight = (bounce == 0) ?
packed_float3(one_float3()) :
INTEGRATOR_STATE(
state, path, pass_diffuse_weight);
packed_float3 pass_diffuse_weight;
packed_float3 pass_glossy_weight;
if (shadow_flag & PATH_RAY_ANY_PASS) {
/* Indirect bounce, use weights from earlier surface or volume bounce. */
pass_diffuse_weight = INTEGRATOR_STATE(state, path, pass_diffuse_weight);
pass_glossy_weight = INTEGRATOR_STATE(state, path, pass_glossy_weight);
}
else {
/* Direct light, no diffuse/glossy distinction needed for volumes. */
shadow_flag |= PATH_RAY_VOLUME_PASS;
pass_diffuse_weight = packed_float3(one_float3());
pass_glossy_weight = packed_float3(zero_float3());
}
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, pass_diffuse_weight) = pass_diffuse_weight;
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, pass_glossy_weight) = zero_float3();
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, pass_glossy_weight) = pass_glossy_weight;
}
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, render_pixel_index) = INTEGRATOR_STATE(

View File

@ -113,22 +113,30 @@ ccl_device_inline bool light_sample(KernelGlobals kg,
ls->P = make_float3(klight->co[0], klight->co[1], klight->co[2]);
if (type == LIGHT_SPOT) {
ls->Ng = make_float3(klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]);
float radius = klight->spot.radius;
const float3 center = make_float3(klight->co[0], klight->co[1], klight->co[2]);
const float radius = klight->spot.radius;
const float3 dir = make_float3(
klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]);
/* disk oriented normal */
const float3 lightN = normalize(P - center);
ls->P = center;
if (radius > 0.0f)
/* sphere light */
ls->P += disk_light_sample(ls->Ng, randu, randv) * radius;
/* disk light */
ls->P += disk_light_sample(lightN, randu, randv) * radius;
const float invarea = klight->spot.invarea;
ls->pdf = invarea;
ls->D = normalize_len(ls->P - P, &ls->t);
/* we set the light normal to the outgoing direction to support texturing */
ls->Ng = -ls->D;
float invarea = klight->spot.invarea;
ls->eval_fac = (0.25f * M_1_PI_F) * invarea;
ls->pdf = invarea;
/* spot light attenuation */
ls->eval_fac *= spot_light_attenuation(
ls->Ng, klight->spot.spot_angle, klight->spot.spot_smooth, -ls->D);
dir, klight->spot.spot_angle, klight->spot.spot_smooth, -ls->D);
if (!in_volume_segment && ls->eval_fac == 0.0f) {
return false;
}
@ -137,32 +145,33 @@ ccl_device_inline bool light_sample(KernelGlobals kg,
ls->u = uv.x;
ls->v = uv.y;
ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
ls->pdf *= lamp_light_pdf(kg, lightN, -ls->D, ls->t);
}
else if (type == LIGHT_POINT) {
float3 center = make_float3(klight->co[0], klight->co[1], klight->co[2]);
float radius = klight->spot.radius;
/* disk oriented normal */
const float3 lightN = normalize(P - center);
ls->P = center;
float pdf = 1.0;
if (radius > 0.0f) {
ls->Ng = normalize(P - center);
ls->P += disk_light_sample(ls->Ng, randu, randv) * radius;
pdf = klight->spot.invarea;
ls->D = normalize_len(ls->P - P, &ls->t);
}
else {
ls->Ng = normalize(P - center);
ls->P += disk_light_sample(lightN, randu, randv) * radius;
}
ls->pdf = klight->spot.invarea;
ls->D = normalize_len(ls->P - P, &ls->t);
ls->pdf = pdf;
/* we set the light normal to the outgoing direction to support texturing */
ls->Ng = -ls->D;
ls->eval_fac = M_1_PI_F * 0.25f * klight->spot.invarea;
if (!in_volume_segment && ls->eval_fac == 0.0f) {
return false;
}
float2 uv = map_to_sphere(ls->Ng);
ls->u = uv.x;
ls->v = uv.y;
ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
ls->pdf *= lamp_light_pdf(kg, lightN, -ls->D, ls->t);
}
else {
/* area light */
@ -263,14 +272,16 @@ ccl_device bool lights_intersect(KernelGlobals kg,
if (type == LIGHT_SPOT) {
/* Spot/Disk light. */
const float mis_ray_t = INTEGRATOR_STATE(state, path, mis_ray_t);
const float3 ray_P = ray->P - ray->D * mis_ray_t;
const float3 lightP = make_float3(klight->co[0], klight->co[1], klight->co[2]);
const float3 lightN = make_float3(
klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]);
const float radius = klight->spot.radius;
if (radius == 0.0f) {
continue;
}
/* disk oriented normal */
const float3 lightN = normalize(ray_P - lightP);
/* One sided. */
if (dot(ray->D, lightN) >= 0.0f) {
continue;
@ -292,9 +303,10 @@ ccl_device bool lights_intersect(KernelGlobals kg,
continue;
}
/* disk oriented normal */
const float3 lightN = normalize(ray_P - lightP);
float3 P;
const float3 lsN = normalize(ray_P - lightP);
if (!ray_disk_intersect(ray->P, ray->D, ray->t, lightP, lsN, radius, &P, &t)) {
if (!ray_disk_intersect(ray->P, ray->D, ray->t, lightP, lightN, radius, &P, &t)) {
continue;
}
}
@ -427,7 +439,12 @@ ccl_device bool light_sample_from_intersection(KernelGlobals kg,
ls->D = ray_D;
if (type == LIGHT_SPOT) {
ls->Ng = make_float3(klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]);
const float3 center = make_float3(klight->co[0], klight->co[1], klight->co[2]);
const float3 dir = make_float3(klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]);
/* the normal of the oriented disk */
const float3 lightN = normalize(ray_P - center);
/* we set the light normal to the outgoing direction to support texturing*/
ls->Ng = -ls->D;
float invarea = klight->spot.invarea;
ls->eval_fac = (0.25f * M_1_PI_F) * invarea;
@ -435,7 +452,7 @@ ccl_device bool light_sample_from_intersection(KernelGlobals kg,
/* spot light attenuation */
ls->eval_fac *= spot_light_attenuation(
ls->Ng, klight->spot.spot_angle, klight->spot.spot_smooth, -ls->D);
dir, klight->spot.spot_angle, klight->spot.spot_smooth, -ls->D);
if (ls->eval_fac == 0.0f) {
return false;
@ -447,23 +464,32 @@ ccl_device bool light_sample_from_intersection(KernelGlobals kg,
/* compute pdf */
if (ls->t != FLT_MAX)
ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
ls->pdf *= lamp_light_pdf(kg, lightN, -ls->D, ls->t);
else
ls->pdf = 0.f;
}
else if (type == LIGHT_POINT) {
float3 center = make_float3(klight->co[0], klight->co[1], klight->co[2]);
const float3 center = make_float3(klight->co[0], klight->co[1], klight->co[2]);
const float3 lighN = normalize(ray_P - center);
/* we set the light normal to the outgoing direction to support texturing*/
ls->Ng = -ls->D;
ls->Ng = normalize(ray_P - center);
float invarea = klight->spot.invarea;
ls->eval_fac = (0.25f * M_1_PI_F) * invarea;
ls->pdf = invarea;
if (ls->eval_fac == 0.0f) {
return false;
}
float2 uv = map_to_sphere(ls->Ng);
ls->u = uv.x;
ls->v = uv.y;
/* compute pdf */
if (ls->t != FLT_MAX)
ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
ls->pdf *= lamp_light_pdf(kg, lighN, -ls->D, ls->t);
else
ls->pdf = 0.f;
}
@ -921,4 +947,4 @@ ccl_device_inline bool light_distribution_sample_new_position(KernelGlobals kg,
}
}
CCL_NAMESPACE_END
CCL_NAMESPACE_END

View File

@ -889,16 +889,11 @@ extern char *GHOST_getClipboard(bool selection);
extern void GHOST_putClipboard(const char *buffer, bool selection);
/**
* Toggles console
* \param action:
* - 0: Hides
* - 1: Shows
* - 2: Toggles
* - 3: Hides if it runs not from command line
* - *: Does nothing
* Set the Console State
* \param action: console state
* \return current status (1 -visible, 0 - hidden)
*/
extern int GHOST_toggleConsole(int action);
extern int setConsoleWindowState(GHOST_TConsoleWindowState action);
/**
* Use native pixel size (MacBook pro 'retina'), if supported.

View File

@ -411,16 +411,11 @@ class GHOST_ISystem {
#endif
/**
* Toggles console
* \param action:
* - 0: Hides.
* - 1: Shows
* - 2: Toggles
* - 3: Hides if it runs not from command line
* - *: Does nothing
* Set the Console State
* \param action: console state
* \return current status (1 -visible, 0 - hidden)
*/
virtual int toggleConsole(int action) = 0;
virtual int setConsoleWindowState(GHOST_TConsoleWindowState action) = 0;
/***************************************************************************************
* Access to clipboard.

View File

@ -152,6 +152,13 @@ typedef enum {
// GHOST_kWindowStateUnModified,
} GHOST_TWindowState;
typedef enum {
GHOST_kConsoleWindowStateHide = 0,
GHOST_kConsoleWindowStateShow,
GHOST_kConsoleWindowStateToggle,
GHOST_kConsoleWindowStateHideForNonConsoleLaunch
} GHOST_TConsoleWindowState;
typedef enum { GHOST_kWindowOrderTop = 0, GHOST_kWindowOrderBottom } GHOST_TWindowOrder;
typedef enum {

View File

@ -809,10 +809,10 @@ void GHOST_putClipboard(const char *buffer, bool selection)
system->putClipboard(buffer, selection);
}
int GHOST_toggleConsole(int action)
int setConsoleWindowState(GHOST_TConsoleWindowState action)
{
GHOST_ISystem *system = GHOST_ISystem::getSystem();
return system->toggleConsole(action);
return system->setConsoleWindowState(action);
}
int GHOST_UseNativePixels(void)

View File

@ -244,7 +244,7 @@ class GHOST_SystemCocoa : public GHOST_System {
/**
* \see GHOST_ISystem
*/
int toggleConsole(int action)
int setConsoleWindowState(GHOST_TConsoleWindowState action)
{
return 0;
}

View File

@ -890,7 +890,7 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent)
bool anyProcessed = false;
NSEvent *event;
// TODO : implement timer ??
/* TODO: implement timer? */
#if 0
do {
GHOST_TimerManager* timerMgr = getTimerManager();

View File

@ -40,7 +40,7 @@ class GHOST_SystemNULL : public GHOST_System {
{
return false;
}
int toggleConsole(int action)
int setConsoleWindowState(GHOST_TConsoleWindowState action)
{
return 0;
}

View File

@ -47,7 +47,7 @@ class GHOST_SystemSDL : public GHOST_System {
bool processEvents(bool waitForEvent);
int toggleConsole(int action)
int setConsoleWindowState(GHOST_TConsoleWindowState action)
{
return 0;
}

View File

@ -1473,7 +1473,7 @@ bool GHOST_SystemWayland::processEvents(bool waitForEvent)
return fired || (getEventManager()->getNumEvents() > 0);
}
int GHOST_SystemWayland::toggleConsole(int /*action*/)
int GHOST_SystemWayland::setConsoleWindowState(GHOST_TConsoleWindowState /*action*/)
{
return 0;
}

View File

@ -53,7 +53,7 @@ class GHOST_SystemWayland : public GHOST_System {
bool processEvents(bool waitForEvent) override;
int toggleConsole(int action) override;
int setConsoleWindowState(GHOST_TConsoleWindowState action) override;
GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys &keys) const override;

View File

@ -105,6 +105,8 @@
*/
#define BROKEN_PEEK_TOUCHPAD
static bool isStartedFromCommandPrompt();
static void initRawInput()
{
#ifdef WITH_INPUT_NDOF
@ -166,7 +168,10 @@ GHOST_SystemWin32::~GHOST_SystemWin32()
{
// Shutdown COM
OleUninitialize();
toggleConsole(1);
if (isStartedFromCommandPrompt()) {
setConsoleWindowState(GHOST_kConsoleWindowStateShow);
}
}
uint64_t GHOST_SystemWin32::performanceCounterToMillis(__int64 perf_ticks) const
@ -2216,31 +2221,30 @@ static bool isStartedFromCommandPrompt()
return false;
}
int GHOST_SystemWin32::toggleConsole(int action)
int GHOST_SystemWin32::setConsoleWindowState(GHOST_TConsoleWindowState action)
{
HWND wnd = GetConsoleWindow();
switch (action) {
case 3: // startup: hide if not started from command prompt
{
case GHOST_kConsoleWindowStateHideForNonConsoleLaunch: {
if (!isStartedFromCommandPrompt()) {
ShowWindow(wnd, SW_HIDE);
m_consoleStatus = 0;
}
break;
}
case 0: // hide
case GHOST_kConsoleWindowStateHide:
ShowWindow(wnd, SW_HIDE);
m_consoleStatus = 0;
break;
case 1: // show
case GHOST_kConsoleWindowStateShow:
ShowWindow(wnd, SW_SHOW);
if (!isStartedFromCommandPrompt()) {
DeleteMenu(GetSystemMenu(wnd, FALSE), SC_CLOSE, MF_BYCOMMAND);
}
m_consoleStatus = 1;
break;
case 2: // toggle
case GHOST_kConsoleWindowStateToggle:
ShowWindow(wnd, m_consoleStatus ? SW_HIDE : SW_SHOW);
m_consoleStatus = !m_consoleStatus;
if (m_consoleStatus && !isStartedFromCommandPrompt()) {

View File

@ -436,16 +436,11 @@ class GHOST_SystemWin32 : public GHOST_System {
static LRESULT WINAPI s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
/**
* Toggles console
* \param action:
* - 0 - Hides
* - 1 - Shows
* - 2 - Toggles
* - 3 - Hides if it runs not from command line
* - * - Does nothing
* Set the Console State
* \param action: console state
* \return current status (1 -visible, 0 - hidden)
*/
int toggleConsole(int action);
int setConsoleWindowState(GHOST_TConsoleWindowState action);
/** The current state of the modifier keys. */
GHOST_ModifierKeys m_modifierKeys;

View File

@ -269,7 +269,7 @@ class GHOST_SystemX11 : public GHOST_System {
/**
* \see GHOST_ISystem
*/
int toggleConsole(int /*action*/)
int setConsoleWindowState(GHOST_TConsoleWindowState /*action*/)
{
return 0;
}

View File

@ -86,6 +86,7 @@ void GHOST_XrContext::initialize(const GHOST_XrContextCreateInfo *create_info)
initApiLayers();
initExtensions();
if (isDebugMode()) {
printSDKVersion();
printAvailableAPILayersAndExtensionsInfo();
}
@ -156,6 +157,16 @@ void GHOST_XrContext::storeInstanceProperties()
/** \name Debug Printing
* \{ */
void GHOST_XrContext::printSDKVersion()
{
const XrVersion sdk_version = XR_CURRENT_API_VERSION;
printf("OpenXR SDK Version: %u.%u.%u\n",
XR_VERSION_MAJOR(sdk_version),
XR_VERSION_MINOR(sdk_version),
XR_VERSION_PATCH(sdk_version));
}
void GHOST_XrContext::printInstanceInfo()
{
assert(m_oxr->instance != XR_NULL_HANDLE);

View File

@ -126,6 +126,7 @@ class GHOST_XrContext : public GHOST_IXrContext {
void storeInstanceProperties();
void initDebugMessenger();
void printSDKVersion();
void printInstanceInfo();
void printAvailableAPILayersAndExtensionsInfo();
void printExtensionsAndAPILayersToEnable();

View File

@ -39,8 +39,8 @@
* second intern/ module with MEM_ prefix, for use in c++.
*
* \subsection memdependencies Dependencies
* - stdlib
* - stdio
* - `stdlib`
* - `stdio`
*
* \subsection memdocs API Documentation
* See \ref MEM_guardedalloc.h
@ -276,6 +276,12 @@ void MEM_use_guarded_allocator(void);
* Allocate new memory for and constructs an object of type #T.
* #MEM_delete should be used to delete the object. Just calling #MEM_freeN is not enough when #T
* is not a trivial type.
*
* Note that when no arguments are passed, C++ will do recursive member-wise value initialization.
* That is because C++ differentiates between creating an object with `T` (default initialization)
* and `T()` (value initialization), whereby this function does the latter. Value initialization
* rules are complex, but for C-style structs, memory will be zero-initialized. So this doesn't
* match a `malloc()`, but a `calloc()` call in this case. See https://stackoverflow.com/a/4982720.
*/
template<typename T, typename... Args>
inline T *MEM_new(const char *allocation_name, Args &&...args)

View File

@ -56,7 +56,6 @@ if(WITH_INTERNATIONAL)
list(APPEND LIB
${BOOST_LIBRARIES}
)
add_definitions(-DWITH_INTERNATIONAL)
add_definitions(${BOOST_DEFINITIONS})
endif()

@ -1 +1 @@
Subproject commit 93612eddc7cdfa82d1e7c31c362df0988388629b
Subproject commit 2d12637a69df7643484a8a3655b7eeb6faa170a7

@ -1 +1 @@
Subproject commit 9207696bbfac648c299f29f031ab5f18d8fa0077
Subproject commit 089aef61debbece2baff6516e33fc7491629b1d0

View File

@ -356,6 +356,7 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = {
"y",
"y = (Ax + B)",
# Sub-strings.
"and AMD Radeon Pro 21.Q4 driver or newer",
"available with",
"brown fox",
"can't save image while rendering",
@ -378,6 +379,7 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = {
"image path can't be written to",
"in memory to enable editing!",
"insufficient content",
"into",
"jumps over",
"left",
"local",
@ -387,6 +389,7 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = {
"performance impact!",
"right",
"the lazy dog",
"to the top level of the tree",
"unable to load movie clip",
"unable to load text",
"unable to open the file",

View File

@ -76,10 +76,12 @@ class SpellChecker:
"tangency",
"vertices",
"wasn", # wasn't
"zig", "zag",
# Brands etc.
"htc",
"huawei",
"radeon",
"vive",
"xbox",
@ -136,6 +138,7 @@ class SpellChecker:
"filename", "filenames",
"filepath", "filepaths",
"forcefield", "forcefields",
"framerange",
"fulldome", "fulldomes",
"fullscreen",
"gamepad",
@ -498,6 +501,7 @@ class SpellChecker:
"framerate",
"gimbal",
"grayscale",
"icosahedron",
"icosphere",
"inpaint",
"kerning",
@ -556,6 +560,7 @@ class SpellChecker:
"bspline",
"bweight",
"colorband",
"crazyspace",
"datablock", "datablocks",
"despeckle",
"depsgraph",
@ -730,6 +735,7 @@ class SpellChecker:
"precisa",
"px",
"qmc",
"rdna",
"rdp",
"rgb", "rgba",
"rhs",

View File

@ -677,7 +677,6 @@ url_manual_mapping = (
("bpy.ops.gpencil.stroke_merge_by_distance*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-stroke-merge-by-distance"),
("bpy.ops.node.collapse_hide_unused_toggle*", "interface/controls/nodes/editing.html#bpy-ops-node-collapse-hide-unused-toggle"),
("bpy.ops.object.anim_transforms_to_deltas*", "scene_layout/object/editing/apply.html#bpy-ops-object-anim-transforms-to-deltas"),
("bpy.ops.object.convert_proxy_to_override*", "files/linked_libraries/library_overrides.html#bpy-ops-object-convert-proxy-to-override"),
("bpy.ops.object.modifier_copy_to_selected*", "modeling/modifiers/introduction.html#bpy-ops-object-modifier-copy-to-selected"),
("bpy.ops.preferences.app_template_install*", "advanced/app_templates.html#bpy-ops-preferences-app-template-install"),
("bpy.types.actionposemarkers.active_index*", "animation/armatures/properties/pose_library.html#bpy-types-actionposemarkers-active-index"),
@ -2140,7 +2139,6 @@ url_manual_mapping = (
("bpy.ops.object.origin_set*", "scene_layout/object/origin.html#bpy-ops-object-origin-set"),
("bpy.ops.object.parent_set*", "scene_layout/object/editing/parent.html#bpy-ops-object-parent-set"),
("bpy.ops.object.pointcloud*", "modeling/point_cloud.html#bpy-ops-object-pointcloud"),
("bpy.ops.object.proxy_make*", "files/linked_libraries/library_proxies.html#bpy-ops-object-proxy-make"),
("bpy.ops.object.select_all*", "scene_layout/object/selecting.html#bpy-ops-object-select-all"),
("bpy.ops.object.shade_flat*", "scene_layout/object/editing/shading.html#bpy-ops-object-shade-flat"),
("bpy.ops.pose.group_assign*", "animation/armatures/properties/bone_groups.html#bpy-ops-pose-group-assign"),

View File

@ -298,7 +298,7 @@ def xml2rna(
del value_xml_split
tp_name = 'ARRAY'
# print(" %s.%s (%s) --- %s" % (type(value).__name__, attr, tp_name, subvalue_type))
# print(" %s.%s (%s) --- %s" % (type(value).__name__, attr, tp_name, subvalue_type))
try:
setattr(value, attr, value_xml_coerce)
except ValueError:
@ -340,7 +340,6 @@ def xml2rna(
else:
# print(elems)
if len(elems) == 1:
# sub node named by its type
child_xml_real, = elems
@ -376,7 +375,6 @@ def _get_context_val(context, path):
def xml_file_run(context, filepath, rna_map):
import xml.dom.minidom
xml_nodes = xml.dom.minidom.parse(filepath)
@ -391,27 +389,25 @@ def xml_file_run(context, filepath, rna_map):
value = _get_context_val(context, rna_path)
if value is not Ellipsis and value is not None:
print(" loading XML: %r -> %r" % (filepath, rna_path))
# print(" loading XML: %r -> %r" % (filepath, rna_path))
xml2rna(xml_node, root_rna=value)
def xml_file_write(context, filepath, rna_map, *, skip_typemap=None):
with open(filepath, "w", encoding="utf-8") as file:
fw = file.write
fw("<bpy>\n")
file = open(filepath, "w", encoding="utf-8")
fw = file.write
fw("<bpy>\n")
for rna_path, _xml_tag in rna_map:
# xml_tag is ignored, we get this from the rna
value = _get_context_val(context, rna_path)
rna2xml(fw,
for rna_path, _xml_tag in rna_map:
# xml_tag is ignored, we get this from the rna
value = _get_context_val(context, rna_path)
rna2xml(
fw=fw,
root_rna=value,
method='ATTR',
root_ident=" ",
ident_val=" ",
skip_typemap=skip_typemap,
)
)
fw("</bpy>\n")
file.close()
fw("</bpy>\n")

View File

@ -318,7 +318,8 @@ def load():
use_v3d_tab_menu=kc_prefs.use_v3d_tab_menu,
use_v3d_shade_ex_pie=kc_prefs.use_v3d_shade_ex_pie,
use_gizmo_drag=(is_select_left and kc_prefs.gizmo_action == 'DRAG'),
use_fallback_tool=(True if is_select_left else (kc_prefs.rmb_action == 'FALLBACK_TOOL')),
use_fallback_tool=True,
use_fallback_tool_rmb=(False if is_select_left else kc_prefs.rmb_action == 'FALLBACK_TOOL'),
use_alt_tool_or_cursor=(
(not use_mouse_emulate_3_button) and
(kc_prefs.use_alt_tool if is_select_left else kc_prefs.use_alt_cursor)

View File

@ -16,6 +16,16 @@
#
# ##### END GPL LICENSE BLOCK #####
# ------------------------------------------------------------------------------
# Developer Notes
#
# - This script should run without Blender (no references to the `bpy` module for example).
# - All configuration must be passed into the `generate_keymaps` function (via `Params`).
# - Supporting some combinations of options is becoming increasingly complex,
# especially `Params.select_mouse` & `Params.use_fallback_tool_rmb`.
# To ensure changes don't unintentionally break other configurations, see:
# `source/tools/utils/blender_keyconfig_export_permutations.py --help`
#
# ------------------------------------------------------------------------------
# Configurable Parameters
@ -46,6 +56,8 @@ class Params:
"use_gizmo_drag",
# Use the fallback tool instead of tweak for RMB select.
"use_fallback_tool",
# Only set for RMB select.
"use_fallback_tool_rmb",
# Use pie menu for tab by default (swap 'Tab/Ctrl-Tab').
"use_v3d_tab_menu",
# Use extended pie menu for shading.
@ -64,17 +76,16 @@ class Params:
"v3d_tilde_action",
# Alt-MMB axis switching 'RELATIVE' or 'ABSOLUTE' axis switching.
"v3d_alt_mmb_drag_action",
# File selector actions on single click.
"use_file_single_click",
# Convenience variables:
# (derived from other settings).
#
# This case needs to be checked often,
# Shorthand for: `(params.use_fallback_tool if params.select_mouse ==
# 'RIGHTMOUSE' else False)`.
"use_fallback_tool_rmb",
# Shorthand for: `('CLICK' if params.use_fallback_tool_rmb else
# params.select_mouse_value)`.
# The fallback tool is activated on the same button as selection.
# Shorthand for: `(True if (select_mouse == 'LEFT') else self.use_fallback_tool_rmb)`
"use_fallback_tool_select_mouse",
# Shorthand for: `('CLICK' if self.use_fallback_tool_rmb else self.select_mouse_value)`.
"select_mouse_value_fallback",
# Shorthand for: `{"type": params.select_tweak, "value": 'ANY'}`.
"select_tweak_event",
@ -106,6 +117,7 @@ class Params:
use_select_all_toggle=False,
use_gizmo_drag=True,
use_fallback_tool=False,
use_fallback_tool_rmb=False,
use_v3d_tab_menu=False,
use_v3d_shade_ex_pie=False,
use_v3d_mmb_pan=False,
@ -148,7 +160,6 @@ class Params:
self.cursor_set_event = {"type": 'LEFTMOUSE', "value": 'CLICK'}
self.cursor_tweak_event = None
self.use_fallback_tool = use_fallback_tool
self.tool_modifier = {}
else:
# Left mouse select uses Click event for selection. This is a
@ -173,7 +184,6 @@ class Params:
self.cursor_set_event = {"type": 'RIGHTMOUSE', "value": 'PRESS', "shift": True}
self.cursor_tweak_event = {"type": 'EVT_TWEAK_R', "value": 'ANY', "shift": True}
self.use_fallback_tool = True
# Use the "tool" functionality for LMB select.
if use_alt_tool_or_cursor:
@ -201,8 +211,11 @@ class Params:
self.use_file_single_click = use_file_single_click
self.use_fallback_tool = use_fallback_tool
self.use_fallback_tool_rmb = use_fallback_tool_rmb
# Convenience variables:
self.use_fallback_tool_rmb = self.use_fallback_tool if select_mouse == 'RIGHT' else False
self.use_fallback_tool_select_mouse = True if (select_mouse == 'LEFT') else self.use_fallback_tool_rmb
self.select_mouse_value_fallback = 'CLICK' if self.use_fallback_tool_rmb else self.select_mouse_value
self.select_tweak_event = {"type": self.select_tweak, "value": 'ANY'}
self.pie_value = 'CLICK_DRAG' if use_pie_click_drag else 'PRESS'
@ -1047,9 +1060,7 @@ def km_uv_editor(params):
items.extend([# Selection modes.
*_template_items_uv_select_mode(params),
*_template_uv_select(type=params.select_mouse,
value=('CLICK' if params.use_fallback_tool_rmb else params.select_mouse_value),
legacy=params.legacy,),
*_template_uv_select(type=params.select_mouse, value=params.select_mouse_value_fallback, legacy=params.legacy),
("uv.mark_seam", {"type": 'E', "value": 'PRESS', "ctrl": True}, None),
("uv.select_loop",
{"type": params.select_mouse, "value": params.select_mouse_value, "alt": True}, None),
@ -5660,10 +5671,12 @@ def km_image_editor_tool_uv_select(params, *, fallback):
def km_image_editor_tool_uv_select_box(params, *, fallback):
return (_fallback_id("Image Editor Tool: Uv, Select Box", fallback),
{"space_type": 'IMAGE_EDITOR', "region_type": 'WINDOW'},
{"items": [*([] if (fallback and not params.use_fallback_tool) else _template_items_tool_select_actions_simple("uv.select_box",
# Don't use `tool_maybe_tweak_event`, see comment for this
# slot.
**(params.select_tweak_event if fallback else params.tool_tweak_event))),
{"items": [
*([] if (fallback and not params.use_fallback_tool) else _template_items_tool_select_actions_simple(
"uv.select_box",
# Don't use `tool_maybe_tweak_event`, see comment for this slot.
**(params.select_tweak_event if (fallback and params.use_fallback_tool_select_mouse) else
params.tool_tweak_event))),
]},
)
@ -5671,8 +5684,11 @@ def km_image_editor_tool_uv_select_box(params, *, fallback):
def km_image_editor_tool_uv_select_circle(params, *, fallback):
return (_fallback_id("Image Editor Tool: Uv, Select Circle", fallback),
{"space_type": 'IMAGE_EDITOR', "region_type": 'WINDOW'},
{"items": [*([] if (fallback and not params.use_fallback_tool) else _template_items_tool_select_actions_simple("uv.select_circle",
**(params.select_tweak_event if fallback else {"type": params.tool_mouse, "value": 'PRESS'}),
{"items": [
*([] if (fallback and not params.use_fallback_tool) else _template_items_tool_select_actions_simple(
"uv.select_circle",
**(params.select_tweak_event if (fallback and params.use_fallback_tool_select_mouse) else
{"type": params.tool_mouse, "value": 'PRESS'}),
properties=[("wait_for_input", False)])),
# No selection fallback since this operates on press.
]},)
@ -5682,8 +5698,11 @@ def km_image_editor_tool_uv_select_lasso(params, *, fallback):
return (_fallback_id("Image Editor Tool: Uv, Select Lasso", fallback),
{"space_type": 'IMAGE_EDITOR', "region_type": 'WINDOW'},
{"items": [*([] if (fallback and not params.use_fallback_tool) else _template_items_tool_select_actions_simple("uv.select_lasso",
**(params.select_tweak_event if fallback else params.tool_tweak_event))),
{"items": [
*([] if (fallback and not params.use_fallback_tool) else _template_items_tool_select_actions_simple(
"uv.select_lasso",
**(params.select_tweak_event if (fallback and params.use_fallback_tool_select_mouse) else
params.tool_tweak_event))),
]},
)
@ -5753,7 +5772,8 @@ def km_node_editor_tool_select_box(params, *, fallback):
*([] if (fallback and not params.use_fallback_tool) else _template_items_tool_select_actions_simple(
"node.select_box",
# Don't use `tool_maybe_tweak_event`, see comment for this slot.
**(params.select_tweak_event if fallback else params.tool_tweak_event),
**(params.select_tweak_event if (fallback and params.use_fallback_tool_select_mouse) else
params.tool_tweak_event),
properties=[("tweak", True)],
)),
]},
@ -5765,7 +5785,9 @@ def km_node_editor_tool_select_lasso(params, *, fallback):
{"space_type": 'NODE_EDITOR', "region_type": 'WINDOW'},
{"items": [
*([] if (fallback and not params.use_fallback_tool) else _template_items_tool_select_actions_simple(
"node.select_lasso", **(params.select_tweak_event if fallback else params.tool_tweak_event),
"node.select_lasso",
**(params.select_tweak_event if (fallback and params.use_fallback_tool_select_mouse) else
params.tool_tweak_event),
properties=[("tweak", True)]))
]},
)
@ -5779,7 +5801,7 @@ def km_node_editor_tool_select_circle(params, *, fallback):
"node.select_circle",
# Why circle select should be used on tweak?
# So that RMB or Shift-RMB is still able to set an element as active.
type=params.select_tweak if fallback else params.tool_mouse,
type=params.select_tweak if (fallback and params.use_fallback_tool_select_mouse) else params.tool_mouse,
value='ANY' if fallback else 'PRESS',
properties=[("wait_for_input", False)])),
]},
@ -5820,10 +5842,12 @@ def km_3d_view_tool_select(params, *, fallback):
def km_3d_view_tool_select_box(params, *, fallback):
return (_fallback_id("3D View Tool: Select Box", fallback),
{"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
{"items": [*([] if (fallback and not params.use_fallback_tool) else _template_items_tool_select_actions("view3d.select_box",
# Don't use `tool_maybe_tweak_event`, see comment for this
# slot.
**(params.select_tweak_event if fallback else params.tool_tweak_event))),
{"items": [
*([] if (fallback and not params.use_fallback_tool) else _template_items_tool_select_actions(
"view3d.select_box",
# Don't use `tool_maybe_tweak_event`, see comment for this slot.
**(params.select_tweak_event if (fallback and params.use_fallback_tool_select_mouse) else
params.tool_tweak_event))),
]},
)
@ -5833,9 +5857,8 @@ def km_3d_view_tool_select_circle(params, *, fallback):
{"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
{"items": [*([] if (fallback and not params.use_fallback_tool) else _template_items_tool_select_actions_simple("view3d.select_circle",
# Why circle select should be used on tweak?
# So that RMB or Shift-RMB is still able to set an element as
# active.
type=params.select_tweak if fallback else params.tool_mouse,
# So that RMB or Shift-RMB is still able to set an element as active.
type=params.select_tweak if (fallback and params.use_fallback_tool_select_mouse) else params.tool_mouse,
value='ANY' if fallback else 'PRESS',
properties=[("wait_for_input", False)])),
]},
@ -5845,8 +5868,11 @@ def km_3d_view_tool_select_circle(params, *, fallback):
def km_3d_view_tool_select_lasso(params, *, fallback):
return (_fallback_id("3D View Tool: Select Lasso", fallback),
{"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
{"items": [*([] if (fallback and not params.use_fallback_tool) else _template_items_tool_select_actions("view3d.select_lasso",
**(params.select_tweak_event if fallback else params.tool_tweak_event))),
{"items": [
*([] if (fallback and not params.use_fallback_tool) else _template_items_tool_select_actions(
"view3d.select_lasso",
**(params.select_tweak_event if (fallback and params.use_fallback_tool_select_mouse) else
params.tool_tweak_event))),
]}
)
@ -6471,10 +6497,12 @@ def km_3d_view_tool_edit_gpencil_select(params, *, fallback):
def km_3d_view_tool_edit_gpencil_select_box(params, *, fallback):
return (_fallback_id("3D View Tool: Edit Gpencil, Select Box", fallback),
{"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
{"items": [*([] if (fallback and not params.use_fallback_tool) else _template_items_tool_select_actions("gpencil.select_box",
# Don't use `tool_maybe_tweak_event`, see comment for this
# slot.
**(params.select_tweak_event if fallback else params.tool_tweak_event))),
{"items": [
*([] if (fallback and not params.use_fallback_tool) else _template_items_tool_select_actions(
"gpencil.select_box",
# Don't use `tool_maybe_tweak_event`, see comment for this slot.
**(params.select_tweak_event if (fallback and params.use_fallback_tool_select_mouse) else
params.tool_tweak_event))),
]},
)
@ -6484,9 +6512,8 @@ def km_3d_view_tool_edit_gpencil_select_circle(params, *, fallback):
{"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
{"items": [*([] if (fallback and not params.use_fallback_tool) else _template_items_tool_select_actions_simple("gpencil.select_circle",
# Why circle select should be used on tweak?
# So that RMB or Shift-RMB is still able to set an element as
# active.
type=params.select_tweak if fallback else params.tool_mouse,
# So that RMB or Shift-RMB is still able to set an element as active.
type=params.select_tweak if (fallback and params.use_fallback_tool_select_mouse) else params.tool_mouse,
value='ANY' if fallback else 'PRESS',
properties=[("wait_for_input", False)])),
]},
@ -6496,8 +6523,11 @@ def km_3d_view_tool_edit_gpencil_select_circle(params, *, fallback):
def km_3d_view_tool_edit_gpencil_select_lasso(params, *, fallback):
return (_fallback_id("3D View Tool: Edit Gpencil, Select Lasso", fallback),
{"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
{"items": [*([] if (fallback and not params.use_fallback_tool) else _template_items_tool_select_actions("gpencil.select_lasso",
**(params.select_tweak_event if fallback else params.tool_tweak_event))),
{"items": [
*([] if (fallback and not params.use_fallback_tool) else _template_items_tool_select_actions(
"gpencil.select_lasso",
**(params.select_tweak_event if (fallback and params.use_fallback_tool_select_mouse) else
params.tool_tweak_event))),
]}
)
@ -6606,9 +6636,12 @@ def km_sequencer_editor_tool_generic_select_box(params, *, fallback):
return (
_fallback_id("Sequencer Tool: Select Box", fallback),
{"space_type": 'SEQUENCE_EDITOR', "region_type": 'WINDOW'},
{"items": [# Don't use `tool_maybe_tweak_event`, see comment for this slot.
*([] if (fallback and not params.use_fallback_tool) else _template_items_tool_select_actions_simple("sequencer.select_box",
**(params.select_tweak_event if fallback else params.tool_tweak_event),
{"items": [
# Don't use `tool_maybe_tweak_event`, see comment for this slot.
*([] if (fallback and not params.use_fallback_tool) else _template_items_tool_select_actions_simple(
"sequencer.select_box",
**(params.select_tweak_event if (fallback and params.use_fallback_tool_select_mouse) else
params.tool_tweak_event),
properties=[("tweak", params.select_mouse == 'LEFTMOUSE')])),
# RMB select can already set the frame, match the tweak tool.

View File

@ -2977,94 +2977,76 @@ class WM_MT_splash_quick_setup(Menu):
bl_label = "Quick Setup"
def draw(self, context):
wm = context.window_manager
# prefs = context.preferences
layout = self.layout
layout.operator_context = 'EXEC_DEFAULT'
show_build_notes(layout)
layout.label(text="Quick Setup")
split = layout.split(factor=0.25)
split = layout.split(factor=0.14) # Left margin.
split.label()
split = split.split(factor=2.0 / 3.0)
split = split.split(factor=0.73) # Content width.
col = split.column()
col.use_property_split = True
col.use_property_decorate = False
# Languages.
if bpy.app.build_options.international:
sub = col.split(factor=0.35)
row = sub.row()
row.alignment = 'RIGHT'
row.label(text="Language")
prefs = context.preferences
sub.prop(prefs.view, "language", text="")
col.prop(prefs.view, "language")
col.separator()
col.separator()
# Shortcuts.
wm = context.window_manager
kc = wm.keyconfigs.active
kc_prefs = kc.preferences
sub = col.split(factor=0.35)
row = sub.row()
row.alignment = 'RIGHT'
row.label(text="Shortcuts")
text = bpy.path.display_name(wm.keyconfigs.active.name)
sub = col.column(heading="Shortcuts")
text = bpy.path.display_name(kc.name)
if not text:
text = "Blender"
sub.menu("USERPREF_MT_keyconfigs", text=text)
kc = wm.keyconfigs.active
kc_prefs = kc.preferences
has_select_mouse = hasattr(kc_prefs, "select_mouse")
if has_select_mouse:
sub = col.split(factor=0.35)
row = sub.row()
row.alignment = 'RIGHT'
row.label(text="Select With")
sub.row().prop(kc_prefs, "select_mouse", expand=True)
has_select_mouse = True
col.row().prop(kc_prefs, "select_mouse", text="Select With", expand=True)
has_spacebar_action = hasattr(kc_prefs, "spacebar_action")
if has_spacebar_action:
sub = col.split(factor=0.35)
row = sub.row()
row.alignment = 'RIGHT'
row.label(text="Spacebar")
sub.row().prop(kc_prefs, "spacebar_action", expand=True)
has_select_mouse = True
col.row().prop(kc_prefs, "spacebar_action", text="Spacebar")
col.separator()
sub = col.split(factor=0.35)
row = sub.row()
row.alignment = 'RIGHT'
row.label(text="Theme")
# Themes.
sub = col.column(heading="Theme")
label = bpy.types.USERPREF_MT_interface_theme_presets.bl_label
if label == "Presets":
label = "Blender Dark"
sub.menu("USERPREF_MT_interface_theme_presets", text=label)
# Keep height constant
# Keep height constant.
if not has_select_mouse:
col.label()
if not has_spacebar_action:
col.label()
layout.label()
layout.separator(factor=2.0)
row = layout.row()
# Save settings buttons.
sub = layout.row()
sub = row.row()
old_version = bpy.types.PREFERENCES_OT_copy_prev.previous_version()
if bpy.types.PREFERENCES_OT_copy_prev.poll(context) and old_version:
sub.operator("preferences.copy_prev", text=iface_("Load %d.%d Settings", "Operator") % old_version)
sub.operator("preferences.copy_prev", text="Load %d.%d Settings" % old_version)
sub.operator("wm.save_userpref", text="Save New Settings")
else:
sub.label()
sub.label()
sub.operator("wm.save_userpref", text="Next")
layout.separator()
layout.separator()
layout.separator(factor=2.4)
class WM_MT_splash(Menu):

View File

@ -33,9 +33,9 @@ _modules = [
"properties_data_bone",
"properties_data_camera",
"properties_data_curve",
"properties_data_curves",
"properties_data_empty",
"properties_data_gpencil",
"properties_data_hair",
"properties_data_light",
"properties_data_lattice",
"properties_data_mesh",

View File

@ -149,7 +149,6 @@ class DATA_PT_bone_groups(ArmatureButtonsPanel, Panel):
col.operator("pose.group_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
split = layout.split()
split.active = (ob.proxy is None)
col = split.column()
col.prop(group, "color_set")

View File

@ -30,10 +30,10 @@ class DataButtonsPanel:
@classmethod
def poll(cls, context):
engine = context.scene.render.engine
return hasattr(context, 'hair') and context.hair and (engine in cls.COMPAT_ENGINES)
return hasattr(context, 'curves') and context.curves and (engine in cls.COMPAT_ENGINES)
class DATA_PT_context_hair(DataButtonsPanel, Panel):
class DATA_PT_context_curves(DataButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
@ -42,21 +42,21 @@ class DATA_PT_context_hair(DataButtonsPanel, Panel):
layout = self.layout
ob = context.object
hair = context.hair
curves = context.curves
space = context.space_data
if ob:
layout.template_ID(ob, "data")
elif hair:
elif curves:
layout.template_ID(space, "pin_id")
class HAIR_MT_add_attribute(Menu):
class CURVES_MT_add_attribute(Menu):
bl_label = "Add Attribute"
@staticmethod
def add_standard_attribute(layout, hair, name, data_type, domain):
exists = hair.attributes.get(name) is not None
def add_standard_attribute(layout, curves, name, data_type, domain):
exists = curves.attributes.get(name) is not None
col = layout.column()
col.enabled = not exists
@ -69,10 +69,10 @@ class HAIR_MT_add_attribute(Menu):
def draw(self, context):
layout = self.layout
hair = context.hair
curves = context.curves
self.add_standard_attribute(layout, hair, 'Radius', 'FLOAT', 'POINT')
self.add_standard_attribute(layout, hair, 'Color', 'FLOAT_COLOR', 'POINT')
self.add_standard_attribute(layout, curves, 'radius', 'FLOAT', 'POINT')
self.add_standard_attribute(layout, curves, 'color', 'FLOAT_COLOR', 'POINT')
layout.separator()
@ -80,7 +80,7 @@ class HAIR_MT_add_attribute(Menu):
layout.operator("geometry.attribute_add", text="Custom...")
class HAIR_UL_attributes(UIList):
class CURVES_UL_attributes(UIList):
def draw_item(self, _context, layout, _data, attribute, _icon, _active_data, _active_propname, _index):
data_type = attribute.bl_rna.properties['data_type'].enum_items[attribute.data_type]
domain = attribute.bl_rna.properties['domain'].enum_items[attribute.domain]
@ -96,44 +96,44 @@ class HAIR_UL_attributes(UIList):
sub.label(text=data_type.name)
class DATA_PT_hair_attributes(DataButtonsPanel, Panel):
class DATA_PT_CURVES_attributes(DataButtonsPanel, Panel):
bl_label = "Attributes"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
def draw(self, context):
hair = context.hair
curves = context.curves
layout = self.layout
row = layout.row()
col = row.column()
col.template_list(
"HAIR_UL_attributes",
"CURVES_UL_attributes",
"attributes",
hair,
curves,
"attributes",
hair.attributes,
curves.attributes,
"active_index",
rows=3,
)
col = row.column(align=True)
col.menu("HAIR_MT_add_attribute", icon='ADD', text="")
col.menu("CURVES_MT_add_attribute", icon='ADD', text="")
col.operator("geometry.attribute_remove", icon='REMOVE', text="")
class DATA_PT_custom_props_hair(DataButtonsPanel, PropertyPanel, Panel):
class DATA_PT_custom_props_curves(DataButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
_context_path = "object.data"
_property_type = bpy.types.Hair if hasattr(bpy.types, "Hair") else None
_property_type = bpy.types.Curves if hasattr(bpy.types, "Curves") else None
classes = (
DATA_PT_context_hair,
DATA_PT_hair_attributes,
DATA_PT_custom_props_hair,
HAIR_MT_add_attribute,
HAIR_UL_attributes,
DATA_PT_context_curves,
DATA_PT_CURVES_attributes,
DATA_PT_custom_props_curves,
CURVES_MT_add_attribute,
CURVES_UL_attributes,
)
if __name__ == "__main__": # only for live edit.

View File

@ -127,8 +127,8 @@ class DopesheetFilterPopoverBase:
flow.prop(dopesheet, "show_lattices", text="Lattices")
if bpy.data.metaballs:
flow.prop(dopesheet, "show_metaballs", text="Metaballs")
if hasattr(bpy.data, "hairs") and bpy.data.hairs:
flow.prop(dopesheet, "show_hairs", text="Hairs")
if hasattr(bpy.data, "hair_curves") and bpy.data.hair_curves:
flow.prop(dopesheet, "show_hair_curves", text="Hair Curves")
if hasattr(bpy.data, "pointclouds") and bpy.data.pointclouds:
flow.prop(dopesheet, "show_pointclouds", text="Point Clouds")
if bpy.data.volumes:

View File

@ -291,6 +291,9 @@ class NLA_MT_context_menu(Menu):
layout.separator()
props = layout.operator("wm.call_panel", text="Rename...")
props.name = "TOPBAR_PT_name"
props.keep_open = False
layout.operator("nla.duplicate", text="Duplicate").linked = False
layout.operator("nla.duplicate", text="Linked Duplicate").linked = True

View File

@ -448,7 +448,7 @@ class OUTLINER_PT_filter(Panel):
if (
bpy.data.curves or
bpy.data.metaballs or
(hasattr(bpy.data, "hairs") and bpy.data.hairs) or
(hasattr(bpy.data, "hair_curves") and bpy.data.hair_curves) or
(hasattr(bpy.data, "pointclouds") and bpy.data.pointclouds) or
bpy.data.volumes or
bpy.data.lightprobes or

View File

@ -2027,6 +2027,9 @@ class SEQUENCER_PT_adjust_transform(SequencerButtonsPanel, Panel):
layout.use_property_split = True
layout.active = not strip.mute
col = layout.column(align=True)
col.prop(strip.transform, "filter", text="Filter")
col = layout.column(align=True)
col.prop(strip.transform, "offset_x", text="Position X")
col.prop(strip.transform, "offset_y", text="Y")

View File

@ -481,7 +481,7 @@ class TOPBAR_MT_file_export(Menu):
bl_owner_use_filter = False
def draw(self, _context):
self.layout.operator("wm.obj_export", text="Wavefront OBJ (.obj) - New")
self.layout.operator("wm.obj_export", text="Wavefront OBJ (.obj)")
if bpy.app.build_options.collada:
self.layout.operator("wm.collada_export",
text="Collada (Default) (.dae)")
@ -832,6 +832,14 @@ class TOPBAR_PT_name(Panel):
row = row_with_icon(layout, 'NODE')
row.prop(item, "label", text="")
found = True
elif space_type == 'NLA_EDITOR':
layout.label(text="NLA Strip Name")
item = next(
(strip for strip in context.selected_nla_strips if strip.active), None)
if item:
row = row_with_icon(layout, 'NLA')
row.prop(item, "name", text="")
found = True
else:
if mode == 'POSE' or (mode == 'WEIGHT_PAINT' and context.pose_object):
layout.label(text="Bone Name")

View File

@ -2227,7 +2227,9 @@ class USERPREF_PT_experimental_prototypes(ExperimentalPanel, Panel):
bl_label = "Prototypes"
def draw(self, context):
self._draw_items(context, (({"property": "use_new_hair_type"}, "T68981"),
self._draw_items(
context, (
({"property": "use_new_curves_type"}, "T68981"),
({"property": "use_new_point_cloud_type"}, "T75717"),
({"property": "use_full_frame_compositor"}, "T88150"),),)
@ -2245,7 +2247,6 @@ class USERPREF_PT_experimental_debugging(ExperimentalPanel, Panel):
def draw(self, context):
self._draw_items(context, (({"property": "use_undo_legacy"}, "T60695"),
({"property": "override_auto_resync"}, "T83811"),
({"property": "proxy_to_override_auto_conversion"}, "T91671"),
({"property": "use_cycles_debug"}, None),
({"property": "use_geometry_nodes_legacy"}, "T91274"),
({"property": "show_asset_debug_info"}, None),

View File

@ -2223,8 +2223,8 @@ class VIEW3D_MT_add(Menu):
layout.menu("VIEW3D_MT_surface_add", icon='OUTLINER_OB_SURFACE')
layout.menu("VIEW3D_MT_metaball_add", text="Metaball", icon='OUTLINER_OB_META')
layout.operator("object.text_add", text="Text", icon='OUTLINER_OB_FONT')
if context.preferences.experimental.use_new_hair_type:
layout.operator("object.hair_add", text="Hair", icon='OUTLINER_OB_HAIR')
if context.preferences.experimental.use_new_curves_type:
layout.operator("object.hair_curves_add", text="Hair Curves", icon='OUTLINER_OB_CURVES')
if context.preferences.experimental.use_new_point_cloud_type:
layout.operator("object.pointcloud_add", text="Point Cloud", icon='OUTLINER_OB_POINTCLOUD')
layout.menu("VIEW3D_MT_volume_add", text="Volume", icon='OUTLINER_OB_VOLUME')
@ -2299,8 +2299,6 @@ class VIEW3D_MT_object_relations(Menu):
layout.operator("object.make_override_library", text="Make Library Override...")
layout.operator("object.convert_proxy_to_override")
layout.operator("object.make_dupli_face")
layout.separator()

View File

@ -547,6 +547,8 @@ compositor_node_categories = [
NodeItem("CompositorNodeCombYUVA"),
NodeItem("CompositorNodeSepYCCA"),
NodeItem("CompositorNodeCombYCCA"),
NodeItem("CompositorNodeSeparateXYZ"),
NodeItem("CompositorNodeCombineXYZ"),
NodeItem("CompositorNodeSwitchView"),
NodeItem("CompositorNodeConvertColorSpace"),
]),

View File

@ -48,7 +48,7 @@ set(SRC_DNA_INC
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpencil_modifier_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpencil_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpu_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_hair_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_curves_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_image_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_ipo_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_key_types.h

View File

@ -65,6 +65,7 @@ else()
)
add_executable(blender-thumbnailer ${SRC} ${SRC_CMD})
setup_platform_linker_flags(blender-thumbnailer)
target_link_libraries(blender-thumbnailer bf_blenlib)
target_link_libraries(blender-thumbnailer ${PTHREADS_LIBRARIES})
endif()

View File

@ -309,7 +309,7 @@ void BLF_thumb_preview(const char *filename,
/* blf_default.c */
void BLF_default_dpi(int dpi);
void BLF_default_size(int size);
void BLF_default_size(float size);
void BLF_default_set(int fontid);
/**
* Get default font ID so we can pass it to other functions.

View File

@ -63,10 +63,6 @@ if(WIN32)
)
endif()
if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
if(WITH_PYTHON)
add_definitions(-DWITH_PYTHON)
list(APPEND INC

View File

@ -37,15 +37,15 @@
/* Default size and dpi, for BLF_draw_default. */
static int global_font_default = -1;
static int global_font_dpi = 72;
/* Keep in sync with `UI_style_get()->widgetlabel.points` */
static int global_font_size = 11;
/* Keep in sync with `UI_DEFAULT_TEXT_POINTS` */
static float global_font_size = 11.0f;
void BLF_default_dpi(int dpi)
{
global_font_dpi = dpi;
}
void BLF_default_size(int size)
void BLF_default_size(float size)
{
global_font_size = size;
}

View File

@ -34,7 +34,6 @@
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include FT_ADVANCES_H /* For FT_Get_Advance */
#include "MEM_guardedalloc.h"
@ -826,7 +825,10 @@ float blf_font_height(FontBLF *font,
float blf_font_fixed_width(FontBLF *font)
{
return (float)font->fixed_width;
GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
float width = (gc) ? (float)gc->fixed_width : font->size / 2.0f;
blf_glyph_cache_release(font);
return width;
}
static void blf_font_boundbox_foreach_glyph_ex(FontBLF *font,
@ -1236,6 +1238,12 @@ FontBLF *blf_font_new(const char *name, const char *filename)
font = (FontBLF *)MEM_callocN(sizeof(FontBLF), "blf_font_new");
err = FT_New_Face(ft_lib, filename, 0, &font->face);
if (err) {
if (ELEM(err, FT_Err_Unknown_File_Format, FT_Err_Unimplemented_Feature)) {
printf("Format of this font file is not supported\n");
}
else {
printf("Error encountered while opening font file\n");
}
MEM_freeN(font);
return NULL;
}
@ -1318,12 +1326,7 @@ FontBLF *blf_font_new_from_mem(const char *name, const unsigned char *mem, int m
void blf_font_free(FontBLF *font)
{
BLI_spin_lock(&blf_glyph_cache_mutex);
GlyphCacheBLF *gc;
while ((gc = BLI_pophead(&font->cache))) {
blf_glyph_cache_free(gc);
}
blf_glyph_cache_clear(font);
if (font->kerning_cache) {
MEM_freeN(font->kerning_cache);
@ -1337,8 +1340,6 @@ void blf_font_free(FontBLF *font)
MEM_freeN(font->name);
}
MEM_freeN(font);
BLI_spin_unlock(&blf_glyph_cache_mutex);
}
/** \} */
@ -1347,51 +1348,25 @@ void blf_font_free(FontBLF *font)
/** \name Font Configure
* \{ */
void blf_font_size(FontBLF *font, float size, unsigned int dpi)
bool blf_font_size(FontBLF *font, float size, unsigned int dpi)
{
blf_glyph_cache_acquire(font);
/* FreeType uses fixed-point integers in 64ths. */
FT_F26Dot6 ft_size = lroundf(size * 64.0f);
/* Adjust our size to be on even 64ths. */
/* Adjust our new size to be on even 64ths. */
size = (float)ft_size / 64.0f;
GlyphCacheBLF *gc = blf_glyph_cache_find(font, size, dpi);
if (gc && (font->size == size && font->dpi == dpi)) {
/* Optimization: do not call FT_Set_Char_Size if size did not change. */
}
else {
const FT_Error err = FT_Set_Char_Size(font->face, 0, ft_size, dpi, dpi);
if (err) {
/* FIXME: here we can go through the fixed size and choice a close one */
printf("The current font don't support the size, %f and dpi, %u\n", size, dpi);
}
else {
if (font->size != size || font->dpi != dpi) {
if (FT_Set_Char_Size(font->face, 0, ft_size, dpi, dpi) == 0) {
font->size = size;
font->dpi = dpi;
if (gc == NULL) {
blf_glyph_cache_new(font);
}
}
else {
printf("The current font does not support the size, %f and dpi, %u\n", size, dpi);
return false;
}
}
blf_glyph_cache_release(font);
/* Set fixed-width size for monospaced output. */
FT_UInt gindex = FT_Get_Char_Index(font->face, U'0');
if (gindex) {
FT_Fixed advance = 0;
FT_Get_Advance(font->face, gindex, FT_LOAD_NO_HINTING, &advance);
/* Use CSS 'ch unit' width, advance of zero character. */
font->fixed_width = (int)(advance >> 16);
}
else {
/* Font does not contain "0" so use CSS fallback of 1/2 of em. */
font->fixed_width = (int)((font->face->size->metrics.height / 2) >> 6);
}
if (font->fixed_width < 1) {
font->fixed_width = 1;
}
return true;
}
/** \} */

View File

@ -34,6 +34,7 @@
#include FT_GLYPH_H
#include FT_OUTLINE_H
#include FT_BITMAP_H
#include FT_ADVANCES_H /* For FT_Get_Advance. */
#include "MEM_guardedalloc.h"
@ -73,7 +74,7 @@ static FT_Fixed to_16dot16(double val)
/** \name Glyph Cache
* \{ */
GlyphCacheBLF *blf_glyph_cache_find(FontBLF *font, float size, unsigned int dpi)
static GlyphCacheBLF *blf_glyph_cache_find(FontBLF *font, float size, unsigned int dpi)
{
GlyphCacheBLF *gc = (GlyphCacheBLF *)font->cache.first;
while (gc) {
@ -86,7 +87,7 @@ GlyphCacheBLF *blf_glyph_cache_find(FontBLF *font, float size, unsigned int dpi)
return NULL;
}
GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font)
static GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font)
{
GlyphCacheBLF *gc = (GlyphCacheBLF *)MEM_callocN(sizeof(GlyphCacheBLF), "blf_glyph_cache_new");
@ -100,6 +101,22 @@ GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font)
memset(gc->glyph_ascii_table, 0, sizeof(gc->glyph_ascii_table));
memset(gc->bucket, 0, sizeof(gc->bucket));
/* Determine ideal fixed-width size for monospaced output. */
FT_UInt gindex = FT_Get_Char_Index(font->face, U'0');
if (gindex) {
FT_Fixed advance = 0;
FT_Get_Advance(font->face, gindex, FT_LOAD_NO_HINTING, &advance);
/* Use CSS 'ch unit' width, advance of zero character. */
gc->fixed_width = (int)(advance >> 16);
}
else {
/* Font does not contain "0" so use CSS fallback of 1/2 of em. */
gc->fixed_width = (int)((font->face->size->metrics.height / 2) >> 6);
}
if (gc->fixed_width < 1) {
gc->fixed_width = 1;
}
BLI_addhead(&font->cache, gc);
return gc;
}
@ -122,20 +139,7 @@ void blf_glyph_cache_release(FontBLF *font)
BLI_spin_unlock(font->glyph_cache_mutex);
}
void blf_glyph_cache_clear(FontBLF *font)
{
GlyphCacheBLF *gc;
BLI_spin_lock(font->glyph_cache_mutex);
while ((gc = BLI_pophead(&font->cache))) {
blf_glyph_cache_free(gc);
}
BLI_spin_unlock(font->glyph_cache_mutex);
}
void blf_glyph_cache_free(GlyphCacheBLF *gc)
static void blf_glyph_cache_free(GlyphCacheBLF *gc)
{
GlyphBLF *g;
for (uint i = 0; i < ARRAY_SIZE(gc->bucket); i++) {
@ -152,6 +156,19 @@ void blf_glyph_cache_free(GlyphCacheBLF *gc)
MEM_freeN(gc);
}
void blf_glyph_cache_clear(FontBLF *font)
{
GlyphCacheBLF *gc;
BLI_spin_lock(font->glyph_cache_mutex);
while ((gc = BLI_pophead(&font->cache))) {
blf_glyph_cache_free(gc);
}
BLI_spin_unlock(font->glyph_cache_mutex);
}
/**
* Try to find a glyph in cache.
*

View File

@ -56,7 +56,11 @@ struct FontBLF *blf_font_new(const char *name, const char *filename);
struct FontBLF *blf_font_new_from_mem(const char *name, const unsigned char *mem, int mem_size);
void blf_font_attach_from_mem(struct FontBLF *font, const unsigned char *mem, int mem_size);
void blf_font_size(struct FontBLF *font, float size, unsigned int dpi);
/**
* Change font's output size. Returns true if successful in changing the size.
*/
bool blf_font_size(struct FontBLF *font, float size, unsigned int dpi);
void blf_font_draw(struct FontBLF *font,
const char *str,
size_t str_len,
@ -65,10 +69,7 @@ void blf_font_draw__wrap(struct FontBLF *font,
const char *str,
size_t str_len,
struct ResultBLF *r_info);
void blf_font_draw_ascii(struct FontBLF *font,
const char *str,
size_t str_len,
struct ResultBLF *r_info);
/**
* Use fixed column width, but an utf8 character may occupy multiple columns.
*/
@ -137,18 +138,9 @@ int blf_font_count_missing_chars(struct FontBLF *font,
void blf_font_free(struct FontBLF *font);
/**
* Find a glyph cache that matches a size, DPI & styles.
*/
struct GlyphCacheBLF *blf_glyph_cache_find(struct FontBLF *font, float size, unsigned int dpi);
/**
* Create a new glyph cache for the current size, DPI & styles.
*/
struct GlyphCacheBLF *blf_glyph_cache_new(struct FontBLF *font);
struct GlyphCacheBLF *blf_glyph_cache_acquire(struct FontBLF *font);
void blf_glyph_cache_release(struct FontBLF *font);
void blf_glyph_cache_clear(struct FontBLF *font);
void blf_glyph_cache_free(struct GlyphCacheBLF *gc);
/**
* Create (or load from cache) a fully-rendered bitmap glyph.

View File

@ -73,6 +73,9 @@ typedef struct GlyphCacheBLF {
bool bold;
bool italic;
/* Column width when printing monospaced. */
int fixed_width;
/* and the glyphs. */
ListBase bucket[257];
@ -207,9 +210,6 @@ typedef struct FontBLF {
/* font size. */
float size;
/* Column width when printing monospaced. */
int fixed_width;
/* max texture size. */
int tex_size_max;

View File

@ -61,7 +61,6 @@ void BLF_thumb_preview(const char *filename,
int font_shrink = 4;
FontBLF *font;
GlyphCacheBLF *gc;
/* Create a new blender font obj and fill it with default values */
font = blf_font_new("thumb_font", filename);
@ -90,10 +89,8 @@ void BLF_thumb_preview(const char *filename,
const size_t draw_str_i18n_len = strlen(draw_str_i18n);
int draw_str_i18n_nbr = 0;
blf_font_size(font, (float)MAX2(font_size_min, font_size_curr), dpi);
gc = blf_glyph_cache_find(font, font->size, font->dpi);
/* There will be no matching glyph cache if blf_font_size() failed to set font size. */
if (!gc) {
CLAMP_MIN(font_size_curr, font_size_min);
if (!blf_font_size(font, (float)font_size_curr, dpi)) {
break;
}

View File

@ -104,14 +104,6 @@ typedef enum DerivedMeshType {
DM_TYPE_CCGDM,
} DerivedMeshType;
typedef enum DMDirtyFlag {
/* dm has valid tessellated faces, but tessellated CDDATA need to be updated. */
DM_DIRTY_TESS_CDLAYERS = 1 << 0,
/* check this with modifier dependsOnNormals callback to see if normals need recalculation */
DM_DIRTY_NORMALS = 1 << 1,
} DMDirtyFlag;
typedef struct DerivedMesh DerivedMesh;
struct DerivedMesh {
/** Private DerivedMesh data, only for internal DerivedMesh use */
@ -120,7 +112,6 @@ struct DerivedMesh {
int needsFree; /* checked on ->release, is set to 0 for cached results */
int deformedOnly; /* set by modifier stack if only deformed from original */
DerivedMeshType type;
DMDirtyFlag dirty;
/**
* \warning Typical access is done via #getLoopTriArray, #getNumLoopTri.
@ -139,9 +130,6 @@ struct DerivedMesh {
short tangent_mask; /* which tangent layers are calculated */
/** Calculate vert and face normals */
void (*calcNormals)(DerivedMesh *dm);
/** Loop tessellation cache (WARNING! Only call inside threading-protected code!) */
void (*recalcLoopTri)(DerivedMesh *dm);
/** accessor functions */
@ -164,7 +152,6 @@ struct DerivedMesh {
*/
struct MVert *(*getVertArray)(DerivedMesh *dm);
struct MEdge *(*getEdgeArray)(DerivedMesh *dm);
struct MFace *(*getTessFaceArray)(DerivedMesh *dm);
struct MLoop *(*getLoopArray)(DerivedMesh *dm);
struct MPoly *(*getPolyArray)(DerivedMesh *dm);
@ -173,7 +160,6 @@ struct DerivedMesh {
*/
void (*copyVertArray)(DerivedMesh *dm, struct MVert *r_vert);
void (*copyEdgeArray)(DerivedMesh *dm, struct MEdge *r_edge);
void (*copyTessFaceArray)(DerivedMesh *dm, struct MFace *r_face);
void (*copyLoopArray)(DerivedMesh *dm, struct MLoop *r_loop);
void (*copyPolyArray)(DerivedMesh *dm, struct MPoly *r_poly);
@ -182,37 +168,18 @@ struct DerivedMesh {
*/
struct MVert *(*dupVertArray)(DerivedMesh *dm);
struct MEdge *(*dupEdgeArray)(DerivedMesh *dm);
struct MFace *(*dupTessFaceArray)(DerivedMesh *dm);
struct MLoop *(*dupLoopArray)(DerivedMesh *dm);
struct MPoly *(*dupPolyArray)(DerivedMesh *dm);
/** Return a pointer to a single element of vert/edge/face custom data
* from the derived mesh (this gives a pointer to the actual data, not
* a copy)
*/
void *(*getVertData)(DerivedMesh *dm, int index, int type);
void *(*getEdgeData)(DerivedMesh *dm, int index, int type);
void *(*getTessFaceData)(DerivedMesh *dm, int index, int type);
void *(*getPolyData)(DerivedMesh *dm, int index, int type);
/** Return a pointer to the entire array of vert/edge/face custom data
* from the derived mesh (this gives a pointer to the actual data, not
* a copy)
*/
void *(*getVertDataArray)(DerivedMesh *dm, int type);
void *(*getEdgeDataArray)(DerivedMesh *dm, int type);
void *(*getTessFaceDataArray)(DerivedMesh *dm, int type);
void *(*getLoopDataArray)(DerivedMesh *dm, int type);
void *(*getPolyDataArray)(DerivedMesh *dm, int type);
/** Retrieves the base CustomData structures for
* verts/edges/tessfaces/loops/faces. */
CustomData *(*getVertDataLayout)(DerivedMesh *dm);
CustomData *(*getEdgeDataLayout)(DerivedMesh *dm);
CustomData *(*getTessFaceDataLayout)(DerivedMesh *dm);
CustomData *(*getLoopDataLayout)(DerivedMesh *dm);
CustomData *(*getPolyDataLayout)(DerivedMesh *dm);
/** Optional grid access for subsurf */
int (*getNumGrids)(DerivedMesh *dm);
int (*getGridSize)(DerivedMesh *dm);
@ -231,11 +198,6 @@ struct DerivedMesh {
/** Get smooth vertex normal, undefined if index is not valid */
void (*getVertNo)(DerivedMesh *dm, int index, float r_no[3]);
void (*getPolyNo)(DerivedMesh *dm, int index, float r_no[3]);
/** Get a map of vertices to faces
*/
const struct MeshElemMap *(*getPolyMap)(struct Object *ob, DerivedMesh *dm);
/** Release reference to the DerivedMesh. This function decides internally
* if the DerivedMesh will be freed, or cached for later use. */
@ -265,15 +227,6 @@ void DM_init(DerivedMesh *dm,
* Utility function to initialize a DerivedMesh for the desired number
* of vertices, edges and faces, with a layer setup copied from source
*/
void DM_from_template_ex(DerivedMesh *dm,
DerivedMesh *source,
DerivedMeshType type,
int numVerts,
int numEdges,
int numTessFaces,
int numLoops,
int numPolys,
const struct CustomData_MeshMasks *mask);
void DM_from_template(DerivedMesh *dm,
DerivedMesh *source,
DerivedMeshType type,
@ -303,25 +256,8 @@ void DM_set_only_copy(DerivedMesh *dm, const struct CustomData_MeshMasks *mask);
void DM_add_vert_layer(struct DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer);
void DM_add_edge_layer(struct DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer);
void DM_add_tessface_layer(struct DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer);
void DM_add_loop_layer(DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer);
void DM_add_poly_layer(struct DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer);
/* -------------------------------------------------------------------- */
/** \name Custom Data Access Functions
*
* \return pointer to data from first layer which matches type
* if they return NULL for valid indices, data doesn't exist.
* \note these return pointers - any change modifies the internals of the mesh.
* \{ */
void *DM_get_vert_data(struct DerivedMesh *dm, int index, int type);
void *DM_get_edge_data(struct DerivedMesh *dm, int index, int type);
void *DM_get_tessface_data(struct DerivedMesh *dm, int index, int type);
void *DM_get_poly_data(struct DerivedMesh *dm, int index, int type);
/** \} */
/* -------------------------------------------------------------------- */
/** \name Custom Data Layer Access Functions
*
@ -332,7 +268,6 @@ void *DM_get_poly_data(struct DerivedMesh *dm, int index, int type);
void *DM_get_vert_data_layer(struct DerivedMesh *dm, int type);
void *DM_get_edge_data_layer(struct DerivedMesh *dm, int type);
void *DM_get_tessface_data_layer(struct DerivedMesh *dm, int type);
void *DM_get_poly_data_layer(struct DerivedMesh *dm, int type);
void *DM_get_loop_data_layer(struct DerivedMesh *dm, int type);
@ -354,8 +289,6 @@ void DM_copy_vert_data(struct DerivedMesh *source,
*/
void DM_DupPolys(DerivedMesh *source, DerivedMesh *target);
void DM_ensure_normals(DerivedMesh *dm);
/**
* Ensure the array is large enough.
*
@ -401,11 +334,6 @@ void makeDerivedMesh(struct Depsgraph *depsgraph,
struct Object *ob,
const struct CustomData_MeshMasks *dataMask);
void DM_calc_loop_tangents(DerivedMesh *dm,
bool calc_active_tangent,
const char (*tangent_names)[MAX_NAME],
int tangent_names_len);
#ifdef __cplusplus
}
#endif

View File

@ -365,7 +365,6 @@ void what_does_obaction(struct Object *ob,
char groupname[],
const struct AnimationEvalContext *anim_eval_context);
/* for proxy */
void BKE_pose_copy_pchan_result(struct bPoseChannel *pchanto,
const struct bPoseChannel *pchanfrom);
/**

View File

@ -163,6 +163,30 @@ void BKE_armature_transform(struct bArmature *arm, const float mat[4][4], bool d
/* Bounding box. */
struct BoundBox *BKE_armature_boundbox_get(struct Object *ob);
/**
* Calculate the axis-aligned bounds of `pchan` in world-space,
* taking into account custom transform when set.
*
* `r_min` and `r_max` are expanded to fit `pchan` so the caller must initialize them
* (typically using #INIT_MINMAX).
*
* \note The bounds are calculated based on the head & tail of the bone
* or the custom object's bounds (if the bone uses a custom object).
* Visual elements such as the envelopes radius & bendy-bone spline segments are *not* included,
* making this not so useful for viewport culling.
*/
void BKE_pchan_minmax(const struct Object *ob,
const struct bPoseChannel *pchan,
float r_min[3],
float r_max[3]);
/**
* Calculate the axis aligned bounds of the pose of `ob` in world-space.
* `r_min` and `r_max` are expanded to fit `ob->pose` so the caller must initialize them
* (typically using #INIT_MINMAX).
*
* \note This uses #BKE_pchan_minmax, see its documentation for details on bounds calculation.
*/
bool BKE_pose_minmax(
struct Object *ob, float r_min[3], float r_max[3], bool use_hidden, bool use_select);
@ -619,14 +643,6 @@ void BKE_pose_eval_cleanup(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *object);
void BKE_pose_eval_proxy_init(struct Depsgraph *depsgraph, struct Object *object);
void BKE_pose_eval_proxy_done(struct Depsgraph *depsgraph, struct Object *object);
void BKE_pose_eval_proxy_cleanup(struct Depsgraph *depsgraph, struct Object *object);
void BKE_pose_eval_proxy_copy_bone(struct Depsgraph *depsgraph,
struct Object *object,
int pchan_index);
/* -------------------------------------------------------------------- */
/** \name Deform 3D Coordinates by Armature (armature_deform.c)
* \{ */

View File

@ -41,11 +41,11 @@ struct AttributeRef;
/* Attribute.domain */
typedef enum AttributeDomain {
ATTR_DOMAIN_AUTO = -1, /* Use for nodes to choose automatically based on other data. */
ATTR_DOMAIN_POINT = 0, /* Mesh, Hair or PointCloud Point */
ATTR_DOMAIN_POINT = 0, /* Mesh, Curve or Point Cloud Point */
ATTR_DOMAIN_EDGE = 1, /* Mesh Edge */
ATTR_DOMAIN_FACE = 2, /* Mesh Face */
ATTR_DOMAIN_CORNER = 3, /* Mesh Corner */
ATTR_DOMAIN_CURVE = 4, /* Hair Curve */
ATTR_DOMAIN_CURVE = 4, /* A single curve in a larger curve data-block */
ATTR_DOMAIN_INSTANCE = 5, /* Instance */
ATTR_DOMAIN_NUM

View File

@ -50,6 +50,9 @@ inline void convert_to_static_type(const CustomDataType data_type, const Func &f
case CD_PROP_BOOL:
func(bool());
break;
case CD_PROP_INT8:
func(int8_t());
break;
case CD_PROP_COLOR:
func(ColorGeometry4f());
break;
@ -77,6 +80,9 @@ inline void convert_to_static_type(const fn::CPPType &cpp_type, const Func &func
else if (cpp_type.is<bool>()) {
func(bool());
}
else if (cpp_type.is<int8_t>()) {
func(int8_t());
}
else if (cpp_type.is<ColorGeometry4f>()) {
func(ColorGeometry4f());
}
@ -93,6 +99,12 @@ inline void convert_to_static_type(const fn::CPPType &cpp_type, const Func &func
template<typename T> T mix3(const float3 &weights, const T &v0, const T &v1, const T &v2);
template<>
inline int8_t mix3(const float3 &weights, const int8_t &v0, const int8_t &v1, const int8_t &v2)
{
return static_cast<int8_t>(weights.x * v0 + weights.y * v1 + weights.z * v2);
}
template<> inline bool mix3(const float3 &weights, const bool &v0, const bool &v1, const bool &v2)
{
return (weights.x * v0 + weights.y * v1 + weights.z * v2) >= 0.5f;
@ -147,6 +159,11 @@ template<> inline bool mix2(const float factor, const bool &a, const bool &b)
return ((1.0f - factor) * a + factor * b) >= 0.5f;
}
template<> inline int8_t mix2(const float factor, const int8_t &a, const int8_t &b)
{
return static_cast<int8_t>((1.0f - factor) * a + factor * b);
}
template<> inline int mix2(const float factor, const int &a, const int &b)
{
return static_cast<int>((1.0f - factor) * a + factor * b);
@ -364,6 +381,15 @@ template<> struct DefaultMixerStruct<bool> {
using type = SimpleMixerWithAccumulationType<bool, float, float_to_bool>;
};
template<> struct DefaultMixerStruct<int8_t> {
static int8_t float_to_int8_t(const float &value)
{
return static_cast<int8_t>(value);
}
/* Store interpolated 8 bit integers in a float temporarily to increase accuracy. */
using type = SimpleMixerWithAccumulationType<int8_t, float, float_to_int8_t>;
};
template<typename T> struct DefaultPropatationMixerStruct {
/* Use void by default. This can be checked for in `if constexpr` statements. */
using type = typename DefaultMixerStruct<T>::type;

View File

@ -39,7 +39,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 0
#define BLENDER_FILE_SUBVERSION 3
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file

View File

@ -123,11 +123,20 @@ struct Collection *BKE_collection_object_find(struct Main *bmain,
bool BKE_collection_is_empty(const struct Collection *collection);
/**
* Add object to collection
* Add object to given collection, ensuring this collection is 'editable' (i.e. local and not a
* liboverride), and finding a suitable parent one otherwise.
*/
bool BKE_collection_object_add(struct Main *bmain,
struct Collection *collection,
struct Object *ob);
/**
* Same as #BKE_collection_object_add, but unconditionally adds the object to the given collection.
*
* NOTE: required in certain cases, like do-versioning or complex ID management tasks.
*/
bool BKE_collection_object_add_notest(struct Main *bmain,
struct Collection *collection,
struct Object *ob);
/**
* Add \a ob_dst to all scene collections that reference object \a ob_src is in.
* Used for copying objects.

View File

@ -278,18 +278,6 @@ bool BKE_constraint_apply_and_remove_for_pose(struct Depsgraph *depsgraph,
void BKE_constraint_panel_expand(struct bConstraint *con);
/* Constraints + Proxies function prototypes */
/**
* Rescue all constraints tagged as being #CONSTRAINT_PROXY_LOCAL
* (i.e. added to bone that's proxy-synced in this file).
*/
void BKE_constraints_proxylocal_extract(struct ListBase *dst, struct ListBase *src);
/**
* Returns if the owner of the constraint is proxy-protected.
*/
bool BKE_constraints_proxylocked_owner(struct Object *ob, struct bPoseChannel *pchan);
/* Constraint Evaluation function prototypes */
/**

View File

@ -0,0 +1,68 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#pragma once
/** \file
* \ingroup bke
* \brief Low-level operations for curves.
*/
#ifdef __cplusplus
extern "C" {
#endif
struct BoundBox;
struct CustomDataLayer;
struct Depsgraph;
struct Curves;
struct Main;
struct Object;
struct Scene;
void *BKE_curves_add(struct Main *bmain, const char *name);
struct BoundBox *BKE_curves_boundbox_get(struct Object *ob);
void BKE_curves_update_customdata_pointers(struct Curves *curves);
bool BKE_curves_customdata_required(struct Curves *curves, struct CustomDataLayer *layer);
/* Depsgraph */
struct Curves *BKE_curves_new_for_eval(const struct Curves *curves_src,
int totpoint,
int totcurve);
struct Curves *BKE_curves_copy_for_eval(struct Curves *curves_src, bool reference);
void BKE_curves_data_update(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *object);
/* Draw Cache */
enum {
BKE_CURVES_BATCH_DIRTY_ALL = 0,
};
void BKE_curves_batch_cache_dirty_tag(struct Curves *curves, int mode);
void BKE_curves_batch_cache_free(struct Curves *curves);
extern void (*BKE_curves_batch_cache_dirty_tag_cb)(struct Curves *curves, int mode);
extern void (*BKE_curves_batch_cache_free_cb)(struct Curves *curves);
#ifdef __cplusplus
}
#endif

View File

@ -259,6 +259,11 @@ bool CustomData_free_layer_active(struct CustomData *data, int type, int totelem
*/
void CustomData_free_layers(struct CustomData *data, int type, int totelem);
/**
* Free all anonymous attributes.
*/
void CustomData_free_layers_anonymous(struct CustomData *data, int totelem);
/**
* Returns true if a layer with the specified type exists.
*/

View File

@ -1,63 +0,0 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#pragma once
/** \file
* \ingroup bke
* \brief General operations for hairs.
*/
#ifdef __cplusplus
extern "C" {
#endif
struct BoundBox;
struct CustomDataLayer;
struct Depsgraph;
struct Hair;
struct Main;
struct Object;
struct Scene;
void *BKE_hair_add(struct Main *bmain, const char *name);
struct BoundBox *BKE_hair_boundbox_get(struct Object *ob);
void BKE_hair_update_customdata_pointers(struct Hair *hair);
bool BKE_hair_customdata_required(struct Hair *hair, struct CustomDataLayer *layer);
/* Depsgraph */
struct Hair *BKE_hair_new_for_eval(const struct Hair *hair_src, int totpoint, int totcurve);
struct Hair *BKE_hair_copy_for_eval(struct Hair *hair_src, bool reference);
void BKE_hair_data_update(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *object);
/* Draw Cache */
enum {
BKE_HAIR_BATCH_DIRTY_ALL = 0,
};
void BKE_hair_batch_cache_dirty_tag(struct Hair *hair, int mode);
void BKE_hair_batch_cache_free(struct Hair *hair);
extern void (*BKE_hair_batch_cache_dirty_tag_cb)(struct Hair *hair, int mode);
extern void (*BKE_hair_batch_cache_free_cb)(struct Hair *hair);
#ifdef __cplusplus
}
#endif

View File

@ -278,7 +278,7 @@ extern IDTypeInfo IDType_ID_PC;
extern IDTypeInfo IDType_ID_CF;
extern IDTypeInfo IDType_ID_WS;
extern IDTypeInfo IDType_ID_LP;
extern IDTypeInfo IDType_ID_HA;
extern IDTypeInfo IDType_ID_CV;
extern IDTypeInfo IDType_ID_PT;
extern IDTypeInfo IDType_ID_VO;
extern IDTypeInfo IDType_ID_SIM;

View File

@ -23,8 +23,8 @@
* image that are changed. These areas are organized in chunks. Changes that happen over time are
* organized in changesets.
*
* A common usecase is to update GPUTexture for drawing where only that part is uploaded that only
* changed.
* A common use case is to update #GPUTexture for drawing where only that part is uploaded that
* only changed.
*/
#pragma once

View File

@ -376,10 +376,6 @@ enum {
/** Clear asset data (in case the ID can actually be made local, in copy case asset data is never
* copied over). */
LIB_ID_MAKELOCAL_ASSET_DATA_CLEAR = 1 << 3,
/* Special type-specific options. */
/** For Objects, do not clear the proxy pointers while making the data-block local. */
LIB_ID_MAKELOCAL_OBJECT_NO_PROXY_CLEARING = 1 << 16,
};
/**

View File

@ -100,6 +100,9 @@ struct ID *BKE_lib_override_library_create_from_id(struct Main *bmain,
* main. You can add more local IDs to be remapped to use new overriding ones by setting their
* LIB_TAG_DOIT tag.
*
* \param owner_library: the library in which the overrides should be created. Besides versioning
* and resync code path, this should always be NULL (i.e. the local .blend file).
*
* \param reference_library: the library from which the linked data being overridden come from
* (i.e. the library of the linked reference ID).
*
@ -109,7 +112,8 @@ struct ID *BKE_lib_override_library_create_from_id(struct Main *bmain,
* \return \a true on success, \a false otherwise.
*/
bool BKE_lib_override_library_create_from_tag(struct Main *bmain,
const struct Library *reference_library,
struct Library *owner_library,
const struct ID *id_root_reference,
bool do_no_main);
/**
* Advanced 'smart' function to create fully functional overrides.
@ -122,16 +126,24 @@ bool BKE_lib_override_library_create_from_tag(struct Main *bmain,
*
* \param view_layer: the active view layer to search instantiated collections in, can be NULL (in
* which case \a scene's master collection children hierarchy is used instead).
*
* \param owner_library: the library in which the overrides should be created. Besides versioning
* and resync code path, this should always be NULL (i.e. the local .blend file).
*
* \param id_root: The root ID to create an override from.
*
* \param id_reference: Some reference ID used to do some post-processing after overrides have been
* created, may be NULL. Typically, the Empty object instantiating the linked collection we
* override, currently.
*
* \param r_id_root_override: if not NULL, the override generated for the given \a id_root.
*
* \return true if override was successfully created.
*/
bool BKE_lib_override_library_create(struct Main *bmain,
struct Scene *scene,
struct ViewLayer *view_layer,
struct Library *owner_library,
struct ID *id_root,
struct ID *id_reference,
struct ID **r_id_root_override);
@ -160,6 +172,15 @@ bool BKE_lib_override_library_proxy_convert(struct Main *bmain,
*/
void BKE_lib_override_library_main_proxy_convert(struct Main *bmain,
struct BlendFileReadReport *reports);
/**
* Find and set the 'hierarchy root' ID pointer of all library overrides in given `bmain`.
*
* NOTE: Cannot be called from `do_versions_after_linking` as this code needs a single complete
* Main database, not a split-by-libraries one.
*/
void BKE_lib_override_library_main_hierarchy_root_ensure(struct Main *bmain);
/**
* Advanced 'smart' function to resync, re-create fully functional overrides up-to-date with linked
* data, from an existing override hierarchy.

View File

@ -63,7 +63,7 @@ enum {
/**
* That ID is not really used by its owner, it's just an internal hint/helper.
* This addresses Their Highest Ugliness the 'from' pointers: Object->from_proxy and Key->from.
* This marks the 'from' pointers issue, like Key->from.
* How to handle that kind of cases totally depends on what caller code is doing... */
IDWALK_CB_LOOPBACK = (1 << 4),
@ -135,7 +135,6 @@ enum {
/** Do not process ID pointers inside embedded IDs. Needed by depsgraph processing e.g. */
IDWALK_IGNORE_EMBEDDED_ID = (1 << 3),
IDWALK_NO_INDIRECT_PROXY_DATA_USAGE = (1 << 8), /* Ugly special case :(((( */
/** Also process internal ID pointers like `ID.newid` or `ID.orig_id`.
* WARNING: Dangerous, use with caution. */
IDWALK_DO_INTERNAL_RUNTIME_POINTERS = (1 << 9),

View File

@ -68,15 +68,6 @@ enum {
* and can cause crashes very easily!
*/
ID_REMAP_FORCE_NEVER_NULL_USAGE = 1 << 3,
/**
* Do not consider proxy/_group pointers of local objects as indirect usages...
* Our oh-so-beloved proxies again...
* Do not consider data used by local proxy object as indirect usage.
* This is needed e.g. in reload scenario,
* since we have to ensure remapping of Armature data of local proxy
* is also performed. Usual nightmare...
*/
ID_REMAP_NO_INDIRECT_PROXY_DATA_USAGE = 1 << 4,
/** Do not remap library override pointers. */
ID_REMAP_SKIP_OVERRIDE_LIBRARY = 1 << 5,
/** Don't touch the user count (use for low level actions such as swapping pointers). */

View File

@ -182,7 +182,11 @@ typedef struct Main {
ListBase linestyles;
ListBase cachefiles;
ListBase workspaces;
ListBase hairs;
/**
* \note The name `hair_curves` is chosen to be different than `curves`,
* but they are generic curve data-blocks, not just for hair.
*/
ListBase hair_curves;
ListBase pointclouds;
ListBase volumes;
ListBase simulations;

View File

@ -245,10 +245,6 @@ typedef struct ModifierTypeInfo {
const struct ModifierEvalContext *ctx,
struct Mesh *mesh);
struct Hair *(*modifyHair)(struct ModifierData *md,
const struct ModifierEvalContext *ctx,
struct Hair *hair);
/**
* The modifier has to change the geometry set in-place. The geometry set can contain zero or
* more geometry components. This callback can be used by modifiers that don't work on any
@ -470,6 +466,8 @@ void BKE_modifiers_foreach_tex_link(struct Object *ob, TexWalkFunc walk, void *u
struct ModifierData *BKE_modifiers_findby_type(const struct Object *ob, ModifierType type);
struct ModifierData *BKE_modifiers_findby_name(const struct Object *ob, const char *name);
struct ModifierData *BKE_modifiers_findby_session_uuid(const struct Object *ob,
const SessionUUID *session_uuid);
void BKE_modifiers_clear_errors(struct Object *ob);
/**
* used for buttons, to find out if the 'draw deformed in edit-mode option is there.
@ -568,7 +566,8 @@ const char *BKE_modifier_path_relbase_from_global(struct Object *ob);
* For a given modifier data, get corresponding original one.
* If the modifier data is already original, return it as-is.
*/
struct ModifierData *BKE_modifier_get_original(struct ModifierData *md);
struct ModifierData *BKE_modifier_get_original(const struct Object *object,
struct ModifierData *md);
struct ModifierData *BKE_modifier_get_evaluated(struct Depsgraph *depsgraph,
struct Object *object,
struct ModifierData *md);

View File

@ -274,6 +274,9 @@ typedef struct bNodeType {
char *label,
int maxlen);
/** Optional override for node class, used for drawing node header. */
int (*ui_class)(const struct bNode *node);
/** Called when the node is updated in the editor. */
void (*updatefunc)(struct bNodeTree *ntree, struct bNode *node);
/** Check and update if internal ID data has changed. */
@ -1291,6 +1294,8 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
#define CMP_NODE_POSTERIZE 327
#define CMP_NODE_CONVERT_COLOR_SPACE 328
#define CMP_NODE_SCENE_TIME 329
#define CMP_NODE_SEPARATE_XYZ 330
#define CMP_NODE_COMBINE_XYZ 331
/* channel toggles */
#define CMP_CHAN_RGB 1

View File

@ -146,18 +146,6 @@ void BKE_object_link_modifiers(struct Object *ob_dst, const struct Object *ob_sr
void BKE_object_free_modifiers(struct Object *ob, int flag);
void BKE_object_free_shaderfx(struct Object *ob, int flag);
/**
* Proxy rule:
* - `lib_object->proxy_from` == the one we borrow from, set temporally while object_update.
* - `local_object->proxy` == pointer to library object, saved in files and read.
* - `local_object->proxy_group` == pointer to collection dupli-object, saved in files and read.
*/
void BKE_object_make_proxy(struct Main *bmain,
struct Object *ob,
struct Object *target,
struct Object *cob);
void BKE_object_copy_proxy_drivers(struct Object *ob, struct Object *target);
bool BKE_object_exists_check(struct Main *bmain, const struct Object *obtest);
/**
* Actual check for internal data, not context or flags.
@ -446,7 +434,6 @@ void BKE_object_eval_constraints(struct Depsgraph *depsgraph,
struct Object *ob);
void BKE_object_eval_transform_final(struct Depsgraph *depsgraph, struct Object *ob);
bool BKE_object_eval_proxy_copy(struct Depsgraph *depsgraph, struct Object *object);
void BKE_object_eval_uber_transform(struct Depsgraph *depsgraph, struct Object *ob);
void BKE_object_eval_uber_data(struct Depsgraph *depsgraph,
struct Scene *scene,
@ -488,12 +475,6 @@ void BKE_object_handle_data_update(struct Depsgraph *depsgraph,
*/
void BKE_object_handle_update(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob);
/**
* Proxy rule:
* - lib_object->proxy_from == the one we borrow from, only set temporal and cleared here.
* - local_object->proxy == pointer to library object, saved in files and read.
*
* Function below is polluted with proxy exceptions, cleanup will follow!
*
* The main object update call, for object matrix, constraints, keys and #DispList (modifiers)
* requires flags to be set!
*
@ -503,8 +484,7 @@ void BKE_object_handle_update(struct Depsgraph *depsgraph, struct Scene *scene,
void BKE_object_handle_update_ex(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *ob,
struct RigidBodyWorld *rbw,
bool do_proxy_update);
struct RigidBodyWorld *rbw);
void BKE_object_sculpt_data_create(struct Object *ob);

View File

@ -710,10 +710,11 @@ typedef struct SculptSession {
/* These are always assigned to base mesh data when using PBVH_FACES and PBVH_GRIDS. */
struct MVert *mvert;
struct MEdge *medge;
const float (*vert_normals)[3];
struct MLoop *mloop;
struct MPoly *mpoly;
const float (*vert_normals)[3];
// only assigned in PBVH_FACES and PBVH_GRIDS
CustomData *vdata, *edata, *ldata, *pdata;

View File

@ -127,6 +127,7 @@ set(SRC
intern/crazyspace.c
intern/cryptomatte.cc
intern/curve.cc
intern/curves.cc
intern/curve_bevel.c
intern/curve_convert.c
intern/curve_decimate.c
@ -166,7 +167,6 @@ set(SRC
intern/gpencil_curve.c
intern/gpencil_geom.cc
intern/gpencil_modifier.c
intern/hair.cc
intern/icons.cc
intern/icons_rasterize.c
intern/idprop.c
@ -192,6 +192,7 @@ set(SRC
intern/lib_id_eval.c
intern/lib_id_remapper.cc
intern/lib_override.c
intern/lib_override_proxy_conversion.c
intern/lib_query.c
intern/lib_remap.c
intern/library.c
@ -367,6 +368,7 @@ set(SRC
BKE_cryptomatte.h
BKE_cryptomatte.hh
BKE_curve.h
BKE_curves.h
BKE_curve_to_mesh.hh
BKE_curveprofile.h
BKE_customdata.h
@ -396,7 +398,6 @@ set(SRC
BKE_gpencil_curve.h
BKE_gpencil_geom.h
BKE_gpencil_modifier.h
BKE_hair.h
BKE_icons.h
BKE_idprop.h
BKE_idprop.hh
@ -735,10 +736,6 @@ if(WITH_FFTW3)
add_definitions(-DFFTW3=1)
endif()
if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
if(WITH_FREESTYLE)
add_definitions(-DWITH_FREESTYLE)
endif()

View File

@ -127,30 +127,6 @@ static MEdge *dm_getEdgeArray(DerivedMesh *dm)
return medge;
}
static MFace *dm_getTessFaceArray(DerivedMesh *dm)
{
MFace *mface = (MFace *)CustomData_get_layer(&dm->faceData, CD_MFACE);
if (!mface) {
int numTessFaces = dm->getNumTessFaces(dm);
if (!numTessFaces) {
/* Do not add layer if there's no elements in it, this leads to issues later when
* this layer is needed with non-zero size, but currently CD stuff does not check
* for requested layer size on creation and just returns layer which was previously
* added (sergey) */
return nullptr;
}
mface = (MFace *)CustomData_add_layer(
&dm->faceData, CD_MFACE, CD_CALLOC, nullptr, numTessFaces);
CustomData_set_layer_flag(&dm->faceData, CD_MFACE, CD_FLAG_TEMPORARY);
dm->copyTessFaceArray(dm, mface);
}
return mface;
}
static MLoop *dm_getLoopArray(DerivedMesh *dm)
{
MLoop *mloop = (MLoop *)CustomData_get_layer(&dm->loopData, CD_MLOOP);
@ -203,18 +179,6 @@ static MEdge *dm_dupEdgeArray(DerivedMesh *dm)
return tmp;
}
static MFace *dm_dupFaceArray(DerivedMesh *dm)
{
MFace *tmp = (MFace *)MEM_malloc_arrayN(
dm->getNumTessFaces(dm), sizeof(*tmp), "dm_dupFaceArray tmp");
if (tmp) {
dm->copyTessFaceArray(dm, tmp);
}
return tmp;
}
static MLoop *dm_dupLoopArray(DerivedMesh *dm)
{
MLoop *tmp = (MLoop *)MEM_malloc_arrayN(
@ -270,42 +234,15 @@ static const MLoopTri *dm_getLoopTriArray(DerivedMesh *dm)
return looptri;
}
static CustomData *dm_getVertCData(DerivedMesh *dm)
{
return &dm->vertData;
}
static CustomData *dm_getEdgeCData(DerivedMesh *dm)
{
return &dm->edgeData;
}
static CustomData *dm_getTessFaceCData(DerivedMesh *dm)
{
return &dm->faceData;
}
static CustomData *dm_getLoopCData(DerivedMesh *dm)
{
return &dm->loopData;
}
static CustomData *dm_getPolyCData(DerivedMesh *dm)
{
return &dm->polyData;
}
void DM_init_funcs(DerivedMesh *dm)
{
/* default function implementations */
dm->getVertArray = dm_getVertArray;
dm->getEdgeArray = dm_getEdgeArray;
dm->getTessFaceArray = dm_getTessFaceArray;
dm->getLoopArray = dm_getLoopArray;
dm->getPolyArray = dm_getPolyArray;
dm->dupVertArray = dm_dupVertArray;
dm->dupEdgeArray = dm_dupEdgeArray;
dm->dupTessFaceArray = dm_dupFaceArray;
dm->dupLoopArray = dm_dupLoopArray;
dm->dupPolyArray = dm_dupPolyArray;
@ -314,19 +251,8 @@ void DM_init_funcs(DerivedMesh *dm)
/* subtypes handle getting actual data */
dm->getNumLoopTri = dm_getNumLoopTri;
dm->getVertDataLayout = dm_getVertCData;
dm->getEdgeDataLayout = dm_getEdgeCData;
dm->getTessFaceDataLayout = dm_getTessFaceCData;
dm->getLoopDataLayout = dm_getLoopCData;
dm->getPolyDataLayout = dm_getPolyCData;
dm->getVertData = DM_get_vert_data;
dm->getEdgeData = DM_get_edge_data;
dm->getTessFaceData = DM_get_tessface_data;
dm->getPolyData = DM_get_poly_data;
dm->getVertDataArray = DM_get_vert_data_layer;
dm->getEdgeDataArray = DM_get_edge_data_layer;
dm->getTessFaceDataArray = DM_get_tessface_data_layer;
dm->getPolyDataArray = DM_get_poly_data_layer;
dm->getLoopDataArray = DM_get_loop_data_layer;
}
@ -349,7 +275,6 @@ void DM_init(DerivedMesh *dm,
DM_init_funcs(dm);
dm->needsFree = 1;
dm->dirty = (DMDirtyFlag)0;
/* Don't use #CustomData_reset because we don't want to touch custom-data. */
copy_vn_i(dm->vertData.typemap, CD_NUMTYPES, -1);
@ -359,16 +284,16 @@ void DM_init(DerivedMesh *dm,
copy_vn_i(dm->polyData.typemap, CD_NUMTYPES, -1);
}
void DM_from_template_ex(DerivedMesh *dm,
DerivedMesh *source,
DerivedMeshType type,
int numVerts,
int numEdges,
int numTessFaces,
int numLoops,
int numPolys,
const CustomData_MeshMasks *mask)
void DM_from_template(DerivedMesh *dm,
DerivedMesh *source,
DerivedMeshType type,
int numVerts,
int numEdges,
int numTessFaces,
int numLoops,
int numPolys)
{
const CustomData_MeshMasks *mask = &CD_MASK_DERIVEDMESH;
CustomData_copy(&source->vertData, &dm->vertData, mask->vmask, CD_CALLOC, numVerts);
CustomData_copy(&source->edgeData, &dm->edgeData, mask->emask, CD_CALLOC, numEdges);
CustomData_copy(&source->faceData, &dm->faceData, mask->fmask, CD_CALLOC, numTessFaces);
@ -387,26 +312,6 @@ void DM_from_template_ex(DerivedMesh *dm,
DM_init_funcs(dm);
dm->needsFree = 1;
dm->dirty = (DMDirtyFlag)0;
}
void DM_from_template(DerivedMesh *dm,
DerivedMesh *source,
DerivedMeshType type,
int numVerts,
int numEdges,
int numTessFaces,
int numLoops,
int numPolys)
{
DM_from_template_ex(dm,
source,
type,
numVerts,
numEdges,
numTessFaces,
numLoops,
numPolys,
&CD_MASK_DERIVEDMESH);
}
bool DM_release(DerivedMesh *dm)
@ -464,14 +369,6 @@ void DM_DupPolys(DerivedMesh *source, DerivedMesh *target)
}
}
void DM_ensure_normals(DerivedMesh *dm)
{
if (dm->dirty & DM_DIRTY_NORMALS) {
dm->calcNormals(dm);
}
BLI_assert((dm->dirty & DM_DIRTY_NORMALS) == 0);
}
void DM_ensure_looptri_data(DerivedMesh *dm)
{
const unsigned int totpoly = dm->numPolyData;
@ -524,7 +421,7 @@ void DM_set_only_copy(DerivedMesh *dm, const CustomData_MeshMasks *mask)
* see replies to r50969, Campbell */
#if 0
CustomData_set_only_copy(&dm->loopData, mask->lmask);
CustomData_set_only_copy(&dm->polyData, mask->pmask);
Custom(&dm->polyData, mask->pmask);
#endif
}
@ -552,45 +449,11 @@ void DM_add_edge_layer(DerivedMesh *dm, int type, eCDAllocType alloctype, void *
CustomData_add_layer(&dm->edgeData, type, alloctype, layer, dm->numEdgeData);
}
void DM_add_tessface_layer(DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer)
{
CustomData_add_layer(&dm->faceData, type, alloctype, layer, dm->numTessFaceData);
}
void DM_add_loop_layer(DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer)
{
CustomData_add_layer(&dm->loopData, type, alloctype, layer, dm->numLoopData);
}
void DM_add_poly_layer(DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer)
{
CustomData_add_layer(&dm->polyData, type, alloctype, layer, dm->numPolyData);
}
void *DM_get_vert_data(DerivedMesh *dm, int index, int type)
{
BLI_assert(index >= 0 && index < dm->getNumVerts(dm));
return CustomData_get(&dm->vertData, index, type);
}
void *DM_get_edge_data(DerivedMesh *dm, int index, int type)
{
BLI_assert(index >= 0 && index < dm->getNumEdges(dm));
return CustomData_get(&dm->edgeData, index, type);
}
void *DM_get_tessface_data(DerivedMesh *dm, int index, int type)
{
BLI_assert(index >= 0 && index < dm->getNumTessFaces(dm));
return CustomData_get(&dm->faceData, index, type);
}
void *DM_get_poly_data(DerivedMesh *dm, int index, int type)
{
BLI_assert(index >= 0 && index < dm->getNumPolys(dm));
return CustomData_get(&dm->polyData, index, type);
}
void *DM_get_vert_data_layer(DerivedMesh *dm, int type)
{
if (type == CD_MVERT) {
@ -609,15 +472,6 @@ void *DM_get_edge_data_layer(DerivedMesh *dm, int type)
return CustomData_get_layer(&dm->edgeData, type);
}
void *DM_get_tessface_data_layer(DerivedMesh *dm, int type)
{
if (type == CD_MFACE) {
return dm->getTessFaceArray(dm);
}
return CustomData_get_layer(&dm->faceData, type);
}
void *DM_get_poly_data_layer(DerivedMesh *dm, int type)
{
return CustomData_get_layer(&dm->polyData, type);
@ -1731,13 +1585,6 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
BKE_id_free(nullptr, mesh_orco);
}
/* Ensure normals calculation below is correct (normal settings have transferred properly).
* However, nodes modifiers might create meshes from scratch or transfer meshes from other
* objects with different settings, and in general it doesn't make sense to guarantee that
* the settings are the same as the original mesh. If necessary, this could become a modifier
* type flag. */
BLI_assert(mesh_input->smoothresh == mesh_cage->smoothresh);
/* Compute normals. */
editbmesh_calc_modifier_final_normals(mesh_final, &final_datamask);
if (mesh_cage && (mesh_cage != mesh_final)) {
@ -2144,32 +1991,6 @@ void mesh_get_mapped_verts_coords(Mesh *me_eval, float (*r_cos)[3], const int to
}
}
void DM_calc_loop_tangents(DerivedMesh *dm,
bool calc_active_tangent,
const char (*tangent_names)[MAX_NAME],
int tangent_names_len)
{
BKE_mesh_calc_loop_tangent_ex(
dm->getVertArray(dm),
dm->getPolyArray(dm),
dm->getNumPolys(dm),
dm->getLoopArray(dm),
dm->getLoopTriArray(dm),
dm->getNumLoopTri(dm),
&dm->loopData,
calc_active_tangent,
tangent_names,
tangent_names_len,
(const float(*)[3])CustomData_get_layer(&dm->vertData, CD_NORMAL),
(const float(*)[3])CustomData_get_layer(&dm->polyData, CD_NORMAL),
(const float(*)[3])dm->getLoopDataArray(dm, CD_NORMAL),
(const float(*)[3])dm->getVertDataArray(dm, CD_ORCO), /* may be nullptr */
/* result */
&dm->loopData,
dm->getNumLoops(dm),
&dm->tangent_mask);
}
static void mesh_init_origspace(Mesh *mesh)
{
const float default_osf[4][2] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};

View File

@ -1956,30 +1956,15 @@ void BKE_pose_blend_read_lib(BlendLibReader *reader, Object *ob, bPose *pose)
return;
}
/* always rebuild to match proxy or lib changes, but on Undo */
/* Always rebuild to match library changes, except on Undo. */
bool rebuild = false;
if (!BLO_read_lib_is_undo(reader)) {
if (ob->proxy || ob->id.lib != arm->id.lib) {
if (ob->id.lib != arm->id.lib) {
rebuild = true;
}
}
if (ob->proxy) {
/* sync proxy layer */
if (pose->proxy_layer) {
arm->layer = pose->proxy_layer;
}
/* sync proxy active bone */
if (pose->proxy_act_bone[0]) {
Bone *bone = BKE_armature_find_bone_name(arm, pose->proxy_act_bone);
if (bone) {
arm->act_bone = bone;
}
}
}
LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
BKE_constraint_blend_read_lib(reader, (ID *)ob, &pchan->constraints);

View File

@ -1284,8 +1284,8 @@ void BKE_animdata_main_cb(Main *bmain, ID_AnimData_Edit_Callback func, void *use
/* cache files */
ANIMDATA_IDS_CB(bmain->cachefiles.first);
/* hairs */
ANIMDATA_IDS_CB(bmain->hairs.first);
/* Hair Curves. */
ANIMDATA_IDS_CB(bmain->hair_curves.first);
/* pointclouds */
ANIMDATA_IDS_CB(bmain->pointclouds.first);
@ -1413,8 +1413,8 @@ void BKE_animdata_fix_paths_rename_all_ex(Main *bmain,
/* cache files */
RENAMEFIX_ANIM_IDS(bmain->cachefiles.first);
/* hairs */
RENAMEFIX_ANIM_IDS(bmain->hairs.first);
/* Hair Curves. */
RENAMEFIX_ANIM_IDS(bmain->hair_curves.first);
/* pointclouds */
RENAMEFIX_ANIM_IDS(bmain->pointclouds.first);

View File

@ -3382,8 +3382,8 @@ void BKE_animsys_evaluate_all_animation(Main *main, Depsgraph *depsgraph, float
/* cache files */
EVAL_ANIM_IDS(main->cachefiles.first, ADT_RECALC_ANIM);
/* hairs */
EVAL_ANIM_IDS(main->hairs.first, ADT_RECALC_ANIM);
/* Hair Curves. */
EVAL_ANIM_IDS(main->hair_curves.first, ADT_RECALC_ANIM);
/* pointclouds */
EVAL_ANIM_IDS(main->pointclouds.first, ADT_RECALC_ANIM);

View File

@ -69,8 +69,6 @@
#include "CLG_log.h"
static CLG_LogRef LOG = {"bke.armature"};
/* -------------------------------------------------------------------- */
/** \name Prototypes
* \{ */
@ -2296,161 +2294,6 @@ void BKE_armature_where_is(bArmature *arm)
/** \name Pose Rebuild
* \{ */
/* if bone layer is protected, copy the data from from->pose
* when used with linked libraries this copies from the linked pose into the local pose */
static void pose_proxy_sync(Object *ob, Object *from, int layer_protected)
{
bPose *pose = ob->pose, *frompose = from->pose;
bPoseChannel *pchan, *pchanp;
bConstraint *con;
int error = 0;
if (frompose == NULL) {
return;
}
/* in some cases when rigs change, we can't synchronize
* to avoid crashing check for possible errors here */
for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
if (pchan->bone->layer & layer_protected) {
if (BKE_pose_channel_find_name(frompose, pchan->name) == NULL) {
CLOG_ERROR(&LOG,
"failed to sync proxy armature because '%s' is missing pose channel '%s'",
from->id.name,
pchan->name);
error = 1;
}
}
}
if (error) {
return;
}
/* clear all transformation values from library */
BKE_pose_rest(frompose, false);
/* copy over all of the proxy's bone groups */
/* TODO: for later
* - implement 'local' bone groups as for constraints
* NOTE: this isn't trivial, as bones reference groups by index not by pointer,
* so syncing things correctly needs careful attention */
BLI_freelistN(&pose->agroups);
BLI_duplicatelist(&pose->agroups, &frompose->agroups);
pose->active_group = frompose->active_group;
for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
pchanp = BKE_pose_channel_find_name(frompose, pchan->name);
if (UNLIKELY(pchanp == NULL)) {
/* happens for proxies that become invalid because of a missing link
* for regular cases it shouldn't happen at all */
}
else if (pchan->bone->layer & layer_protected) {
ListBase proxylocal_constraints = {NULL, NULL};
bPoseChannel pchanw;
/* copy posechannel to temp, but restore important pointers */
pchanw = *pchanp;
pchanw.bone = pchan->bone;
pchanw.prev = pchan->prev;
pchanw.next = pchan->next;
pchanw.parent = pchan->parent;
pchanw.child = pchan->child;
pchanw.custom_tx = pchan->custom_tx;
pchanw.bbone_prev = pchan->bbone_prev;
pchanw.bbone_next = pchan->bbone_next;
pchanw.mpath = pchan->mpath;
pchan->mpath = NULL;
/* Reset runtime data, we don't want to share that with the proxy. */
BKE_pose_channel_runtime_reset_on_copy(&pchanw.runtime);
/* this is freed so copy a copy, else undo crashes */
if (pchanw.prop) {
pchanw.prop = IDP_CopyProperty(pchanw.prop);
/* use the values from the existing props */
if (pchan->prop) {
IDP_SyncGroupValues(pchanw.prop, pchan->prop);
}
}
/* Constraints - proxy constraints are flushed... local ones are added after
* 1: extract constraints not from proxy (CONSTRAINT_PROXY_LOCAL) from pchan's constraints.
* 2: copy proxy-pchan's constraints on-to new.
* 3: add extracted local constraints back on top.
*
* Note for BKE_constraints_copy:
* When copying constraints, disable 'do_extern' otherwise
* we get the libs direct linked in this blend.
*/
BKE_constraints_proxylocal_extract(&proxylocal_constraints, &pchan->constraints);
BKE_constraints_copy(&pchanw.constraints, &pchanp->constraints, false);
BLI_movelisttolist(&pchanw.constraints, &proxylocal_constraints);
/* constraints - set target ob pointer to own object */
for (con = pchanw.constraints.first; con; con = con->next) {
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
if (cti && cti->get_constraint_targets) {
cti->get_constraint_targets(con, &targets);
for (ct = targets.first; ct; ct = ct->next) {
if (ct->tar == from) {
ct->tar = ob;
}
}
if (cti->flush_constraint_targets) {
cti->flush_constraint_targets(con, &targets, 0);
}
}
}
/* free stuff from current channel */
BKE_pose_channel_free(pchan);
/* copy data in temp back over to the cleaned-out (but still allocated) original channel */
*pchan = pchanw;
if (pchan->custom) {
id_us_plus(&pchan->custom->id);
}
}
else {
/* always copy custom shape */
pchan->custom = pchanp->custom;
if (pchan->custom) {
id_us_plus(&pchan->custom->id);
}
if (pchanp->custom_tx) {
pchan->custom_tx = BKE_pose_channel_find_name(pose, pchanp->custom_tx->name);
}
/* ID-Property Syncing */
{
IDProperty *prop_orig = pchan->prop;
if (pchanp->prop) {
pchan->prop = IDP_CopyProperty(pchanp->prop);
if (prop_orig) {
/* copy existing values across when types match */
IDP_SyncGroupValues(pchan->prop, prop_orig);
}
}
else {
pchan->prop = NULL;
}
if (prop_orig) {
IDP_FreeProperty(prop_orig);
}
}
}
}
}
/**
* \param r_last_visited_bone_p: The last bone handled by the last call to this function.
*/
@ -2579,16 +2422,6 @@ void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm, const bool do_id_
// printf("rebuild pose %s, %d bones\n", ob->id.name, counter);
/* synchronize protected layers with proxy */
/* HACK! To preserve 2.7x behavior that you always can pose even locked bones,
* do not do any restoration if this is a COW temp copy! */
/* Switched back to just NO_MAIN tag, for some reasons (c)
* using COW tag was working this morning, but not anymore... */
if (ob->proxy != NULL && (ob->id.tag & LIB_TAG_NO_MAIN) == 0) {
BKE_object_copy_proxy_drivers(ob, ob->proxy);
pose_proxy_sync(ob, ob->proxy, arm->layer_protected);
}
BKE_pose_update_constraint_flags(pose); /* for IK detection for example */
pose->flag &= ~POSE_RECALC;
@ -2846,6 +2679,35 @@ BoundBox *BKE_armature_boundbox_get(Object *ob)
return ob->runtime.bb;
}
void BKE_pchan_minmax(const Object *ob, const bPoseChannel *pchan, float r_min[3], float r_max[3])
{
const bArmature *arm = ob->data;
const bPoseChannel *pchan_tx = (pchan->custom && pchan->custom_tx) ? pchan->custom_tx : pchan;
const BoundBox *bb_custom = ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) ?
BKE_object_boundbox_get(pchan->custom) :
NULL;
if (bb_custom) {
float mat[4][4], smat[4][4], rmat[4][4], tmp[4][4];
scale_m4_fl(smat, PCHAN_CUSTOM_BONE_LENGTH(pchan));
rescale_m4(smat, pchan->custom_scale_xyz);
eulO_to_mat4(rmat, pchan->custom_rotation_euler, ROT_MODE_XYZ);
copy_m4_m4(tmp, pchan_tx->pose_mat);
translate_m4(tmp,
pchan->custom_translation[0],
pchan->custom_translation[1],
pchan->custom_translation[2]);
mul_m4_series(mat, ob->obmat, tmp, rmat, smat);
BKE_boundbox_minmax(bb_custom, mat, r_min, r_max);
}
else {
float vec[3];
mul_v3_m4v3(vec, ob->obmat, pchan_tx->pose_head);
minmax_v3v3_v3(r_min, r_max, vec);
mul_v3_m4v3(vec, ob->obmat, pchan_tx->pose_tail);
minmax_v3v3_v3(r_min, r_max, vec);
}
}
bool BKE_pose_minmax(Object *ob, float r_min[3], float r_max[3], bool use_hidden, bool use_select)
{
bool changed = false;
@ -2859,31 +2721,8 @@ bool BKE_pose_minmax(Object *ob, float r_min[3], float r_max[3], bool use_hidden
* (editarmature.c:2592)... Skip in this case too! */
if (pchan->bone && (!((use_hidden == false) && (PBONE_VISIBLE(arm, pchan->bone) == false)) &&
!((use_select == true) && ((pchan->bone->flag & BONE_SELECTED) == 0)))) {
bPoseChannel *pchan_tx = (pchan->custom && pchan->custom_tx) ? pchan->custom_tx : pchan;
BoundBox *bb_custom = ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) ?
BKE_object_boundbox_get(pchan->custom) :
NULL;
if (bb_custom) {
float mat[4][4], smat[4][4], rmat[4][4], tmp[4][4];
scale_m4_fl(smat, PCHAN_CUSTOM_BONE_LENGTH(pchan));
rescale_m4(smat, pchan->custom_scale_xyz);
eulO_to_mat4(rmat, pchan->custom_rotation_euler, ROT_MODE_XYZ);
copy_m4_m4(tmp, pchan_tx->pose_mat);
translate_m4(tmp,
pchan->custom_translation[0],
pchan->custom_translation[1],
pchan->custom_translation[2]);
mul_m4_series(mat, ob->obmat, tmp, rmat, smat);
BKE_boundbox_minmax(bb_custom, mat, r_min, r_max);
}
else {
float vec[3];
mul_v3_m4v3(vec, ob->obmat, pchan_tx->pose_head);
minmax_v3v3_v3(r_min, r_max, vec);
mul_v3_m4v3(vec, ob->obmat, pchan_tx->pose_tail);
minmax_v3v3_v3(r_min, r_max, vec);
}
BKE_pchan_minmax(ob, pchan, r_min, r_max);
changed = true;
}
}

View File

@ -850,10 +850,6 @@ void BKE_pose_eval_init(struct Depsgraph *depsgraph, Scene *UNUSED(scene), Objec
}
BLI_assert(pose->chan_array != NULL || BLI_listbase_is_empty(&pose->chanbase));
if (object->proxy != NULL) {
object->proxy->proxy_from = object;
}
}
void BKE_pose_eval_init_ik(struct Depsgraph *depsgraph, Scene *scene, Object *object)
@ -1070,57 +1066,3 @@ void BKE_pose_eval_cleanup(struct Depsgraph *depsgraph, Scene *scene, Object *ob
BIK_release_tree(scene, object, ctime);
pose_eval_cleanup_common(object);
}
void BKE_pose_eval_proxy_init(struct Depsgraph *depsgraph, Object *object)
{
BLI_assert(ID_IS_LINKED(object) && object->proxy_from != NULL);
DEG_debug_print_eval(depsgraph, __func__, object->id.name, object);
BLI_assert(object->pose->chan_array != NULL || BLI_listbase_is_empty(&object->pose->chanbase));
}
void BKE_pose_eval_proxy_done(struct Depsgraph *depsgraph, Object *object)
{
BLI_assert(ID_IS_LINKED(object) && object->proxy_from != NULL);
DEG_debug_print_eval(depsgraph, __func__, object->id.name, object);
}
void BKE_pose_eval_proxy_cleanup(struct Depsgraph *depsgraph, Object *object)
{
BLI_assert(ID_IS_LINKED(object) && object->proxy_from != NULL);
DEG_debug_print_eval(depsgraph, __func__, object->id.name, object);
pose_eval_cleanup_common(object);
}
void BKE_pose_eval_proxy_copy_bone(struct Depsgraph *depsgraph, Object *object, int pchan_index)
{
const bArmature *armature = (bArmature *)object->data;
if (armature->edbo != NULL) {
return;
}
BLI_assert(ID_IS_LINKED(object) && object->proxy_from != NULL);
bPoseChannel *pchan = pose_pchan_get_indexed(object, pchan_index);
BLI_assert(pchan != NULL);
DEG_debug_print_eval_subdata(
depsgraph, __func__, object->id.name, object, "pchan", pchan->name, pchan);
/* TODO(sergey): Use indexed lookup, once it's guaranteed to be kept
* around for the time while proxies are evaluating.
*/
#if 0
bPoseChannel *pchan_from = pose_pchan_get_indexed(object->proxy_from, pchan_index);
#else
bPoseChannel *pchan_from = BKE_pose_channel_find_name(object->proxy_from->pose, pchan->name);
#endif
if (pchan_from == NULL) {
printf(
"WARNING: Could not find bone %s in linked ID anymore... "
"You should delete and re-generate your proxy.\n",
pchan->name);
return;
}
BKE_pose_copy_pchan_result(pchan, pchan_from);
copy_dq_dq(&pchan->runtime.deform_dual_quat, &pchan_from->runtime.deform_dual_quat);
BKE_pchan_bbone_segments_cache_copy(pchan, pchan_from);
pose_channel_flush_to_orig_if_needed(depsgraph, object, pchan);
}

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