1
1

Compare commits

...

235 Commits

Author SHA1 Message Date
5ba3e6001f LineArt: Try using sort/parallel_sort but crashes 2022-04-25 16:56:06 +08:00
0ebc062604 LineArt: Edge neighbor with object loading code WIP 2022-04-25 14:54:07 +08:00
a3b38c979a Revert "LineArt: CAS-inspired tile tree (WIP)"
This reverts commit 77afe859a0.
2022-04-25 12:49:25 +08:00
77afe859a0 LineArt: CAS-inspired tile tree (WIP) 2022-04-21 21:02:28 +08:00
ce689964a4 LineArt: Index calculation based adjacent lookup WIP 2022-04-20 22:12:05 +08:00
516ec45d10 LineArt: Object loading fixes for master 2022-04-20 20:00:43 +08:00
58511c4175 LineArt: Face mark filtering for new object loading code. 2022-04-20 20:00:43 +08:00
f49948bf48 LineArt: Working fix for new object loading 2022-04-20 20:00:43 +08:00
50840bb2a3 LineArt: Crease in new object loading working correctly. 2022-04-20 20:00:43 +08:00
3a055e8f41 LineArt: Crease by sharp 2022-04-20 20:00:43 +08:00
0d5d554287 LineArt: Crease support for new loading 2022-04-20 20:00:43 +08:00
fe2df4c771 LineArt: Object loading wip 2022-04-20 20:00:43 +08:00
0385e2f1f9 PBVH: Pass Mesh to extract internals.
More mesh data is required when extracting the UV seams. This is an
API change for to support this future enhancement.
2022-04-20 13:42:51 +02:00
5b8a3ccd37 Fix T94775: Buggy liboverride default apply code for items insertion in RNA collections.
For some reason, the rework of liboverride handling of Collection items
insertion (rB33c5e7bcd5e5) completely missed to update accordingly the
default liboverride apply code...

Many thanks to Wayde Moss (@GuiltyGhost) for the investigation and
proposed solution.
2022-04-20 11:05:54 +02:00
97dbcf9746 Fix (unreported) huge liboverride slow-down due to non-disabled UV layer props.
Was revealed by yesterday's fix (rB6f56bd4083f9).
2022-04-20 10:10:29 +02:00
8adc7cad00 Fix compilation without OpenVDB 2022-04-20 09:58:42 +02:00
31a2feceb8 Cleanup: remove unused curves toolsetting 2022-04-20 09:51:14 +02:00
f5191b8760 Fix GPU subdivision: Crash on adding subdivision surface modifier
This was caused by the use of a reserved keyword macro that is not
directly used but causes an error on some compiler.

Change the occurences to not match the macros.
2022-04-20 09:12:02 +02:00
65a1fcdaf7 Cleanup: run autopep8 on tests/performance/benchmark
This file was skipped by source/tools/utils/autopep8_clean.py
since it doesn't have a .py extension, running the autopep8 tool
recursively detects Python scripts without extensions.
2022-04-20 17:07:46 +10:00
67a4908bfc Cleanup: re-run autopep8 with E401 enabled
Put imports on their own line which was almost always the case already.
2022-04-20 16:26:49 +10:00
3adef61942 Cleanup: run autopep8 on release/scripts/presets 2022-04-20 16:21:04 +10:00
41b8e0316a Cleanup: use autopep8 on release/lts 2022-04-20 16:18:42 +10:00
28e068b55c Cleanup: run autopep8 on release/scripts/freestyle 2022-04-20 16:18:30 +10:00
8898251584 Cleanup: run autopep8 on intern/cycles/
Disable autopep8 for the block that yields passes in list_render_passes,
for better readability.
2022-04-20 16:10:05 +10:00
11dd7941af Cleanup: run autopep8 with max-line-length=120 (missed a file) 2022-04-20 15:55:17 +10:00
67516d0dae Cleanup: run autopep8 with max-line-length=120 2022-04-20 15:47:24 +10:00
8ed8fa80f4 Cleanup: use autopep8 for bl_i18n_utils.settings
Disable autopep8 for some regex blocks that use indentation
to signify regex grouping.
2022-04-20 15:39:36 +10:00
08dbd3bc7f Cleanup: run autopep8 on release/scripts/modules/ 2022-04-20 15:12:10 +10:00
38d8b088e7 Cleanup: run autopep8 on release/scripts/templates_py 2022-04-20 15:11:22 +10:00
c2cdbe1e88 Cleanup: run autopep8 on doc/ 2022-04-20 15:10:14 +10:00
df3316cbe9 Cleanup: run autopep8 on build_files/
Replace multiple hashes with over-lines for make_source_archive.py.
2022-04-20 15:08:46 +10:00
972a697f82 PyAPI: improve deprecation warning for bpy.ops context override
- Increase the stack level so the reported line number references
  script authors code (not Blender's wrapper function).
- Include the operator name and poll/call usage in the warning.
2022-04-20 13:17:16 +10:00
feea852b10 Fix crash passing no arguments to Context.temp_override 2022-04-20 13:01:14 +10:00
9364e17936 Docs: update examples to use Context.temp_override 2022-04-20 12:49:13 +10:00
f438344cf2 PyAPI: temporary context override support
Support a way to temporarily override the context from Python.

- Added method `Context.temp_override` context manager.
- Special support for windowing variables "window", "area" and "region",
  other context members such as "active_object".
- Nesting context overrides is supported.
- Previous windowing members are restored when the context exists unless
  they have been removed.
- Overriding context members by passing a dictionary into operators in
  `bpy.ops` has been deprecated and warns when used.

This allows the window in a newly loaded file to be used, see: T92464

Reviewed by: mont29

Ref D13126
2022-04-20 12:19:35 +10:00
6d9268c2c7 PyAPI: utility functions for parsing typed RNA arguments
These functions can be used with PyArg_ParseTupleAndKeywords
(and related functions) to take typed RNA arguments without
having to extract and type-check them separately.

No functional changes, extracted from D13126.
2022-04-20 12:16:11 +10:00
16afff2ddc Cleanup: spelling in comments 2022-04-20 10:41:31 +10:00
42717596d0 Cleanup: clang-format 2022-04-20 10:41:31 +10:00
f8f8edbe1a Cleanup: unused argument warning 2022-04-20 10:41:31 +10:00
Nate Rupsis
75ccfa63d0 UI: Fix typo in Apply Parent Inverse tooltip
There's a small typo in the tool tip for applying the Parent Inverse. This patch fixes that typo

old:
{F13010751}

new:
{F13010749}

Reviewed By: Blendify

Maniphest Tasks: T97437

Differential Revision: https://developer.blender.org/D14693
2022-04-19 20:40:59 -04:00
6a3c3c77b3 Mesh: Avoid unnecessary normal calculation and dirty tags
This is mostly a cleanup to avoid hardcoding the eager calculation of
normals it isn't necessary, by reducing calls to `BKE_mesh_calc_normals`
and by removing calls to `BKE_mesh_normals_tag_dirty` when the mesh
is newly created and already has dirty normals anyway. This reduces
boilerplate code and makes the "dirty by default" state more clear.
Any regressions from this commit should be easy to fix, though the
lazy calculation is solid enough that none are expected.
2022-04-19 17:08:02 -05:00
9ec94c3882 Cleanup: Don't recalculate normals in versioning code
Normals are not read from files anymore, calculating them in versioning
is unnecessary and wasteful.
2022-04-19 16:51:58 -05:00
d813ee55fd Fix: Incorrect info message in set material node
The node does have support for curves since c4f7f59c65.
2022-04-19 13:20:19 -05:00
5a06996722 Fix: Assert when sculpting empty curves 2022-04-19 12:09:29 -05:00
67962824e9 GPU: Fix Adresse Sanitizer errors 2022-04-19 19:03:40 +02:00
37d298391e Cleanup: GPUMaterial: Remove GPU_material_is_volume_shader 2022-04-19 19:03:40 +02:00
2890c11cd7 Cycles: add support for volume motion blur
This adds support for rendering motion blur for volumes, using their
velocity field. This works for fluid simulations and imported VDB
volumes. For the latter, the name of the velocity field can be set per
volume object, with automatic detection of velocity fields that are
split into 3 scalar grids.

A new parameter is also added to scale velocity for more artistic control.

Like for Alembic and USD caches, a parameter to set the unit of time in
which the velocity vectors are expressed is also added. For Blender gas
simulations, the velocity unit should always be in seconds, so this is
only exposed for volume objects which may come from external OpenVDB
files.

These parameters are available under the `Render` panels for the fluid
domain and the volume object data properties respectively.

Credits: kernel advection code from Tangent Animation's Blackbird based
on earlier work by Geraldine Chua

Differential Revision: https://developer.blender.org/D14629
2022-04-19 17:07:53 +02:00
56cfd60d43 Cleanup: remove unused code 2022-04-19 16:50:25 +02:00
Robert Guetzkow
721a9bc35c Fix T97338: Correct reference count for COM handling and removal of gotos
The fix ensures that the reference count for `IShellItem *pSI` is decremented,
preventing a memory leak. For `IFileOperation *pfo` the decrement of the
reference count is only attempted when `CoCreateInstance` is successful.
Additionally, the gotos have been replaced with nested if/else statements.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D14681
2022-04-19 16:30:22 +02:00
Germano Cavalcante
3e98331a09 PyGPU: remove outdated function 'code_from_builtin'
Since shader sources are now parsed on demand via `GPUShaderCreateInfo`,
sources are not available to be read via
`GPU_shader_get_builtin_shader_code`.

Currently this results in a crash as the code tries to read `NULL`
pointers.

`GPU_shader_get_builtin_shader_code` was created with the intention of
informing the user how a builtin shader works, thus "replacing"
detailed documentation.

Therefore this function doesn't really have a practical use in an addon.

So, instead of updating the function (which would require several
changes to the gpu module), remove it and improve the documentation.

Release Notes: https://wiki.blender.org/wiki/Reference/Release_Notes/3.2/Python_API#Breaking_Changes

Reviewed By: fclem

Differential Revision: https://developer.blender.org/D14678
2022-04-19 11:23:51 -03:00
47de3659f0 improve hover tip for 'Lock Object Modes' property 2022-04-19 15:58:28 +02:00
6f56bd4083 Fix wrong logic in comparison code of RNA collection proerties.
Noted as part of T94775 investigation by Wayde Moss (@GuiltyGhost),
thanks!

NOTE: this mistake probably did not have any pratical impact in current
code, at least for overrides.
2022-04-19 15:53:54 +02:00
767939231d DRW: Volume: Fix warning about unused variable 2022-04-19 14:47:09 +02:00
058ce64be0 Fix: Uninitialized paint brush when using byte textures.
This is a fix for the 3d texturing brush.
2022-04-19 12:31:00 +02:00
14a2706886 EEVEE: Fix compilation caused by missing file 2022-04-19 12:27:27 +02:00
fa3bd17ae8 GPU: Replace GPUMaterialVolumeGrid by GPUMaterialAttribute
This is to make the codegen and shading nodes object type agnostic. This
is essential for flexibility of the engine to use the nodetree as it see
fits.

The essential volume attributes struct properties are moved to the
`GPUMaterialAttribute` which see its final input name set on creation.

The binding process is centralized into `draw_volume.cc` to avoid
duplicating the code between multiple engines. It mimics the hair attributes
process.

Volume object grid transforms and other per object uniforms are packed into
one UBO per object. The grid transform is now based on object which simplify
the matrix preparations.

This also gets rid of the double transforms and use object info orco factors
for volume objects.

Tagging @brecht because he did the initial implementation of Volume Grids.
2022-04-19 12:09:18 +02:00
1e3f4c70ab Material: Add name to default shaders
Improve debugging experience.
2022-04-19 12:09:18 +02:00
c2c17cc076 Workbench: Volume: Fix errors about unboud texture 2022-04-19 12:09:18 +02:00
6296cb5129 DRW: Centralize smoke domain texture management
This code was duplicated in multiple engines. Now it is the draw manager
responsability to manage the throwaway fluid textures.
2022-04-19 12:09:18 +02:00
eccc9d8eba Cleanup: Remove unused function in Cycles queue
Noticed while looking into oneAPI patch.

Seems to be unused, without clear indication why/when it might be
needed. Removing the function simplifies adding the new backend.

Differential Revision: https://developer.blender.org/D14652
2022-04-19 10:32:07 +02:00
3035235def Cleanup: run autopep8 on tests/ 2022-04-19 15:25:55 +10:00
58d86527ae Cleanup: run autopep8 on release/scripts/startup/ 2022-04-19 15:07:04 +10:00
8c25889bb6 Refactor: Move mesh face dot tag out of MVert
Continuing the refactors described in T93602, this commit moves
the face dot tag set by the subdivision surface modifier out of
`MVert` to `MeshRuntime`. This clarifies its status as runtime data
and allows further refactoring of mesh positions in the future.

Before, `BKE_modifiers_uses_subsurf_facedots` was used to check
whether subsurf face dots should be drawn, but now we can just check
if the tags exist on the mesh. Modifiers that create new new geometry
or modify topology will already remove the array by clearing mesh
runtime data.

Differential Revision: https://developer.blender.org/D14680
2022-04-18 23:48:43 -05:00
775f0d76d5 Fix missing C/Python methods in API docs
The following methods weren't included in API docs.

- BlendDataLibraries.load
- BlendDataLibraries.write
- Text.region_as_string
- Text.region_from_string
2022-04-19 13:08:48 +10:00
7e045094c1 PyDoc: quiet warnings for duplicate members bpy.context 2022-04-19 12:19:08 +10:00
f401741544 PyDoc: remove multiple children properties for Bone type
This doesn't cause any functional change as the RNA property
of Bone wasn't overridden by the _GenericBone's property,
however the `children` property was documented twice, causing a warning.
2022-04-19 12:18:53 +10:00
76acc5e999 PyDoc: fix including literal text immediately after function args
Literal text from examples could be included directly after function
arguments, this caused a warning with mis-matching indentation.
2022-04-19 12:17:58 +10:00
adcce654e3 Cleanup: Use correct capitalization of "F-Curve" 2022-04-18 20:17:41 -04:00
Colin Basnett
549f68149d UI: Fix typo in UI description for bpy.types.ActionFCurves.remove function
The UI description for the `bpy.types.ActionFCurves.remove` was incorrect;
seemingly a copy-paste typo from the `rna_Action_groups_remove` function.

Reviewed By: sybren, Blendify

Differential Revision: https://developer.blender.org/D14659
2022-04-18 20:11:45 -04:00
b90e892a17 Fix call of 'BLI_assert' instead 'BLI_assert_msg'
Error in 5da02548e9
2022-04-18 19:15:46 -03:00
5da02548e9 Cleanup: remove redundant 'DEG_get_original_object' call
The `BMEditMesh` pointer is the same in the original or evaluated mesh.

Also a clang-format was missed.
2022-04-18 19:00:55 -03:00
a0c2d6bf85 Transform: small optimization in snap to edit mesh
In some cases, selected elements do not contribute to snapping.
So ignore these elements when creating the edit meshes bound box.
2022-04-18 18:25:16 -03:00
bec057a453 Fix assert on meshes without mloop in snap code
Meshes without loops are still valid for snapping.
2022-04-18 18:24:50 -03:00
03d39a04a3 Fix T97002: Preserve multi socket link order
Preserve multi socket link order when copying nodes or adding a new
group input sockets by linking directly to multi inputs from the group
input node's extension socket.

This is done by also copying the `multi_input_socket_index` when
the new links are created by copying existing or temporary links.

Reviewed By: Hans Goudey

Differential Revision: http://developer.blender.org/D14535
2022-04-18 22:28:03 +02:00
314b27850c Cleanup: Remove incorrect comment 2022-04-18 14:08:29 -05:00
95cce6f6b0 Cleanup: Move object_modifier.c to C++
This allows using C++ only APIs/data structures, and potentially
simplifies adding support to apply modifiers for the Curves object.
2022-04-18 12:40:23 -05:00
98fc998c70 Cleanup: Clang tidy
- Inconsistent parameter names
- Else after return
- Braces around statements
- Qualified auto
- Also (not clang tidy): Pass StringRef by value, unused parameter
2022-04-18 12:36:37 -05:00
fc58368263 Build: link with GameController and CoreHaptics frameworks on macOS
In preparation of upcoming SDL upgrade, which uses these.
2022-04-18 19:14:36 +02:00
2cb76a6c8d Cleanup: consistently use parallel_for without tbb namespace in Cycles 2022-04-18 19:14:36 +02:00
029b0df81a Fix Cycles blackbody shader not taking into account OpenColorIO config
Keep the existing Rec.709 fit and convert to other colorspace if needed, it
seems accurate enough in practice, and keeps the same performance for the
default case.
2022-04-18 19:14:34 +02:00
41b3feea85 Fix Cycles build error with latest TBB after recent changes
From changes in 869a46df29, ref D14454
2022-04-18 18:49:35 +02:00
Angus Stanton
ccd2e89d37 Fix T94559: Copying geometry node group does not copy animation data
Reimplement copy geometry node groups in C. The version implemented in
Python could also manually copy the animation data, but it's more
standard to do this with `BKE_id_copy_ex` and `LIB_ID_COPY_ACTIONS`.

Differential Revision: https://developer.blender.org/D14615
2022-04-18 10:15:30 -05:00
ef2b8c1c3a Nodes: Remove unnecessary RNA pointer creation
`rna_NodeSocket_refine` and `rna_Node_refine` take significant time
when building the `NodeTreeRef` acceleration data structure, but they
aren't used at all. This commit removes their eager calculation and
instead creates them on-demand in the `rna()` functions. They also
aren't inlined to avoid including `RNA_prototypes.h` in the header.

Differential Revision: https://developer.blender.org/D14674
2022-04-18 10:12:17 -05:00
933fed2a17 Minor tweaks to labels/tooltips of override operation in the Outliner. 2022-04-18 12:21:33 +02:00
bf80dc2bd4 Add debugging info for Wintab activated by argument --debug-wintab.
Bonus: Added docs for `--debug-ghost`.

Differential Revision: https://developer.blender.org/D14610
2022-04-17 15:21:59 -07:00
213cd39b6d OBJ: further optimize, cleanup and harden the new C++ importer
Continued improvements to the new C++ based OBJ importer.

Performance: about 2x faster.
- Rungholt.obj (several meshes, 263MB file): Windows 12.7s -> 5.9s, Mac 7.7s -> 3.1s.
- Blender 3.0 splash (24k meshes, 2.4GB file): Windows 97.3s -> 53.6s, Mac 137.3s -> 80.0s.
- "Windows" is VS2022, AMD Ryzen 5950X (32 threads), "Mac" is Xcode/clang 13, M1Max (10 threads).
- Slightly reduced memory usage during import as well.

The performance gains are a combination of several things:
- Replacing `std::stof` / `std::stoi` with C++17 `from_chars`.
- Stop reading input file char-by-char using `std::getline`, and instead read in 64kb chunks, and parse from there (taking care of possibly handling lines split mid-way due to chunk boundaries).
- Removing abstractions for splitting a line by some char,
- Avoid tiny memory allocations: instead of storing a vector of polygon corners in each face, store all the corners in one big array, and per-face only store indices "where do corners start, and how many". Likewise, don't store full string names of material/group names for each face; only store indices into overall material/group names arrays.
- Stop always doing mesh validation, which is slow. Do it just like the Alembic importer does: only do validation if found some invalid faces during import, or if requested by the user via an import setting checkbox (which defaults to off).
- Stop doing "collection sync" for each object being added; instead do the collection sync right after creating all the objects.

Cleanup / Robustness:

This reworking of parser (see "removing abstractions" point above) means that all the functions that were in `parser_string_utils` file are gone, and replaced with different set of functions. However they are not OBJ specific, so as pointed out during review of the previous differential, they are now in `source/blender/io/common` library.

Added gtest coverage for said functions as well; something that was only indirectly covered by obj tests previously.

Rework of some bits of parsing made the parser actually better able to deal with invalid syntax. E.g. previously, if a face corner were a `/123` string, it would have incorrectly treated that as a vertex index (since it would get "hey that's one number" after splitting a string by a slash), instead of properly marking it as invalid syntax.

Added gtest coverage for .mtl parsing; something that was not covered by any tests at all previously.

Reviewed By: Howard Trickey
Differential Revision: https://developer.blender.org/D14586
2022-04-17 22:07:43 +03:00
a3eb4027c2 Fix T97095: export of Poly curves, export crash when object contains multiple curve types
- Was not exporting "Poly" curves at all,
- Had a crash when a single object contains multiple curves of different types -- it had a check for "is this nurbs compatible?" only for the first curve, and then proceeded to treat the other curves as nurbs as well, without checking for validity.

Fixed both issues by doing the same logic as in the old python exporter:
- Poly curves are supported,
- Treat object as "nurbs compatible" only if all the curves within it are nurbs compatible.

Added test coverage in the gtest suite. While at it, made "all_curves" test use the "golden obj file template" style test, instead of a manually coded test that checks intermediate objects but does not check the final exported result.

Reviewed By: Howard Trickey
Differential Revision: https://developer.blender.org/D14611
2022-04-17 21:59:55 +03:00
b32cb0266c Fix T96824: New 3.1 OBJ exporter writes incorrect polygon/vertex groups in some cases
The new 3.1 OBJ exporter code had incorrect code to determine which vertex group a polygon belongs to -- for each vertex, it was only looking at the first vertex group it has, and not using the group weight either.

This 99% fixes T96824, but not 100% on the user's submitted mesh -- exactly two faces from that mesh get assigned a different group compared to the old exporter. Either choice is "correct" given that on these two faces there are two vertex groups with equal contribution. The old Python exporter was picking the group based on internal python group name map order, whereas the new C++ exporter is picking the group with the lowest index, in case of ties. I'm not sure if it's possible to fix this TBH, will have to wait until the importer is also C++.

While at it, the new vertex group calculation code was doing a lot of redundant work for each and every face (traversing group lists several times, allocating & freeing memory), so I fixed that. Exporting a 6-level subdivided Monkey mesh with 30 vertex groups was taking 810ms, now takes 330ms.

Reviewed By: Howard Trickey
Differential Revision: https://developer.blender.org/D14500
2022-04-17 21:54:51 +03:00
e88807e71c Cleanup: Use C++ Array type 2022-04-17 13:30:30 -05:00
b9f1b64801 USD/Ctest: Add basic USD-Imaging test.
This adds a basic unit test to check USD has been correctly
build with imaging components to support building both with
the old and new libs, it automatically adds the test when it
detects a library with imaging enabled. (platform devs will
have to pay attention it runs the test to validate the libs
build correctly)

For future use in the code it also defines a USD_HAS_IMAGING
define one could check if we're building against an USD lib
that has it (just because we build/ship with it, doesn't
mean downstream builds will ship with it, so we'll have
to be a little pro-active there)

Reviewed By: sybren

Differential Revision:https://developer.blender.org/D14456
2022-04-16 15:32:48 -06:00
98eb111568 Fix T97366: Misdetection of numbers as UDIMs in certain filepaths
In some circumstances singular files with numbers in their name (like
turntable-1080p.png or frame-1042.png) might be detected as a UDIM.

The root cause in this particular instance was because `BKE_image_get_tile_info`
believed this file to be a tiled texture and replaced the filename with
a tokenized version of it. However, later on, the code inside `image_open_single`
did not believe it was tiled because only 1 file was detected and our
tiled textures require at least 2. This discrepancy lead to the broken
filename situation.

This was a regression since rB180b66ae8a1f as that introduced the
tokenization changes.

Differential Revision: https://developer.blender.org/D14667
2022-04-16 14:18:08 -07:00
2b191cd2b4 Mask by color now auto-creates a
color attribute if one does not exist,
and no longer passes through to the
translate tool on tweak grab.
2022-04-15 18:49:38 -07:00
8eb40d2063 This patch changes Sculpt Multi-Plane Scrape tool icon to be red and have a little outline around the color, like the other scraping tools T97271
Also, as a suggestion, this patch changes Mask By Color and Color Filter to be the same shade of green as paint and smear tool icons

{F12998856}

{F12998857}

{F12998858}

Reviewed By: Julian Kaspar & Joseph Eagar
Differential Revision: https://developer.blender.org/D14632
Ref D14632
2022-04-15 18:06:47 -07:00
dc5ae10692 Fix T96988: Merge by distance node crash with certain input
If the `wpoly` vector was small, the `wpoly_new` pointer could point
to part of its inline buffer on the stack, which becomes invalid out of
that scope. Instead, store `wpoly_new` as a span, and assign it properly
from the moved vector.
2022-04-15 16:55:15 -05:00
cb3c233ed3 Cleanup: Return early 2022-04-15 16:44:15 -05:00
65194f47b0 UI: Improve wording for some USD export descriptions
The HIG mentions that redundant words like "Enables" or "Activates"
shouldn't be used for tooltips of boolean properties. In this case
"When checked" was the redundant language that was implied by
the checkbox itself-- convention is to just state what the property
does when it's on.

Also change a few conjugations to the imperative and simplify
wording slightly, in order to be more consistent with language
elsewhere in Blender, and to be a bit more direct.

Differential Revision: https://developer.blender.org/D14644
2022-04-15 13:50:54 -05:00
ad324316ce Fix: Missing Null Check
Introduced by my recent commit: {rB3acbe2d1e933}

Lead to crash when insert_keyframe_direct() was called. Keyframing
crashed for NLA special properties (influence, animated_time),
driven properties, etc.
2022-04-15 13:45:00 -04:00
089e701191 Fix T97363: Duplicate elements node doesn't tag loose edges 2022-04-15 12:38:34 -05:00
4e6c0669e3 Cleanup: fix warning for differing parameter names 2022-04-15 13:21:07 -04:00
0f9057390d Cleanup: Clang tidy 2022-04-15 11:59:02 -05:00
7484f274dc Curves: Port curve to mesh node to the new data-block
This commit changes the Curve to Mesh node to work with `Curves`
instead of `CurveEval`. The change ends up basically completely
rewriting the node, since the different attribute storage means that
the decisions made previously don't make much sense anymore.

The main loops are now "for each attribute: for each curve combination"
rather than the other way around, with the goal of taking advantage
of the locality of curve attributes. This improvement is quite
noticeable with many small curves; I measured a 4-5x improvement
(around 4-5s to <1s) when converting millions of curves to tens of
millions of faces. I didn't obverse any change in performance compared
to 3.1 with fewer curves though.

The changes also solve an algorithmic flaw where any interpolated
attributes would be evaluated for every curve combination instead
of just once per curve. This can be a large improvement when there
are many profile curves.

The code relies heavily on a function `foreach_curve_combination`
which calculates some basic information about each combination and
calls a templated function. I made assumptions about unnecessary reads
being removed by compiler optimizations. For further performance
improvements in the future that might be an area to investigate.
Another might be using a "for a group of curves: for each attribute:
for each curve" pattern to increase the locality of memory access.

Differential Revision: https://developer.blender.org/D14642
2022-04-15 10:15:48 -05:00
cc6db8921b GPU: Make viewport not acquireable during rendering
This is a partial fix to the fact that rendering with EEVEE or other GL
render engines is currently blocking the whole UI when asking to redraw
a viewport.

This patch just bypasses the viewport bind (containing the Draw Context
lock) and the following drawing. There is an update tagging to not
loose a viewport update if there was one asked.

Other queries other than view redraw (such as selection depth drawing or
offscreen drawing) will still block the whole UI as they need immediate
data feedback.

Ping @Severin for the change in `WM_draw_region_viewport_bind()`.
I'm assuming this is not an issue because it's highly unlikely to
bring up this operator during rendering. But in this case, it would just
lock as usual.

The bypassing in `DRW_notify_view_update` might be a bit overparanoid.
2022-04-15 17:09:30 +02:00
47d961a4b1 Fix: Apply tilt in curves data-block normals calculation
The ported normal calculation from ceed37fc5c neglected to
use the tilt attribute to rotate the normals around the tangents.
This commit adds that behavior back, adding a new math header file
to avoid duplicating the rotation function for normalized axes.

Differential Revision: https://developer.blender.org/D14655
2022-04-15 09:54:45 -05:00
Jeroen Bakker
e96a809a68 PBVH Pixel extractor.
This patch contains an initial pixel extractor for PBVH and an initial paint brush implementation.
PBVH is an accelleration structure blender uses internally to speed up 3d painting operations.
At this moment it is extensively used by sculpt, vertex painting and weight painting.

For the 3d texturing brush we will be using the PBVH for texture painting.
Currently PBVH is organized to work on geometry (vertices, polygons and triangles).
For texture painting this should be extended it to use pixels.

{F12995467}

Screen recording has been done on a Mac Mini with a 6 core 3.3 GHZ Intel processor.

# Scope

This patch only contains an extending uv seams to fix uv seams. This is not actually we want, but was easy to add
to make the brush usable.

Pixels are places in the PBVH_Leaf nodes. We want to introduce a special node for pixels, but that will be done
in a separate patch to keep the code review small. This reduces the painting performance when using
low and medium poly assets.

In workbench textures aren't forced to be shown. For now use Material/Rendered view.

# Rasterization process

The rasterization process will generate the pixel information for a leaf node. In the future those
leaf nodes will be split up into multiple leaf nodes to increase the performance when there
isn't enough geometry. For this patch this was left out of scope.

In order to do so every polygon should be uniquely assigned to a leaf node.

For each leaf node
   for each polygon
     If polygon not assigned
       assign polygon to node.

Polygons are to complicated to be used directly we have to split the polygons into triangles.

For each leaf node
  for each polygon
    extract triangles from polygon.

The list of triangles can be stored inside the leaf node. The list of polygons aren't needed anymore.
Each triangle has:

    poly_index.
    vert_indices
    delta barycentric coordinate between x steps.

Each triangle is rasterized in rows. Sequential pixels (in uv space) are stored in a single structure.

    image position
    barycentric coordinate of the first pixel
    number of pixels
    triangle index inside the leaf node.

During the performed experiments we used a fairly simple rasterization process by
finding the UV bounds of an triangle and calculate the barycentric coordinates per
pixel inside the bounds. Even for complex models and huge images this process is
normally finished within 0.5 second. It could be that we want to change this algorithm
to reduce hickups when nodes are initialized during a stroke.

Reviewed By: brecht

Maniphest Tasks: T96710

Differential Revision: https://developer.blender.org/D14504
2022-04-15 16:40:01 +02:00
25196f8a36 EEVEE: Support disabling all lightprobe object contribution in viewport
This is supported throught the visibility toggle. The light cache will
then only be used for world lighting. This is the behavior as light
objects.
2022-04-15 14:05:18 +02:00
2839fe9a4d Curves: initial geometry nodes support for curves objects
* Curves objects now support the geometry nodes modifier.
* It's possible to use the curves object with the Object Info node.
* The spreadsheet shows the curve data.

The main thing holding this back currently is that the drawing code
for the curves object is very incomplete. E.g. it resamples the curves
always in the end, which is not expected for curves in general.

Differential Revision: https://developer.blender.org/D14277
2022-04-15 09:08:50 +02:00
Wayde Moss
db6287873c Object: Set Parent (Keep Transform Without Inverse)
**Relevant to Artists:** This patch adds an option to the Parenting
menu, `Object (Keep Transform Without Inverse)`, and Apply menu, `Parent
Inverse`. The operators preserve the child's world transform without
using the parent inverse matrix. Effectively, we set the child's origin
to the parent. When the child has an identity local transform, then the
child is world-space aligned with its parent (scale excluded).

**Technical:** In both cases, the hidden parent inverse matrix is
generally set to identity (cleared or "not used") as long as the parent
has no shear. If the parent has shear, then this matrix will not be
entirely cleared. It will contain shear to counter the parent's shear.
This is required, otherwise the object's local matrix cannot be properly
decomposed into location, rotation and scale, and thus cannot preserve
the world transform.

If the child's world transform has shear, then its world transform is
not preserved. This is currently not supported for consistency in the
handling of shear during the other parenting ops: Parent (Keep
Transform), Clear [Parent] and Keep Transform. If it should work, then
another patch should add the support for all of them.

Reviewed By: sybren, RiggingDojo
Differential Revision: https://developer.blender.org/D14581
2022-04-14 20:25:06 -04:00
48ff456a4b Fix T96875: Envelope modifier strokes cannot be eselected with Tweak
The new created strokes were not setting the right `orig` pointers, so the select operator could not select the strokes and points.

Now, the original pointers are set in the new strokes. To set the values is necessary assign the original pointer from the reference stroke because in modifiers the stroke is evaluated, so we need back two levels: Eval->Eval->Orig
2022-04-14 21:51:38 +02:00
48d2f536e1 Fix crash when loading Blender due to recent change
Issue introduced in {rB80859a6cb272}

Only seen on Windows.

The `keyword_parse` lambda function code did not consider `\r` as a
whitespace char, resulting in a wrong parse.

(More investigation needs to be done).
2022-04-14 15:54:09 -03:00
05715eaea1 Fix: Use after free when removing attribute on instances
Assume that only one layer matches the id and return instead
of continuing to iterate over attributes after the layers have
been potentially reallocated.
2022-04-14 13:04:23 -05:00
80859a6cb2 GPU: Make nodetree GLSL Codegen render engine agnostic
This commit removes all EEVEE specific code from the `gpu_shader_material*.glsl`
files. It defines a clear interface to evaluate the closure nodes leaving
more flexibility to the render engine.

Some of the long standing workaround are fixed:
- bump mapping support is no longer duplicating a lot of node and is instead
  compiled into a function call.
- bump rewiring to Normal socket is no longer needed as we now use a global
  `g_data.N` for that.


Closure sampling with upstread weight eval is now supported if the engine needs
it.

This also makes all the material GLSL sources use `GPUSource` for better
debugging experience. The `GPUFunction` parsing now happens in `GPUSource`
creation.

The whole `GPUCodegen` now uses the `ShaderCreateInfo` and is object type
agnostic. Is has also been rewritten in C++.

This patch changes a view behavior for EEVEE:
- Mix shader node factor imput is now clamped.
- Tangent Vector displacement behavior is now matching cycles.
- The chosen BSDF used for SSR might change.
- Hair shading may have very small changes on very large hairs when using hair
  polygon stripes.
- ShaderToRGB node will remove any SSR and SSS form a shader.
- SSS radius input now is no longer a scaling factor but defines an average
  radius. The SSS kernel "shape" (radii) are still defined by the socket default
  values.

Appart from the listed changes no other regressions are expected.
2022-04-14 18:47:58 +02:00
66dc4d4efb Cleanup: Alembic, use a structure to pass parameters
This adds a structure, `ABCReadParams`, to store some parameters passed
to `ABC_read_mesh` so we avoid passing too many parameters, and makes it
easier to add more parameters in the future without worrying about
argument order.

Differential Revision: https://developer.blender.org/D14484
2022-04-14 17:48:31 +02:00
45f30543db Fix T97135: Fix selection issues with parented masks in the MCE
Box, Circle and Lasso select were not taking into account if a
mask(point) was parented; selection was only succeeding in the original
place.

Now check coordinates from evaluated mask (points) instead while
setting selection flags and DEG tagging still happens on the original ID.

Maniphest Tasks: T97135

Differential Revision: https://developer.blender.org/D14651
2022-04-14 16:59:50 +02:00
ad245a25e2 Fix T85756: Adjust Last Operation panel is slow.
Extremely subttle bug that would only appear in some specific
circumstances, would cause memfile undo writing code to falsely detect
some ID as changed because it would get the wrong 'starting point' of
comparison with existing previous memfile step.

See T85756 for detailed explanation and reproducible case.
2022-04-14 16:46:51 +02:00
c71013082d Geometry Nodes: show used named attributes in nodes
This adds a new node editor overlay that helps users to see where
named attributes are used. This is important, because named
attributes can have name collisions between independent node
groups which can lead to hard to find issues.

Differential Revision: https://developer.blender.org/D14618
2022-04-14 16:31:09 +02:00
a9b94e5f81 Fix T95700: Oject Info node does not work with GPU subdivided meshes
When GPU subdivision is enabled the mesh objects remain unsubdivided on
the CPU side, and subdivision should be requested somewhat manually (via
`BKE_object_get_evaluated_mesh`).

When referencing an object, the Object Info node calls
`bke::object_get_evaluated_geometry_set` which first checks if a Geometry
Set is present on the object (unless we have a mesh in edit mode). If so
it will return it, if not, the object type is discriminated, which will
return a properly subdivided mesh object via `add_final_mesh_as_geometry_component`.

The unsubdivided mesh is returned because apparently the check on the
Geometry Set always succeeds (as it is always set in `mesh_build_data`).
However, the mesh inside this Geometry Set is not subdivided.

This adds a check for a MeshComponent in this Geometry Set, and if one
exists, calls `add_final_mesh_as_geometry_component` which will ensure
that the mesh is subdivided on the CPU side as well.

Differential Revision: https://developer.blender.org/D14643
2022-04-14 15:11:58 +02:00
31b2b84b3c Fix T97262: Crash with specific view layer setup
Originally was noticed when using a linked background scene and a scene
camera from another (local) scene.

The root issue was that relation from view layer to object's base flags
evaluation was using wrong view layer. This is because the relation was
created between object and currently built view layer, and it only was
happening once (since the object-level relations are only built once).
Depending on order in which `build_object` was called it was possible
that relation from a wrong view layer was used.

Now the code is better split to indicate which parts of object relations
are built when object comes from a base in the view layer, and which ones
are built on indirect linking of object to the dependency graph.

This patch makes relations correct in the cases when the same object is
used as a base in both active and set scenes. But, the operation which
handles object-level flags might not behave correctly as there is no
known design of what is the proper thing to do in this case. Making a
clear design and implementation of case when object is shared between
active and set scene is outside of the scope of this patch.

Differential Revision: https://developer.blender.org/D14626
2022-04-14 14:57:49 +02:00
1440074cac Tests: Change force disable render test messages to be warnings
These were easilly missable and took some effort to find why the test
were disabled.
2022-04-14 13:10:26 +02:00
c9574412c7 Curves: fix some issues with operator to convert to particle system
Ref T97171.

Differential Revision: https://developer.blender.org/D14637
2022-04-14 12:25:54 +02:00
Jason Fielder
8f0e06a0ca Metal: GPU_PRIM_LINE_LOOP alternative implementations.
Prefer using immVertex3f when 3D shaders are used for 2D rendering due to overhead of vertex padding in hardware. CPU overhead is negligible.

Authored by Apple: Michael Parkin-White

Ref T96261

Reviewed By: fclem

Maniphest Tasks: T96261

Differential Revision: https://developer.blender.org/D14494
2022-04-14 12:01:31 +02:00
Jason Fielder
e28f07b5c8 Metal: GLSL shader compatibility 4th pass
MSL follows C++ standard convention, and such variable declarations within switch statements must have their scope localised within each case. Adding braces in all cases ensures correct behaviour and avoids 'case ... bypass initialization of local variable' compilation error.

struct initialisation to follow C++ rules for Metal. Implicit constructors replaced with either explicit constructors or list-initialization where appropriate.

Ref T96261

Authored by Apple: Michael Parkin-White

Reviewed By: fclem

Maniphest Tasks: T96261

Differential Revision: https://developer.blender.org/D14451
2022-04-14 12:00:39 +02:00
3acbe2d1e9 NLA: Keyframe Remap Through Upper Strips
Add a new operator, "Start Tweaking Strip Actions (Full Stack)", which
allows you to insert keyframes and preserve the pose that you visually
keyed while upper strips are evaluating,

The old operator has been renamed from "Start Tweaking Strip Actions" to
"Start Tweaking Strip Actions (Lower Stack)" and remains the default for
the hotkey {key TAB}.

**Limitations, Keyframe Remapping Failure Cases**:
1. For *transitions* above the tweaked strip, keyframe remapping will
   fail for channel values that are affected by the transition. A work
   around is to tweak the active strip without evaluating the upper NLA
   stack.

   It's not supported because it's non-trivial and I couldn't figure it
   out for all transition combinations of blend modes. In the future, it
   would be nice if transitions (and metas) supported nested tracks
   instead of using the left/right strips for the transitions. That
   would allow the transitioned strips to overlap in time. It would also
   allow  N strips to be part of the (previously) left and right strips,
   or perhaps even N strips being transitioned in sequence (similar to a
   blend tree). Proper keyframe remapping through all that is currently
   beyond my mathematical ability. And even if I could figure it out,
   would it make sense to keyframe remap through a transition?

   //This case is reported to the user for failed keyframe insertions.//

2. Full replace upper strip that contains the keyed channels.

   //This case is reported to the user for failed keyframe insertions.//

3. When the same action clip occurs multiple times (colored Red to
   denote it's a linked strip) and vertically overlaps the tweaked
   strip, then the remapping will generally fail and is expected to
   fail.

   I don't plan on adding support for this case as it's also non-trivial
   and (hopefully) not a common or expected use case so it shouldn't be
   much of an issue to lack support here.

   For anyone curious on the cases that would work, it works when the
   linked strips aren't time-aligned and when we can insert a keyframe
   into the tweaked strip without modifying the current frame output of
   the other linked strips. Having all frames sampled and the strip
   non-time aligned leads to a working case. But if all key handles are
   AUTO, then it's likely to fail.

   //This case is not reported to the user for failed keyframe
   insertions.//

4. When using Quaternions and a small strip influence on the tweaked
   Combine strip. This was an existing failure case before this patch
   too but worth a mention in case it causes confusion. D10504 has an
   example file with instructions.

   //This case is not reported to the user for failed keyframe insertions. //

5. When an upper Replace strip with high influence and animator keys to
   Quaternion Combine (Replace is fine). This case is similar to (4)
   where Quaternion 180 degree rotation limitations prevent a solution.

   //This case is not reported to the user for failed keyframe insertions.//

Reviewed By: sybren, RiggingDojo

Differential Revision: https://developer.blender.org/D10504
2022-04-14 11:55:08 +02:00
Jason Fielder
b0dc3aff2c Metal: GLSL shader compatibility 3rd pass
Undefined behaviour for divergent control-flow fixes, replacement for partial vector references, and resolution of a number of calculation precision issues occuring on macOS.

Authored by Apple: Michael Parkin-White

Ref: T96261

Reviewed By: fclem

Differential Revision: https://developer.blender.org/D14437
2022-04-14 11:49:18 +02:00
Ethan-Hall
d62f443f2d GPUTexture: Fixed typo where wrong enum was used
This patch fixes a typo in commit e59f754c16 which incorrectly uses `GPU_TEXTURE_ARRAY` instead of `GPU_FORMAT_COMPRESSED`.

`GPU_FORMAT_COMPRESSED` and `GPU_TEXTURE_ARRAY` both currently evaluate to 16,  so this patch does not change anything functionally; however, this patch will prevent issues from arising in the future.

Reviewed By: fclem

Differential Revision: https://developer.blender.org/D14384
2022-04-14 11:46:49 +02:00
Colin Basnett
f1ae6952a8 Animation: Select markers before/after current frame
Add operator to select markers left/right of the current frame
(including the current frame).

`bpy.ops.marker.select_leftright(mode='LEFT', extend=False)`

`mode` can be either 'LEFT' or 'RIGHT'.

The naming and defaults of the above variables match similar operators
(e.g., `bpy.ops.nla.select_leftright`)

This also adds a new sub-menu to the Marker menu found in animation
editors, exposing both the new `bpy.ops.marker.select_leftright`
operator as well as the `bpy.ops.marker.select_all` operator.

Despite the name "Before Current Frame" and "After Current Frame", it
also selects a marker that falls on the current from for both of the
modes. This is to match the behavior found in the `nla.select_leftright`
operator.

RCS: https://blender.community/c/rightclickselect/OgmG/

Reviewed by: sybren, looch

Differential Revision: https://developer.blender.org/D14176
2022-04-14 11:30:12 +02:00
RedMser
d6e7241237 Animation: Add F2 for renaming markers
F2 allows renaming lots of different types of active items, and now it
also works for markers.

Before, Ctrl+M was used, and it's context-sensitive: you often get
"Mirror Keys" instead, when your cursor isn't on the markers region, and
that operator has nothing to do with either renaming or markers.

**What this commit does:**

- Replace Ctrl+M shortcut with F2.
  - Adds the `TOPBAR_PT_name_marker` panel which is implemented similar
    to the global rename panel. This having to press enter twice to
    confirm or escape twice to cancel, which would happen if the
    `marker.rename` operator was called directly.
- Replace usages of `marker.rename` in the UI with `wm.call_panel`.
- To make the Industry Compatible keymap consistent with Blender
  Default, the rename shortcut only works when hovering the markers
  area.

Reviewed By: ChrisLend, sybren

Differential Revision: https://developer.blender.org/D12298
2022-04-14 10:58:14 +02:00
4fa3eadce9 Icons: Re-sync Blender with latest svn icon file
There are no real difference from the previous icons, but since some
manual changes were introduced in the icons file, we still needed
a final sync between them.
2022-04-14 09:57:15 +02:00
b1908f2e0b View 3D: disable object mode selection cycling on first-click
Unlike regular selection cycling that is activated when clicking again
in the same location, object mode would cycle to another object
if the object that was selected happened to already be active.

This made it impossible to click-drag to tweak the active object
if there were other objects behind it as those would be activated first.

Resolves T96752.
2022-04-14 17:20:36 +10:00
678b76d99a Correct error in 405bff7fd8
Was adding 1 to dietime twice in init_particle_interpolation.
2022-04-14 17:03:01 +10:00
405bff7fd8 Fix T68290: Baked particles don't render in final frame
Particles baked into memory would never load the final frame because
of an off-by-one error calculating the particles `dietime`.

This value indicates the frame which the particle ceases to exist but
was being set to the end-frame which caused this bug as the scenes
end-frame is inclusive.

While the last frame was properly written and read from memory,
the `dietime` was set to the last frame causing all the particles to be
considered dead when calculating the cached particle system.
2022-04-14 16:58:15 +10:00
bc8dcf6db7 Cleanup: unused argument warning 2022-04-14 16:58:09 +10:00
180163c4e4 Cleanup: Further hair to curves renaming
These were missed in previous passes. Also remove some logic
in `draw_hair.c` that was redundant after f31c3f8114.
2022-04-13 22:52:09 -05:00
f31c3f8114 Curves: Split curve EEVEE/workbench functions from particle hair
The GPU evaluation for curves will have to change significantly from the
current particle hair drawing code, due to its more general use cases
and support for more curve types. To simplify that process and avoid
introducing regressions for the rendering of hair particle systems,
this commit splits drawing functions for the curves object and
particle hair.

The changes are just inlining of functions and copying code
where necessary.

Differential Revision: https://developer.blender.org/D14576
2022-04-13 22:07:31 -05:00
f84f9eb8ed Fix T96563: tangents artifacts with GPU subdivision
When tangent are computed from generated coordinates, the result for GPU
subdivision would be compressed to 16-bit when it shouldn't.
2022-04-14 03:49:44 +02:00
3e25561d51 Fix part of T96596: wrong generated coordinates with GPU subdivision
Problem is that the orco layer was not taken care of by the GPU
subdivision routines. This only handles the issues for EEVEE/Workbench.
For Cycles, this would need to be handled at the wrapper level somehow.
2022-04-14 03:39:28 +02:00
927cb5bfac Cleanup: separate format-units for Python argument parsing
Recent addition to the Python API [0] didn't follow this convention.
See [1] for the rationale behind this change.

[0]: 9bc678969a
[1]: 982aea88e0
2022-04-14 11:21:51 +10:00
f076493dbb Keymap: restore key-shortcut to remove from local-view
Use Alt-Slash to remove objects from local-view (was M prior to [0]),
following the convention of using Alt to perform the reverse of an
action. Also remove the confirmation menu as this key as it can be
undone and it's not likely to be pressed by accident.

This can be useful to quickly subtract items from a complex selection
with items that only become visible when entering local-view.

The M key was originally used in 2.4x since moving between layers wasn't
possible. Now moving between collections is possible in local-view
the keys collided.

[0]: cf5d582b77
2022-04-14 11:14:32 +10:00
3f305b9ab3 Fix T97053: on cage GPU subdivision shows subdivided edges as actual
edges

When wireframe mode is turned on, the subdivision edges not originating
from coarse edges were also drawn as regular edges, which would confuse
users trying to select them. These should not be drawn in edit mode,
only in object mode when optimal display is turned off (matching the CPU
subdivision case).
2022-04-14 03:04:37 +02:00
8826db8f03 Fix T97310: BLF Line Height While Text Wrapping
Fix word-wrapped tooltip text not showing by aligning to pixel grid.

See D14639 for more details.

Differential Revision: https://developer.blender.org/D14639

Reviewed by Campbell Barton
2022-04-13 17:45:32 -07:00
8e4c3c6a24 Cleanup: Make curve deform argument optional
The "dir" argument to `BKE_where_on_path` was only actually
used in a few places. It's easier to see where those are if there
isn't always a dummy argument.
2022-04-13 19:22:10 -05:00
0ba061c3bc Edit Mesh: Parallelize bounds calculation with deform modifiers
When displaying a deform modifier in edit mode, a cached
array of positions is used. Parallelizing bounds calculation when
that array exists can improve the framerate when editing slightly
(a few percent). I observed an improvement of the min/max itself
of about 10x (4-5ms to 0.4ms).
2022-04-13 18:49:11 -05:00
232b388455 Cleanup: Declare variables where initialized
Also adjust comment formatting and use nullptr
where the previous commit missed.
2022-04-13 18:02:21 -05:00
ad3378215c Cleanup: Clang tidy 2022-04-13 17:51:20 -05:00
abd02da4bd Cleanup: Move three mesh files to C++
This will allow easier interaction with other areas also using C++
features, and a potential optimization to edit mesh bounding box
calculation.
2022-04-13 17:51:05 -05:00
5a98e38275 Curves: Avoid duplicating evaluated positions with all poly curves
If all of the curves are poly curves, the evaluated positions are the
same as the original positions. In this case just reuse the original
positions span as the evaluated positions.
2022-04-13 17:13:30 -05:00
078aa677b6 Fix: Curves: Add missing builtin attribute definition 2022-04-13 17:05:35 -05:00
a8ee279aa9 Fix: Use consistent type for nurbs order attribute
An 8 bit integer should be enough for now. We can change this if we ever
want to allow increasing the order past 256.
2022-04-13 17:00:18 -05:00
94495049a8 Fix: Assert evaluating single point Bezier curve
Just return early in that case to keep the rest of the function simpler.
2022-04-13 16:57:13 -05:00
95236d8a75 Rename Color Attributes domain from "Point" to "Vertex"
Addresses T97257, to make it consistent with regular attributes tab

Review by: Julian Kaspar

Differential Revision: https://developer.blender.org/D14631
Ref D14631
2022-04-13 09:53:31 -07:00
6da5ee8368 Fix: compilation error with MSVC
Similar issue as e22fd7247a.
2022-04-13 10:15:00 -06:00
Hallam Roberts
7dc4ac71e8 Fix T97278: wrong hair particle shape with kink spiral
Revert change from 3da84d8b that incorrectly used M_PI_4.

Differential Revision: https://developer.blender.org/D14636
2022-04-13 16:23:47 +02:00
9c09e5ba24 Fix some usages of 'GPU_shader_get_uniform_block'
`GPU_shader_get_uniform_block` is marked as deprecated and the value
returned does not match what `GPU_uniformbuf_bind` expects.

Also, small typo fix in python error message.

Differential Revision: https://developer.blender.org/D14638
2022-04-13 10:51:51 -03:00
e22fd7247a Fix compilation error with MSVC
Caused by previous DNA change.
2022-04-13 15:19:36 +02:00
fb84408aa5 Cleanup: Update icons_geom CMakeLists.txt 2022-04-13 15:18:16 +02:00
0a57d6d076 Docs: correct RST syntax for GPU documentation 2022-04-13 22:39:26 +10:00
24fea2bdc4 Cleanup: Split paint_canvas into BKE and ED.
The BKE part is needed for the 3d texture paiting brush to be part of blender
kernel.
2022-04-13 14:27:19 +02:00
babd027fae Cleanup: make format 2022-04-13 12:30:29 +02:00
cf5d582b77 Fix T97207: Move to Collections Menu Grayed out when in Local View
This behaviour was introduced in a687d98e67 to bring the old obscure
"M" operator to remove objects from the local view. In order to avoid
the keymap clash with the Move to Collection operator, the Move to
Collection was artificially restricted to work in local view.

In retrospect, the "Remove from Local View" operator is in the menu anyways,
so it didn't even need to have a shortcut (back in 2.79 the operator was
not in a menu).

The changes introduced here are:
* No shortcut for "Remove from Local View"
* No more restrictions to "Move/Link to Collection" from local view.

Thanks for Philipp Oeser for digging the old commit that introduced this
and for the rationale on the changes.
2022-04-13 12:29:19 +02:00
c31b89e76e Cycles: Add support for "stageMetersPerUnit" Hydra render setting
This can be useful to match transforms to what native Cycles
would see in Blender, as USD typically uses centimeters, but
Blender uses meters. This patch also fixes the hardcoded focal
length multiplicator, which is now using the same units as
everything else. Default of "stageMetersPerUnit" is 0.01 to match
the USD default of centimeters.

Differential Revision: https://developer.blender.org/D14630
2022-04-13 12:24:21 +02:00
3a88f151c4 Cleanup: Proper printing of a string
Print it as a "%s" so that possible percentage symbols in the
error message does not cause issues.

Use proper assert (assert(true) is a no-op).

Also use `empty()` instead of `length()`.

Reviewed with Clement in real life.
2022-04-13 11:55:37 +02:00
402845744f Cleanup: Strict compiler warning in remesher 2022-04-13 11:51:38 +02:00
25c357124d Cover some DNA files with C++ utility macros
Solves compilation warning with Clang, and moves manipulation with
DNA structures to the designed way for C++.

The tests and few other places are update to the new code by Jacques.

Ref T96847

Maniphest Tasks: T96847

Differential Revision: https://developer.blender.org/D14625
2022-04-13 11:48:12 +02:00
da66c0519f Fix (unreported) collections not being append-reusable.
Related to T97289, appending collections would never re-use already
appended one, since the flag was not set for this ID type...
2022-04-13 10:28:48 +02:00
a63982a65b Fix T97289: Linked collection assets disappear.
After appending, new link/append code would delete linked IDs, even if
those where pre-existing. Note that this would actually lead to invalid
memory access later in append code (ASAN crash).
2022-04-13 10:28:48 +02:00
4a70561bbd Fix T97164: Voxel remesh only supports vertex float
color attributes.

Voxel remesher now supports all color attribute
types.
2022-04-13 00:48:10 -07:00
e0c8d0913b Curves: remove Test1 brush
This was one of multiple placeholder brushes to simplify development.
Having it is not necessary anymore.

It was a brush that could add new curves according to a specific density.
This functionality will be brought back as a new brush later.

Ref T97255.
2022-04-13 09:27:54 +02:00
d1418dd151 Updated voxel remesher defaults
Implements T97163
Newly created meshes have all voxel remesher checkboxes aside from Fix Poles enabled.
Startup files updated with versioning.

Reviewed By @JulianKaspar
Differential Revision: https://developer.blender.org/D14608
Ref D14608
2022-04-12 23:33:36 -07:00
567aad9dcd Fix T97152: Selection tools do nothing in particle hair edit
Regression in [0] which caused canceled PRESS events not to generate
CLICK_DRAG.

Resolve by checking for an active brush tool in poll instead of the
PARTICLE_OT_brush_edit invoke function.

[0]: 4d0f846b93,
2022-04-13 16:27:21 +10:00
9a659f2573 WM: improve logging for handling operators
- Add logging for CLICK_DRAG event handling to debug drag events.
- Use logging API for reporting the key-map, operator and event.

This command now prints useful information for investigating
key-map and event handling issues:

  blender --log "wm.handler.*" --log-level 4
2022-04-13 16:10:32 +10:00
02de1bff1e Cleanup: warning for 'float' to 'int' with MSVC 2022-04-13 14:22:58 +10:00
7d3db7a3ae Cleanup: use C++ comments for disabled code
Also ensure space around text in C-comment blocks.
2022-04-13 13:47:04 +10:00
4b5195a9d7 Cleanup: clang-format 2022-04-13 13:45:42 +10:00
21ae323dbf Cleanup: avoid redundant float/int conversions in BLF
Internally many offsets for BLF were integers but exposed as floats,
since these are used in pixel-space, many callers were converging them
back to integers. Simplify logic by using ints.
2022-04-13 13:06:29 +10:00
ae43872ad5 BLF: sub-pixel positioning support
Support sub-pixel kerning and hinting for future support for improved
character placement. No user visible changes have been made.

- Calculate sub-pixel offsets, using integer maths.
- Use convenience functions to perform the conversions and hide the
  underlying values.
- Use `ft_pix` type to distinguish values that use sub-pixel integer
  values from freetype and values rounded to pixels.

This was originally based on D12999 by @harley with the user visible
changes removed so they can be applied separately.
2022-04-13 11:58:42 +10:00
d0a70adf8f Cleanup: shadowed variable warning 2022-04-13 11:57:45 +10:00
af17676005 gpy.types.GPUUniformBuf: support any object exposing buffer interface
Since uniform buffers are generally structs and not sequences,
`BPyGPU_BufferType` objects are not suitable for filling the buffer.
2022-04-12 22:44:57 -03:00
132576ebb1 gpu.types.Buffer: fill buffer interface with just what is requested
Use the `flags` parameter to avoid unnecessary allocations.
2022-04-12 22:34:52 -03:00
8fad71799f Fix size of MAT3 and MAT4 in GPUShaderCreateInfo.push_constant
It was being wrongly multiplied by 2.
2022-04-12 22:31:27 -03:00
17a19069db Fix cases where 'Py_buffer' might not be released 2022-04-12 22:16:09 -03:00
cd4a9c488f Fix possible pointer being freed without being allocated in pygpu module
The `clear` method can be called before dealloc, which can
mislead buffer ownership.
2022-04-12 20:52:50 -03:00
Germano Cavalcante
9bc678969a pyGPU: Port 'StageInterfaceInfo' and 'ShaderCreateInfo' types
In order to allow GLSL Cross Compilation across platforms, expose in
Python the `GPUShaderCreateInfo` strategy as detailed in
https://wiki.blender.org/wiki/EEVEE_%26_Viewport/GPU_Module/GLSL_Cross_Compilation

The new features can be listed as follows:
```
>>> gpu.types.GPUShaderCreateInfo.
                                  define(
                                  fragment_out(
                                  fragment_source(
                                  push_constant(
                                  sampler(
                                  typedef_source(
                                  uniform_buf(
                                  vertex_in(
                                  vertex_out(
                                  vertex_source(

>>> gpu.types.GPUStageInterfaceInfo.
                                    flat(
                                    name
                                    no_perspective(
                                    smooth(

>>> gpu.shader.create_from_info(
```

Reviewed By: fclem, campbellbarton

Differential Revision: https://developer.blender.org/D14497
2022-04-12 18:50:56 -03:00
359b6baf32 Fix: Assert when curve has no evaluated points
It is valid for NURBS curves to have no evaluated points in some cases.
2022-04-12 14:56:14 -05:00
b1d915d027 Cleanup: Remove reference to CD_NORMAL in poly custom data
Vertex and face normals are not stored in custom data anymore,
in both Mesh and DerivedMesh.
2022-04-12 13:55:41 -05:00
88ab34488b Cleanup: Correct wording in comments 2022-04-12 13:55:41 -05:00
Michael Jones
869a46df29 Cycles fp consistency for Apple Silicon CPUs
Propagate the fp settings from the main thread to all the worker threads (the fp settings includes the FZ settings among other things) - this guarantees consistency in execution of floating point math regardless if its executed in tbb thread arena or on main thread

Add FZ mode to arm64/aarch64 in parallel to the way its been done on intel processors, currently compiling for arm target does not set this mode at all, hence potentially runs slower and with possible results mismatch with intel x86.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D14454
2022-04-12 19:43:47 +01:00
2d472b70e5 Revert "Cycles: enable HIP for Vega and Vega II (Radeon 7) GPUs on Windows"
This is not currently working, reverting until the driver/compiler has a fix.

This reverts commit c46e58817c.
2022-04-12 19:18:58 +02:00
a0957ceab2 Fix T97069: Null collection object during layercollection resync when relinking.
We better handle NULL object pointers before doing layer collections
resync, otherwise said resync process has to deal with those NULL
pointers. By the look of it this mistake has been there since the origin
of the remapping/relinking code.

Also for safety (and optimization), do not perform layer collection
resync from `libblock_remap_data_postprocess_object_update` when
`libblock_remap_data_postprocess_collection_update` is called
immediately afterwards.

Also added same 'skip on NULL collection object pointer' check to
`layer_collection_local_sync` as the one in
`layer_collection_objects_sync`, since it's fairly hard to always
guaranty there is no such NULL pointer when calling that code.
2022-04-12 18:43:26 +02:00
48014fbf14 Fix (unreported) use-after-free case in Properties Editor ID remapping code.
Regression in rBa21bca0e20a051, found while investigating T97069.
2022-04-12 18:43:26 +02:00
77db370cb6 Fix: BMesh Python API errors after vertex_normals addition
64cd927519 didn't update the argument parsing strings,
and updated the docstring of `from_object` incorrectly.

Fixes T97025, T97213
2022-04-12 11:08:21 -05:00
05a1770ab0 Fix T97280: Typo in tooltip of image texture node 2022-04-12 17:36:12 +02:00
ee9688da99 Cleanup: redundant logical not
Overlooked at rB0ebcc711f.

The logical not in this case was only applied to the left hand side of
the comparison.
2022-04-12 10:02:33 -03:00
d1944dee86 Cleanup: remove unused multi-function 2022-04-12 11:59:23 +02:00
5cae213750 Cleanup: pass vectors by reference
Passing them by value caused measurable overhead for me.
2022-04-12 11:56:02 +02:00
b4a2096415 Fix T95679: Outliner 'Unlink' directly on action misses DEG update
Animation would still play in the viewport.

There are two ways to unlink an action from the Outliner:
[1] `Unlink Action` on the Animation Data context menu.
This does `outliner_do_data_operation` / `unlinkact_animdata_fn` and has
the correct DEG update.
[2] `Unlink` on the Action context menu
This does `outliner_do_libdata_operation` / `unlink_action_fn` and was
missing the DEG update.

Now add the missing DEG update to the second case.

Maniphest Tasks: T95679

Differential Revision: https://developer.blender.org/D14089
2022-04-12 11:16:45 +02:00
4fd3d96f46 Fix Pushdown of an action from the Action Editor lacks immediate updates
The issue reported was that the recently introduced manual framerange of
an action (see rB5d59b38605d6) was not having an immediate effect in
case the action was pushed down from the Action Editor and only showed
its effects after e.g. saving and reloading the file. However doing the
same thing (pushing down the action) was working fine when done from the
NLA.

Now bring pushdown in sync (in terms of DEG update tagging) between the
Action Editor and the NLA, meaning that now both the owner and the
action are tagged when pushdown happens from the Action Editor as well.

Fixes T96964.

Maniphest Tasks: T96964

Differential Revision: https://developer.blender.org/D14564
2022-04-12 11:02:44 +02:00
fbca6aeb7c Fix T97132: Create a color attribute automatically
for color filter tool instead of canceling.
2022-04-11 23:25:56 -07:00
4a3bcfa102 Fix T97100: Fix ordering in color attribute list items
The new tab in the properties panel for "Color Attributes" shows the
data type and domain, just like the Attributes tab.
The issue is that the UI does not scale well and can only display the
full names when dragged to an extreme width.
This is due to the inclusion of the render icon in between the
attribute name and attribute type description.

This patch changes the order that items are displayed in the Color
Attributes Panel. Moving the render icon to the very right.
The result is consistent with other parts of the Blender UI and does
not take as much space to display the full text.

Reviewed By: @jbakker
Differential Revision: https://developer.blender.org/D14567
Ref D14567
2022-04-11 23:08:23 -07:00
d683ea4862 Fix T97098: Color filter sharpening artifacts.
Color filter sharpening now clamps the output.
The sharpening delta is now calculated from the
difference of two levels of vertex averaging instead
of one smooth iteration and the base color.

TODO: Sharpen in a different color space;
SRGB-linear has saturation artifacts.  I
tried HSL but it had value artifacts.  I'd
like to try LAB but we don't seem to have
conversion functions for it (at least as far
as I could see).
2022-04-11 22:54:32 -07:00
2451d7d57e Cleanup: use _NUM suffix for space/region type ranges
- Replace SPACE_TYPE_LAST with SPACE_TYPE_NUM (adding 1).
- Rename RGN_TYPE_LEN to RGN_TYPE_NUM

This makes it possible to tag space-type/region-type combinations
with `bool tag[SPACE_TYPE_NUM][RGN_TYPE_NUM]` which reads more clearly
than `bool tag[SPACE_TYPE_LAST + 1][RGN_TYPE_LEN]`.
2022-04-12 11:59:25 +10:00
6f1ad5f5e7 Fix wrong key type for GSet in Grease Pencil same material selection
The type of the key was changed from string to integer in 66da2f537a, but
the GSet was still being created for string keys.

As long as the integers stay small enough, this even kind of works on
little-endian systems, but of course it should use an integer hash instead.
2022-04-12 00:01:30 +02:00
3c62e539af Cleanup: clang-format 2022-04-11 23:49:37 +02:00
484a914647 UI: Add support for showing socket descriptions in tooltips
Currently, hovering over a socket itself shows no tooltip at all, while
hovering over its value field shows "Default value", which is not helpful.

This patch therefore implements socket tooltips following the proposal at
https://blender.community/c/rightclickselect/2Qgbbc/.

A lot of the basic functionality was already implemented for Geometry Nodes,
where hovering over the socket itself shows introspection info.

This patch extends this by:
- Supporting dynamic tooltips on labels, which is important for good tooltip
  coverage in a socket's region of the node.
- Adding a function to setting a dynamic tooltip for an entire uiLayout, which
  avoids needing to set it manually for a wide variety of socket types.
- Hiding the property label field in a tooltip when dynamic tooltip is also
  provided. If really needed, this label can be restored through the dynamic
  tooltip, but in all current cases the label is actually pointless anyways
  since the dynamic tooltip gives more accurate and specific information.
- Adding dynamic tooltips to a socket's UI layout row if it has a description
  configured, both in the Node Editor as well as in the Material Properties.

Note that the patch does not add any actual tooltip content yet, just the
infrastructure to show them. By default, sockets without a description still
show the old "Default value" tooltip.

For an example of how to add socket descriptions, check the Cylinder node
in the Geometry Nodes.

Differential Revision: https://developer.blender.org/D9967
2022-04-11 23:40:48 +02:00
Ethan-Hall
b3525c3487 UI: make snap self inactive if proportional editing
When using proportional editing, the 'project onto self' snap setting
is ignored since proportional editing does not allow snapping to
self. The UI should reflect this fact. This patch makes 'project onto
self' active only when proportional editing is off.

Reviewed By: mano-wii

Differential Revision: https://developer.blender.org/D14496
2022-04-11 17:32:24 -03:00
4aa9888854 PyGPU: make sure the UniformBuffer is padded to 16 bytes
Alignment with `vec4` is a requirement in C++, so it should be a
requirement in Python as well.
2022-04-11 16:59:18 -03:00
07cacb6d14 Fix crash when creating a 'gpu.types.Buffer'
Buffer creation may crash when passed a PyBuffer with no `shape` defined.
(Which is common for strucs).
2022-04-11 16:59:18 -03:00
Christophe Hery
c4f7f59c65 Curves: Add support for new curves type in Set Material node
Simply add the few lines so that the Cycles renderable New Curves
(with a small temporary patch to output the new type to render engines)
would get assigned a shader (in particular a hair shader).

Differential Revision: https://developer.blender.org/D14622
2022-04-11 14:52:20 -05:00
5f2317fa9b Update RNA to user manual references 2022-04-11 15:28:44 -04:00
c65b022e62 Fix OpenColorIO error with configs using <USE_DISPLAY_NAME>
* Don't assume the display colorspace name fully defines the transform
  to display space, this is not true in OpenColorIO 2 where view transforms
  may be defined in more complexs ways than just specifying a colorspace.
* In places where we need to store the display colorspace name, resolve
  <USE_DISPLAY_NAME> token manually.

Ref T96590
2022-04-11 20:10:42 +02:00
a99639792b Fix T97097: Color Filter saturates colors that have no saturation 2022-04-11 10:24:01 -07:00
7163db99c4 Fix T97096: Color filter brush was corrupting alpha. 2022-04-11 10:19:40 -07:00
4aac251b42 Fix adding certain nodes can cause python errors
Adding nodes via `NodeAddOperator` could fail if the node's poll fails
in `rna_NodeTree_node_new`. Examples are trying to add a RenderLayers
node or a Cryptomatte node to a nodegroup.

Now except the python error and use blender error reporting only instead
of throwing full python stacktraces at the user.

Differential Revision: https://developer.blender.org/D14584
2022-04-11 18:49:16 +02:00
e7a69b438f Cleanup: Clarify a few comments in pbvh_intern.h 2022-04-11 09:47:55 -07:00
0329145712 Cleanup: fix attribute.c incorrectly using
CustomDataLayer.type to check for
	 CD_FLAG_TEMPORARY instead of .flag.
2022-04-11 09:40:13 -07:00
0d0a45b89d Fix/workaround i18n script not finding some messages anymore.
For some reasons(c) some base classes (like `bpy.types.Modifier`) are
not listed anymore by a call to
`bpy.types.ID.__base__.__subclasses__()`, unless they are first accessed
explicitely (e.g. by executing `bpy.types.Modifier` etc.).
2022-04-11 15:45:52 +02:00
883dbfb72f Fix T85467: Mask transform center doesn't take parent Track into account
Coordinate checks in `spline_under_mouse_get` need to take place with
the evaluated mask to get the right center. This is now more in line to
how this is done in `ED_mask_point_find_nearest`.

Note: similar issues are reported with box/circle/lasso selection in
T97135, will tackle these separately though.

Maniphest Tasks: T85467

Differential Revision: https://developer.blender.org/D14598
2022-04-11 15:40:55 +02:00
20846596b5 Curves Sculpting Icons: Snake Hook and Grow updates
This implements the icon for snake hook, as well as tweak the
growth brush to make it bigger and with the triangles more
distinct for better reading of the icon.

Differential Revision: https://developer.blender.org/D14616
2022-04-11 15:11:43 +02:00
043555c78f install_deps: Tweak rBbc9c9631a46f, libwebp is not only a dependency from ffmpeg. 2022-04-11 14:52:26 +02:00
Charles Flèche
b6eb7dae59 Fix Cycles missing nullptr check in case mesh has no shader
Did not affect Blender, but could happen with other integrations.

Differential Revision: https://developer.blender.org/D14538
2022-04-11 14:24:59 +02:00
cda3334586 Fix setting key shortcuts for insert keyframe menu items
It was not possible to assign a shortcut to menu items in the insert
key-frame menu going back to version 2.7x. Doing so would replace the
current key that opens the insert keyframe menu (I-key by default),
instead of binding a key to insert a key-frame for the keying-set
referenced by the menu item.

Now each menu item can be bound to a key or added to the "Quick
Favorites" menu, directly inserting a key-frame for the corresponding
keying-set.

Note that users must use the operator `anim.keyframe_insert_by_name`
when setting up key-shortcuts as `anim.keyframe_insert` is only intended
to launch the menu.

Keymap Editor:

When editing these key-map items in the key-map editor, the keying-set
identifier must be used. At the moment the key-map editor doesn't
support showing a drop-down list. The identifiers can be used from the
tool-tip or the info editor.

{F12994924}

Details:

Use `ANIM_OT_keyframe_insert_by_name` instead of
`ANIM_OT_keyframe_insert_menu` for the insert keyframe popup menu to
resolve the following issues binding keys to keying sets:

- The index of the keying set isn't stable (adding/removing keying sets
  may change it).
- Binding a key to items in the popup menu triggers a popup instead of
  inserting a key using the keying set from the menu item.

While support for using the current operator could be improved, it will
still only work for built-in keying sets, so I'd prefer to use an
operator that is intended for key-bindings.

Besides supporting binding keys to menu items there are no functional
changes.

Reviewed By: sybren

Ref D14289
2022-04-11 21:10:05 +10:00
b2143da253 BMesh Python API: add access to vertex crease layer
This simply adds access to the vertex crease layer from Python
code. Documentation was modified to remove "Edge" as it is
shared between edges and vertices, similarly to bevel weights.

Differential Revision: https://developer.blender.org/D14605
2022-04-11 11:54:11 +02:00
e03810693c Cleanup: use doxy-comments and r_ prefix return arguments 2022-04-11 15:42:28 +10:00
5e47056e8d Cleanup: malformed C-style comment blocks, spelling
- Missing star prefix.
- Unnecessary indentation.
- Blank line after dot-points
  (otherwise doxygen merges with the previous dot-point).
- Use back-slash for doxygen commands.
- Correct spelling.
2022-04-11 12:03:09 +10:00
1c264ebdc0 Cleanup: quotes, line length 2022-04-11 11:40:58 +10:00
2e77a8f974 Render: Add operators to add all used or remove all unused lightgroups
These operators build a list of all lightgroups that are used by the view layer's
scene and either add all used lightgroups that are not part of the view layer yet
or remove all lightgroups in the view layer that are not being used.

Differential Revision: https://developer.blender.org/D14596
2022-04-10 18:45:16 +02:00
0b05e0b97e Fix T97159: AOV Pass in Cycles always gets Alpha Value of 1 for whole image
As far as I can see, it makes a lot of sense to have the alpha channel here, it matches the 2.x behavior and also matches what Eevee is doing.

Differential Revision: https://developer.blender.org/D14595
2022-04-10 18:43:57 +02:00
Viktoriia Safiullina
a4f970e86b UI: improve descriptions for camera lens and lens unit
Differential Revision: https://developer.blender.org/D14602
2022-04-10 16:31:11 +02:00
Martijn Versteegh
811371a6bd Fix T96942: disable Adjacent Faces margin for UVs and tangent space bake
Use the Extend method for these, as these do not work correctly. For UVs
it's better to extend the UVs from the same face, and for tangent space
the normals should be encoded in a matching tangent space.

Later the Adjacent Faces method might be improved to support these cases.

Ref T96977

Differential Revision: https://developer.blender.org/D14572
2022-04-10 16:31:11 +02:00
Simon Lenz
1db3e26c74 Mask: refactor mask_rasterize vector copying into a utility function
Add a separate scanline function scanfill_vert_add_v2_with_depth that
adds a vertex from 2D coordinate array & the specified z-value.

Ref D13460
2022-04-10 17:29:06 +10:00
8315e97754 Cleanup: missing-prototypes warning 2022-04-10 17:25:33 +10:00
881c566032 Cleanup compilation warnings.
Missing include statement.
2022-04-09 20:15:07 +02:00
749636bdb9 Missing forward declaration. 2022-04-09 20:10:44 +02:00
ceed37fc5c Curves: Port tangent and normal calculation to the new data-block
Port the "Normal" and "Curve Tangent" nodes to the new curves data-block
to avoid the conversion to `CurveEval`. This should make them faster by
avoiding all that copying, but otherwise nothing else has changed.

This also includes a fix to move the normal mode as a built-in curve
attribute when converting to and from `CurveEval`. The attribute is
needed because the option is used implicitly in many nodes currently.

Differential Revision: https://developer.blender.org/D14609
2022-04-09 12:46:30 -05:00
69a4d113e8 Fix T97133: Crash when creating a scene copy
Crash happened in sequencer editor, because pointer to displayed
channels was not set in `scene_copy_data`.
2022-04-09 18:16:21 +02:00
3f2d5dfc0d GPencil: Fix unreported error in Grab Brush for transformed layers
If the layer was transformed the grab brush was not initialized as expected because it was using an untrasformed matrix.
2022-04-09 16:39:35 +02:00
32da64c17e Fix T95276: Effect strip animation not updated when moving strips
Since effect strips can't be transformed directly, their selection had
to be forced in order to process them. This often failed in more
complicated scenarios, because there was no attempt to parse hierarchy
completely. In worst case only one effect in chain would be selected.
This code was marked by `XXX_DURIAN_ANIM_TX_HACK`.

Instead solution described above, a collection of strips that depend
on non effect strip position is built by function
`query_time_dependent_strips_strips` and it is stored in `TransSeq`.
In `flushTransSeq` this collection is iterated and transformation offset
is applied to effect strip animation. Strips in collection should be
consistent with true state of dependency and should be complete.

Functional changes:
- When 2-input effect strip changes position, animation is offset even
if only handles are moved. This only applies to 2-input effect however.
- Selection is not extended to include effect strips anymore. If effects
are to be moved, they must be selected manually. This is because
previously it was very hard to reorganize effects in chain, since moving
first strip in chain would always select anywhere from 1 to n effects.
So creating or filling gap in channel would almos always result in
collision especially if their order in timeline doesn't perfectly
represent their order in chain.
2022-04-09 16:29:40 +02:00
809 changed files with 23121 additions and 11277 deletions

View File

@@ -446,7 +446,7 @@ if(NOT APPLE)
endif()
option(WITH_CYCLES_HIP_BINARIES "Build Cycles AMD HIP binaries" OFF)
set(CYCLES_HIP_BINARIES_ARCH gfx900 gfx906 gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032 gfx1034 CACHE STRING "AMD HIP architectures to build binaries for")
set(CYCLES_HIP_BINARIES_ARCH gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032 gfx1034 CACHE STRING "AMD HIP architectures to build binaries for")
mark_as_advanced(WITH_CYCLES_DEVICE_HIP)
mark_as_advanced(CYCLES_HIP_BINARIES_ARCH)
endif()

View File

@@ -4004,6 +4004,7 @@ install_DEB() {
WEBP_DEV="libwebp-dev"
check_package_DEB $WEBP_DEV
if [ $? -eq 0 ]; then
install_packages_DEB $WEBP_DEV
WEBP_USE=true
fi
@@ -4435,9 +4436,6 @@ install_DEB() {
if [ "$VPX_USE" = true ]; then
_packages="$_packages $VPX_DEV"
fi
if [ "$WEBP_USE" = true ]; then
_packages="$_packages $WEBP_DEV"
fi
if [ "$OPUS_USE" = true ]; then
_packages="$_packages $OPUS_DEV"
fi
@@ -4722,6 +4720,7 @@ install_RPM() {
WEBP_DEV="libwebp-devel"
check_package_RPM $WEBP_DEV
if [ $? -eq 0 ]; then
install_packages_RPM $WEBP_DEV
WEBP_USE=true
fi
@@ -5124,9 +5123,6 @@ install_RPM() {
if [ "$VPX_USE" = true ]; then
_packages="$_packages $VPX_DEV"
fi
if [ "$WEBP_USE" = true ]; then
_packages="$_packages $WEBP_DEV"
fi
if [ "$OPUS_USE" = true ]; then
_packages="$_packages $OPUS_DEV"
fi
@@ -5300,6 +5296,7 @@ install_ARCH() {
WEBP_DEV="libwebp"
check_package_ARCH $WEBP_DEV
if [ $? -eq 0 ]; then
install_packages_ARCH $WEBP_DEV
WEBP_USE=true
fi
@@ -5704,16 +5701,12 @@ install_ARCH() {
if [ "$VPX_USE" = true ]; then
_packages="$_packages $VPX_DEV"
fi
if [ "$WEBP_USE" = true ]; then
_packages="$_packages $WEBP_DEV"
fi
if [ "$OPUS_USE" = true ]; then
_packages="$_packages $OPUS_DEV"
fi
if [ "$MP3LAME_USE" = true ]; then
_packages="$_packages $MP3LAME_DEV"
fi
install_packages_ARCH $_packages
compile_FFmpeg
fi
@@ -5961,6 +5954,12 @@ print_info() {
fi
fi
if [ "$WEBP_USE" = true ]; then
_1="-D WITH_IMAGE_WEBP=ON"
PRINT " $_1"
_buildargs="$_buildargs $_1"
fi
if [ -d $INST/openexr ]; then
_1="-D OPENEXR_ROOT_DIR=$INST/openexr"
PRINT " $_1"

View File

@@ -202,9 +202,9 @@ def parm_size(node_child):
# NOT PERFECT CODE, EXTRACT SIZE FROM TOKENS
if len(tokens) >= 3: # foo [ 1 ]
if ((tokens[-3].kind == TokenKind.PUNCTUATION and tokens[-3].spelling == "[") and
(tokens[-2].kind == TokenKind.LITERAL and tokens[-2].spelling.isdigit()) and
(tokens[-1].kind == TokenKind.PUNCTUATION and tokens[-1].spelling == "]")):
if ((tokens[-3].kind == TokenKind.PUNCTUATION and tokens[-3].spelling == "[") and
(tokens[-2].kind == TokenKind.LITERAL and tokens[-2].spelling.isdigit()) and
(tokens[-1].kind == TokenKind.PUNCTUATION and tokens[-1].spelling == "]")):
# ---
return int(tokens[-2].spelling)
return -1

View File

@@ -214,7 +214,7 @@ if(WITH_SDL)
find_package(SDL2)
set(SDL_INCLUDE_DIR ${SDL2_INCLUDE_DIRS})
set(SDL_LIBRARY ${SDL2_LIBRARIES})
string(APPEND PLATFORM_LINKFLAGS " -framework ForceFeedback")
string(APPEND PLATFORM_LINKFLAGS " -framework ForceFeedback -framework GameController -framework CoreHaptics")
endif()
set(PNG_ROOT ${LIBDIR}/png)

View File

@@ -114,12 +114,11 @@ def makefile_log() -> List[str]:
print("Can't execute process")
sys.exit(1)
while process.poll():
time.sleep(1)
# We know this is always true based on the input arguments to `Popen`.
stdout: IO[bytes] = process.stdout # type: ignore
stdout: IO[bytes] = process.stdout # type: ignore
out = stdout.read()
stdout.close()
@@ -210,7 +209,7 @@ def build_defines_as_source() -> str:
)
# We know this is always true based on the input arguments to `Popen`.
stdout: IO[bytes] = process.stdout # type: ignore
stdout: IO[bytes] = process.stdout # type: ignore
return cast(str, stdout.read().strip().decode('ascii'))
@@ -228,7 +227,7 @@ def build_defines_as_args() -> List[str]:
def queue_processes(
process_funcs: Sequence[Tuple[Callable[..., subprocess.Popen[Any]], Tuple[Any, ...]]],
*,
job_total: int =-1,
job_total: int = -1,
sleep: float = 0.1,
) -> None:
""" Takes a list of function arg pairs, each function must return a process

View File

@@ -143,8 +143,8 @@ def packages_path(current_directory: Path, cli_args: Any) -> Optional[Path]:
return Path(relpath)
### Manifest creation
# -----------------------------------------------------------------------------
# Manifest creation
def create_manifest(
@@ -195,7 +195,8 @@ def packages_to_manifest(outfile: TextIO, packages_dir: Path) -> None:
print(path, file=outfile)
### Higher-level functions
# -----------------------------------------------------------------------------
# Higher-level functions
def create_tarball(
@@ -249,7 +250,8 @@ def cleanup(manifest: Path) -> None:
print("OK")
## Low-level commands
# -----------------------------------------------------------------------------
# Low-level commands
def git_ls_files(directory: Path = Path(".")) -> Iterable[Path]:
@@ -265,7 +267,7 @@ def git_ls_files(directory: Path = Path(".")) -> Iterable[Path]:
yield path
def git_command(*cli_args: Union[bytes, str, Path] ) -> Iterable[str]:
def git_command(*cli_args: Union[bytes, str, Path]) -> Iterable[str]:
"""Generator, yields lines of output from a Git command."""
command = ("git", *cli_args)

View File

@@ -129,6 +129,7 @@ def svn_update(args, release_version):
call(svn_non_interactive + ["switch", svn_url + dirname, dirpath], exit_on_error=False)
call(svn_non_interactive + ["update", dirpath])
# Test if git repo can be updated.
def git_update_skip(args, check_remote_exists=True):
if make_utils.command_missing(args.git_command):

View File

@@ -47,8 +47,10 @@ def check_output(cmd, exit_on_error=True):
def git_branch_exists(git_command, branch):
return call([git_command, "rev-parse", "--verify", branch], exit_on_error=False, silent=True) == 0 or \
call([git_command, "rev-parse", "--verify", "remotes/origin/" + branch], exit_on_error=False, silent=True) == 0
return (
call([git_command, "rev-parse", "--verify", branch], exit_on_error=False, silent=True) == 0 or
call([git_command, "rev-parse", "--verify", "remotes/origin/" + branch], exit_on_error=False, silent=True) == 0
)
def git_branch(git_command):

View File

@@ -378,7 +378,8 @@ def usage():
def main():
import os, os.path
import os
import os.path
try:
bpy = __import__('bpy')

View File

@@ -103,10 +103,10 @@ blender \- a full-featured 3D application''')
.PP
.B blender
is a full-featured 3D application. It supports the entirety of the 3D pipeline - '''
'''modeling, rigging, animation, simulation, rendering, compositing, motion tracking, and video editing.
'''modeling, rigging, animation, simulation, rendering, compositing, motion tracking, and video editing.
Use Blender to create 3D images and animations, films and commercials, content for games, '''
r'''architectural and industrial visualizations, and scientific visualizations.
r'''architectural and industrial visualizations, and scientific visualizations.
https://www.blender.org''')

View File

@@ -11,6 +11,7 @@ import queue
execution_queue = queue.Queue()
# This function can safely be called in another thread.
# The function will be executed when the timer runs the next time.
def run_in_main_thread(function):

View File

@@ -9,7 +9,7 @@ operator in the different part of the user interface.
The context overrides are passed as a dictionary, with keys matching the context
member names in bpy.context.
For example to override ``bpy.context.active_object``,
you would pass ``{'active_object': object}``.
you would pass ``{'active_object': object}`` to :class:`bpy.types.Context.temp_override`.
.. note::
@@ -17,8 +17,10 @@ you would pass ``{'active_object': object}``.
(otherwise, you'll have to find and gather all needed data yourself).
"""
# remove all objects in scene rather than the selected ones
# Remove all objects in scene rather than the selected ones.
import bpy
override = bpy.context.copy()
override['selected_objects'] = list(bpy.context.scene.objects)
bpy.ops.object.delete(override)
from bpy import context
override = context.copy()
override["selected_objects"] = list(context.scene.objects)
with context.temp_override(**override):
bpy.ops.object.delete()

View File

@@ -1,17 +1,16 @@
"""
It is also possible to run an operator in a particular part of the user
interface. For this we need to pass the window, screen, area and sometimes
a region.
interface. For this we need to pass the window, area and sometimes a region.
"""
# maximize 3d view in all windows
# Maximize 3d view in all windows.
import bpy
from bpy import context
for window in bpy.context.window_manager.windows:
for window in context.window_manager.windows:
screen = window.screen
for area in screen.areas:
if area.type == 'VIEW_3D':
override = {'window': window, 'screen': screen, 'area': area}
bpy.ops.screen.screen_full_area(override)
with context.temp_override(window=window, area=area):
bpy.ops.screen.screen_full_area()
break

View File

@@ -33,6 +33,11 @@ There are 3 optional positional arguments (documented in detail below).
bpy.ops.test.operator(override_context, execution_context, undo)
- override_context - ``dict`` type.
.. deprecated:: 3.2
:class:`bpy.types.Context.temp_override` should be used instead of this argument.
- execution_context - ``str`` (enum).
- undo - ``bool`` type.

View File

@@ -4,6 +4,7 @@ the middle of updating the armature without having to update dependencies
after each change, by manually carrying updated matrices in a recursive walk.
"""
def set_pose_matrices(obj, matrix_map):
"Assign pose space matrices of all bones at once, ignoring constraints."
@@ -11,7 +12,7 @@ def set_pose_matrices(obj, matrix_map):
if pbone.name in matrix_map:
matrix = matrix_map[pbone.name]
## Instead of:
# # Instead of:
# pbone.matrix = matrix
# bpy.context.view_layer.update()

View File

@@ -0,0 +1,19 @@
"""
Overriding the context can be used to temporarily activate another ``window`` / ``area`` & ``region``,
as well as other members such as the ``active_object`` or ``bone``.
Notes:
- When overriding window, area and regions: the arguments must be consistent,
so any region argument that's passed in must be contained by the current area or the area passed in.
The same goes for the area needing to be contained in the current window.
- Temporary context overrides may be nested, when this is done, members will be added to the existing overrides.
- Context members are restored outside the scope of the context.
The only exception to this is when the data is no longer available.
In the event windowing data was removed (for example), the state of the context is left as-is.
While this isn't likely to happen, explicit window operation such as closing windows or loading a new file
remove the windowing data that was set before the temporary context was created.
"""

View File

@@ -0,0 +1,15 @@
"""
Overriding the context can be useful to set the context after loading files
(which would otherwise by None). For example:
"""
import bpy
from bpy import context
# Reload the current file and select all.
bpy.ops.wm.open_mainfile(filepath=bpy.data.filepath)
window = context.window_manager.windows[0]
with context.temp_override(window=window):
bpy.ops.mesh.primitive_uv_sphere_add()
# The context override is needed so it's possible to set edit-mode.
bpy.ops.object.mode_set(mode='EDIT')

View File

@@ -0,0 +1,16 @@
"""
This example shows how it's possible to add an object to the scene in another window.
"""
import bpy
from bpy import context
win_active = context.window
win_other = None
for win_iter in context.window_manager.windows:
if win_iter != win_active:
win_other = win_iter
break
# Add cube in the other window.
with context.temp_override(window=win_other):
bpy.ops.mesh.primitive_cube_add()

View File

@@ -42,10 +42,12 @@ class SimpleMouseOperator(bpy.types.Operator):
self.y = event.mouse_y
return self.execute(context)
# Only needed if you want to add into a dynamic menu
# Only needed if you want to add into a dynamic menu.
def menu_func(self, context):
self.layout.operator(SimpleMouseOperator.bl_idname, text="Simple Mouse Operator")
# Register and add to the view menu (required to also use F3 search "Simple Mouse Operator" for quick access)
bpy.utils.register_class(SimpleMouseOperator)
bpy.types.VIEW3D_MT_view.append(menu_func)

View File

@@ -37,7 +37,7 @@ class ExportSomeData(bpy.types.Operator):
return {'RUNNING_MODAL'}
# Only needed if you want to add into a dynamic menu
# Only needed if you want to add into a dynamic menu.
def menu_func(self, context):
self.layout.operator_context = 'INVOKE_DEFAULT'
self.layout.operator(ExportSomeData.bl_idname, text="Text Export Operator")

View File

@@ -27,7 +27,8 @@ class DialogOperator(bpy.types.Operator):
wm = context.window_manager
return wm.invoke_props_dialog(self)
# Only needed if you want to add into a dynamic menu
# Only needed if you want to add into a dynamic menu.
def menu_func(self, context):
self.layout.operator(DialogOperator.bl_idname, text="Dialog Operator")

View File

@@ -41,11 +41,13 @@ class CustomDrawOperator(bpy.types.Operator):
col.prop(self, "my_string")
# Only needed if you want to add into a dynamic menu
# Only needed if you want to add into a dynamic menu.
def menu_func(self, context):
self.layout.operator(CustomDrawOperator.bl_idname, text="Custom Draw Operator")
# Register and add to the object menu (required to also use F3 search "Custom Draw Operator" for quick access)
# Register and add to the object menu (required to also use F3 search "Custom Draw Operator" for quick access).
bpy.utils.register_class(CustomDrawOperator)
bpy.types.VIEW3D_MT_object.append(menu_func)

View File

@@ -55,11 +55,13 @@ class ModalOperator(bpy.types.Operator):
context.window_manager.modal_handler_add(self)
return {'RUNNING_MODAL'}
# Only needed if you want to add into a dynamic menu
# Only needed if you want to add into a dynamic menu.
def menu_func(self, context):
self.layout.operator(ModalOperator.bl_idname, text="Modal Operator")
# Register and add to the object menu (required to also use F3 search "Modal Operator" for quick access)
# Register and add to the object menu (required to also use F3 search "Modal Operator" for quick access).
bpy.utils.register_class(ModalOperator)
bpy.types.VIEW3D_MT_object.append(menu_func)

View File

@@ -31,10 +31,12 @@ class SearchEnumOperator(bpy.types.Operator):
context.window_manager.invoke_search_popup(self)
return {'RUNNING_MODAL'}
# Only needed if you want to add into a dynamic menu
# Only needed if you want to add into a dynamic menu.
def menu_func(self, context):
self.layout.operator(SearchEnumOperator.bl_idname, text="Search Enum Operator")
# Register and add to the object menu (required to also use F3 search "Search Enum Operator" for quick access)
bpy.utils.register_class(SearchEnumOperator)
bpy.types.VIEW3D_MT_object.append(menu_func)

View File

@@ -22,13 +22,15 @@ class HelloWorldOperator(bpy.types.Operator):
print("Hello World")
return {'FINISHED'}
# Only needed if you want to add into a dynamic menu
# Only needed if you want to add into a dynamic menu.
def menu_func(self, context):
self.layout.operator(HelloWorldOperator.bl_idname, text="Hello World Operator")
# Register and add to the view menu (required to also use F3 search "Hello World Operator" for quick access)
# Register and add to the view menu (required to also use F3 search "Hello World Operator" for quick access).
bpy.utils.register_class(HelloWorldOperator)
bpy.types.VIEW3D_MT_view.append(menu_func)
# test call to the newly defined operator
# Test call to the newly defined operator.
bpy.ops.wm.hello_world()

View File

@@ -93,7 +93,7 @@ Consider the calculations that might contribute to the object's final transforma
- Animation function curves.
- Drivers and their Python expressions.
- Constraints
- Parent objects and all of their F-curves, constraints, etc.
- Parent objects and all of their F-Curves, constraints, etc.
To avoid expensive recalculations every time a property is modified,
Blender defers the evaluation until the results are needed.
@@ -802,7 +802,7 @@ Removing Data
-------------
**Any** data that you remove shouldn't be modified or accessed afterwards,
this includes: F-curves, drivers, render layers, timeline markers, modifiers, constraints
this includes: F-Curves, drivers, render layers, timeline markers, modifiers, constraints
along with objects, scenes, collections, bones, etc.
The ``remove()`` API calls will invalidate the data they free to prevent common mistakes.

View File

@@ -409,7 +409,9 @@ BLENDER_VERSION_DOTS = "%d.%d" % (bpy.app.version[0], bpy.app.version[1])
if BLENDER_REVISION != "Unknown":
# SHA1 Git hash
BLENDER_VERSION_HASH = BLENDER_REVISION
BLENDER_VERSION_HASH_HTML_LINK = "<a href=https://developer.blender.org/rB%s>%s</a>" % (BLENDER_VERSION_HASH, BLENDER_VERSION_HASH)
BLENDER_VERSION_HASH_HTML_LINK = "<a href=https://developer.blender.org/rB%s>%s</a>" % (
BLENDER_VERSION_HASH, BLENDER_VERSION_HASH,
)
BLENDER_VERSION_DATE = time.strftime("%d/%m/%Y", time.localtime(BLENDER_REVISION_TIMESTAMP))
else:
# Fallback: Should not be used
@@ -573,7 +575,7 @@ def example_extract_docstring(filepath):
line_no += 1
file.close()
return "\n".join(text), line_no, line_no_has_content
return "\n".join(text).rstrip("\n"), line_no, line_no_has_content
def title_string(text, heading_char, double=False):
@@ -593,9 +595,13 @@ def write_example_ref(ident, fw, example_id, ext="py"):
filepath_full = os.path.join(os.path.dirname(fw.__self__.name), filepath)
text, line_no, line_no_has_content = example_extract_docstring(filepath_full)
if text:
# Ensure a blank line, needed since in some cases the indentation doesn't match the previous line.
# which causes Sphinx not to warn about bad indentation.
fw("\n")
for line in text.split("\n"):
fw("%s\n" % (ident + line).rstrip())
for line in text.split("\n"):
fw("%s\n" % (ident + line).rstrip())
fw("\n")
# Some files only contain a doc-string.
@@ -1147,6 +1153,9 @@ def pycontext2sphinx(basepath):
fw("Note that all context values are readonly,\n")
fw("but may be modified through the data API or by running operators\n\n")
# Track all unique properties to properly use `noindex`.
unique = set()
def write_contex_cls():
fw(title_string("Global Context", "-"))
@@ -1164,9 +1173,11 @@ def pycontext2sphinx(basepath):
# First write RNA
for prop in sorted_struct_properties:
# support blacklisting props
# Support blacklisting props.
if prop.identifier in struct_blacklist:
continue
# No need to check if there are duplicates yet as it's known there wont be.
unique.add(prop.identifier)
type_descr = prop.get_type_description(
class_fmt=":class:`bpy.types.%s`", collection_id=_BPY_PROP_COLLECTION_ID)
@@ -1204,7 +1215,8 @@ def pycontext2sphinx(basepath):
"file_context_dir",
)
unique = set()
# Track unique for `context_strings` to validate `context_type_map`.
unique_context_strings = set()
blend_cdll = ctypes.CDLL("")
for ctx_str in context_strings:
subsection = "%s Context" % ctx_str.split("_")[0].title()
@@ -1216,22 +1228,34 @@ def pycontext2sphinx(basepath):
i = 0
while char_array[i] is not None:
member = ctypes.string_at(char_array[i]).decode(encoding="ascii")
fw(".. data:: %s\n\n" % member)
unique_all_len = len(unique)
unique.add(member)
member_visited = unique_all_len == len(unique)
unique_context_strings.add(member)
fw(".. data:: %s\n" % member)
# Avoid warnings about the member being included multiple times.
if member_visited:
fw(" :noindex:\n")
fw("\n")
try:
member_type, is_seq = context_type_map[member]
except KeyError:
raise SystemExit("Error: context key %r not found in context_type_map; update %s" % (member, __file__)) from None
raise SystemExit(
"Error: context key %r not found in context_type_map; update %s" %
(member, __file__)) from None
fw(" :type: %s :class:`bpy.types.%s`\n\n" % ("sequence of " if is_seq else "", member_type))
unique.add(member)
i += 1
# generate typemap...
# for member in sorted(unique):
# for member in sorted(unique_context_strings):
# print(' "%s": ("", False),' % member)
if len(context_type_map) > len(unique):
if len(context_type_map) > len(unique_context_strings):
warnings.warn(
"Some types are not used: %s" %
str([member for member in context_type_map if member not in unique]))
str([member for member in context_type_map if member not in unique_context_strings]))
else:
pass # will have raised an error above

27
extern/fast_float/LICENSE-MIT vendored Normal file
View File

@@ -0,0 +1,27 @@
MIT License
Copyright (c) 2021 The fast_float authors
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

7
extern/fast_float/README.blender vendored Normal file
View File

@@ -0,0 +1,7 @@
Project: fast_float
URL: https://github.com/fastfloat/fast_float
License: MIT
Upstream version: 3.4.0 (b7f9d6c)
Local modifications:
- Took only the fast_float.h header and the license/readme files

218
extern/fast_float/README.md vendored Normal file
View File

@@ -0,0 +1,218 @@
## fast_float number parsing library: 4x faster than strtod
![Ubuntu 20.04 CI (GCC 9)](https://github.com/lemire/fast_float/workflows/Ubuntu%2020.04%20CI%20(GCC%209)/badge.svg)
![Ubuntu 18.04 CI (GCC 7)](https://github.com/lemire/fast_float/workflows/Ubuntu%2018.04%20CI%20(GCC%207)/badge.svg)
![Alpine Linux](https://github.com/lemire/fast_float/workflows/Alpine%20Linux/badge.svg)
![MSYS2-CI](https://github.com/lemire/fast_float/workflows/MSYS2-CI/badge.svg)
![VS16-CLANG-CI](https://github.com/lemire/fast_float/workflows/VS16-CLANG-CI/badge.svg)
[![VS16-CI](https://github.com/fastfloat/fast_float/actions/workflows/vs16-ci.yml/badge.svg)](https://github.com/fastfloat/fast_float/actions/workflows/vs16-ci.yml)
The fast_float library provides fast header-only implementations for the C++ from_chars
functions for `float` and `double` types. These functions convert ASCII strings representing
decimal values (e.g., `1.3e10`) into binary types. We provide exact rounding (including
round to even). In our experience, these `fast_float` functions many times faster than comparable number-parsing functions from existing C++ standard libraries.
Specifically, `fast_float` provides the following two functions with a C++17-like syntax (the library itself only requires C++11):
```C++
from_chars_result from_chars(const char* first, const char* last, float& value, ...);
from_chars_result from_chars(const char* first, const char* last, double& value, ...);
```
The return type (`from_chars_result`) is defined as the struct:
```C++
struct from_chars_result {
const char* ptr;
std::errc ec;
};
```
It parses the character sequence [first,last) for a number. It parses floating-point numbers expecting
a locale-independent format equivalent to the C++17 from_chars function.
The resulting floating-point value is the closest floating-point values (using either float or double),
using the "round to even" convention for values that would otherwise fall right in-between two values.
That is, we provide exact parsing according to the IEEE standard.
Given a successful parse, the pointer (`ptr`) in the returned value is set to point right after the
parsed number, and the `value` referenced is set to the parsed value. In case of error, the returned
`ec` contains a representative error, otherwise the default (`std::errc()`) value is stored.
The implementation does not throw and does not allocate memory (e.g., with `new` or `malloc`).
It will parse infinity and nan values.
Example:
``` C++
#include "fast_float/fast_float.h"
#include <iostream>
int main() {
const std::string input = "3.1416 xyz ";
double result;
auto answer = fast_float::from_chars(input.data(), input.data()+input.size(), result);
if(answer.ec != std::errc()) { std::cerr << "parsing failure\n"; return EXIT_FAILURE; }
std::cout << "parsed the number " << result << std::endl;
return EXIT_SUCCESS;
}
```
Like the C++17 standard, the `fast_float::from_chars` functions take an optional last argument of
the type `fast_float::chars_format`. It is a bitset value: we check whether
`fmt & fast_float::chars_format::fixed` and `fmt & fast_float::chars_format::scientific` are set
to determine whether we allow the fixed point and scientific notation respectively.
The default is `fast_float::chars_format::general` which allows both `fixed` and `scientific`.
The library seeks to follow the C++17 (see [20.19.3](http://eel.is/c++draft/charconv.from.chars).(7.1)) specification.
* The `from_chars` function does not skip leading white-space characters.
* [A leading `+` sign](https://en.cppreference.com/w/cpp/utility/from_chars) is forbidden.
* It is generally impossible to represent a decimal value exactly as binary floating-point number (`float` and `double` types). We seek the nearest value. We round to an even mantissa when we are in-between two binary floating-point numbers.
Furthermore, we have the following restrictions:
* We only support `float` and `double` types at this time.
* We only support the decimal format: we do not support hexadecimal strings.
* For values that are either very large or very small (e.g., `1e9999`), we represent it using the infinity or negative infinity value.
We support Visual Studio, macOS, Linux, freeBSD. We support big and little endian. We support 32-bit and 64-bit systems.
## Using commas as decimal separator
The C++ standard stipulate that `from_chars` has to be locale-independent. In
particular, the decimal separator has to be the period (`.`). However,
some users still want to use the `fast_float` library with in a locale-dependent
manner. Using a separate function called `from_chars_advanced`, we allow the users
to pass a `parse_options` instance which contains a custom decimal separator (e.g.,
the comma). You may use it as follows.
```C++
#include "fast_float/fast_float.h"
#include <iostream>
int main() {
const std::string input = "3,1416 xyz ";
double result;
fast_float::parse_options options{fast_float::chars_format::general, ','};
auto answer = fast_float::from_chars_advanced(input.data(), input.data()+input.size(), result, options);
if((answer.ec != std::errc()) || ((result != 3.1416))) { std::cerr << "parsing failure\n"; return EXIT_FAILURE; }
std::cout << "parsed the number " << result << std::endl;
return EXIT_SUCCESS;
}
```
## Reference
- Daniel Lemire, [Number Parsing at a Gigabyte per Second](https://arxiv.org/abs/2101.11408), Software: Pratice and Experience 51 (8), 2021.
## Other programming languages
- [There is an R binding](https://github.com/eddelbuettel/rcppfastfloat) called `rcppfastfloat`.
- [There is a Rust port of the fast_float library](https://github.com/aldanor/fast-float-rust/) called `fast-float-rust`.
- [There is a Java port of the fast_float library](https://github.com/wrandelshofer/FastDoubleParser) called `FastDoubleParser`.
- [There is a C# port of the fast_float library](https://github.com/CarlVerret/csFastFloat) called `csFastFloat`.
## Relation With Other Work
The fastfloat algorithm is part of the [LLVM standard libraries](https://github.com/llvm/llvm-project/commit/87c016078ad72c46505461e4ff8bfa04819fe7ba).
The fast_float library provides a performance similar to that of the [fast_double_parser](https://github.com/lemire/fast_double_parser) library but using an updated algorithm reworked from the ground up, and while offering an API more in line with the expectations of C++ programmers. The fast_double_parser library is part of the [Microsoft LightGBM machine-learning framework](https://github.com/microsoft/LightGBM).
## Users
The fast_float library is used by [Apache Arrow](https://github.com/apache/arrow/pull/8494) where it multiplied the number parsing speed by two or three times. It is also used by [Yandex ClickHouse](https://github.com/ClickHouse/ClickHouse) and by [Google Jsonnet](https://github.com/google/jsonnet).
## How fast is it?
It can parse random floating-point numbers at a speed of 1 GB/s on some systems. We find that it is often twice as fast as the best available competitor, and many times faster than many standard-library implementations.
<img src="http://lemire.me/blog/wp-content/uploads/2020/11/fastfloat_speed.png" width="400">
```
$ ./build/benchmarks/benchmark
# parsing random integers in the range [0,1)
volume = 2.09808 MB
netlib : 271.18 MB/s (+/- 1.2 %) 12.93 Mfloat/s
doubleconversion : 225.35 MB/s (+/- 1.2 %) 10.74 Mfloat/s
strtod : 190.94 MB/s (+/- 1.6 %) 9.10 Mfloat/s
abseil : 430.45 MB/s (+/- 2.2 %) 20.52 Mfloat/s
fastfloat : 1042.38 MB/s (+/- 9.9 %) 49.68 Mfloat/s
```
See https://github.com/lemire/simple_fastfloat_benchmark for our benchmarking code.
## Video
[![Go Systems 2020](http://img.youtube.com/vi/AVXgvlMeIm4/0.jpg)](http://www.youtube.com/watch?v=AVXgvlMeIm4)<br />
## Using as a CMake dependency
This library is header-only by design. The CMake file provides the `fast_float` target
which is merely a pointer to the `include` directory.
If you drop the `fast_float` repository in your CMake project, you should be able to use
it in this manner:
```cmake
add_subdirectory(fast_float)
target_link_libraries(myprogram PUBLIC fast_float)
```
Or you may want to retrieve the dependency automatically if you have a sufficiently recent version of CMake (3.11 or better at least):
```cmake
FetchContent_Declare(
fast_float
GIT_REPOSITORY https://github.com/lemire/fast_float.git
GIT_TAG tags/v1.1.2
GIT_SHALLOW TRUE)
FetchContent_MakeAvailable(fast_float)
target_link_libraries(myprogram PUBLIC fast_float)
```
You should change the `GIT_TAG` line so that you recover the version you wish to use.
## Using as single header
The script `script/amalgamate.py` may be used to generate a single header
version of the library if so desired.
Just run the script from the root directory of this repository.
You can customize the license type and output file if desired as described in
the command line help.
You may directly download automatically generated single-header files:
https://github.com/fastfloat/fast_float/releases/download/v1.1.2/fast_float.h
## Credit
Though this work is inspired by many different people, this work benefited especially from exchanges with
Michael Eisel, who motivated the original research with his key insights, and with Nigel Tao who provided
invaluable feedback. Rémy Oudompheng first implemented a fast path we use in the case of long digits.
The library includes code adapted from Google Wuffs (written by Nigel Tao) which was originally published
under the Apache 2.0 license.
## License
<sup>
Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
</sup>
<br>
<sub>
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this repository by you, as defined in the Apache-2.0 license,
shall be dual licensed as above, without any additional terms or conditions.
</sub>

2979
extern/fast_float/fast_float.h vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -10,6 +10,7 @@ import bpy
from bpy_extras.io_utils import ExportHelper
from bpy.props import PointerProperty, StringProperty
def strip(root):
root.text = None
root.tail = None
@@ -17,6 +18,7 @@ def strip(root):
for elem in root:
strip(elem)
def write(node, fname):
strip(node)
@@ -26,25 +28,31 @@ def write(node, fname):
f = open(fname, "w")
f.write(s)
class CyclesXMLSettings(bpy.types.PropertyGroup):
@classmethod
def register(cls):
bpy.types.Scene.cycles_xml = PointerProperty(
type=cls,
name="Cycles XML export Settings",
description="Cycles XML export settings")
type=cls,
name="Cycles XML export Settings",
description="Cycles XML export settings",
)
cls.filepath = StringProperty(
name='Filepath',
description='Filepath for the .xml file',
maxlen=256,
default='',
subtype='FILE_PATH')
name='Filepath',
description='Filepath for the .xml file',
maxlen=256,
default='',
subtype='FILE_PATH',
)
@classmethod
def unregister(cls):
del bpy.types.Scene.cycles_xml
# User Interface Drawing Code
# User Interface Drawing Code.
class RenderButtonsPanel():
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
@@ -114,22 +122,31 @@ class ExportCyclesXML(bpy.types.Operator, ExportHelper):
uvs += str(uvf.uv1[0]) + " " + str(uvf.uv1[1]) + " "
uvs += str(uvf.uv2[0]) + " " + str(uvf.uv2[1]) + " "
uvs += str(uvf.uv3[0]) + " " + str(uvf.uv3[1]) + " "
if vcount==4:
if vcount == 4:
uvs += " " + str(uvf.uv4[0]) + " " + str(uvf.uv4[1]) + " "
node = etree.Element('mesh', attrib={'nverts': nverts.strip(), 'verts': verts.strip(), 'P': P, 'UV' : uvs.strip()})
node = etree.Element(
'mesh',
attrib={
'nverts': nverts.strip(),
'verts': verts.strip(),
'P': P,
'UV': uvs.strip(),
})
# write to file
write(node, filepath)
return {'FINISHED'}
def register():
bpy.utils.register_module(__name__)
def unregister():
bpy.utils.unregister_module(__name__)
if __name__ == "__main__":
register()

View File

@@ -4,11 +4,14 @@
# <pep8 compliant>
# Fit to match default projective camera with focal_length 50 and sensor_width 36.
default_fisheye_polynomial = [-1.1735143712967577e-05,
-0.019988736953434998,
-3.3525322965709175e-06,
3.099275275886036e-06,
-2.6064646454854524e-08]
default_fisheye_polynomial = [
-1.1735143712967577e-05,
-0.019988736953434998,
-3.3525322965709175e-06,
3.099275275886036e-06,
-2.6064646454854524e-08,
]
# Utilities to generate lens polynomials to match built-in camera types, only here
# for reference at the moment, not used by the code.
@@ -51,7 +54,9 @@ def fisheye_lens_polynomial_from_equidistant(fov=180, sensor_width=36, sensor_he
return [0, -np.radians(fov) / sensor_width, 0, 0, 0]
def fisheye_lens_polynomial_from_distorted_projective_polynomial(k1, k2, k3, focal_length=50, sensor_width=36, sensor_height=None):
def fisheye_lens_polynomial_from_distorted_projective_polynomial(
k1, k2, k3, focal_length=50, sensor_width=36, sensor_height=None,
):
import numpy as np
rr = create_grid(sensor_height, sensor_width)
r2 = (rr / focal_length) ** 2
@@ -61,7 +66,10 @@ def fisheye_lens_polynomial_from_distorted_projective_polynomial(k1, k2, k3, foc
polynomial = np.polyfit(rr.flat, (-np.arctan(rr / focal_length * r_coeff)).flat, 4)
return list(reversed(polynomial))
def fisheye_lens_polynomial_from_distorted_projective_divisions(k1, k2, focal_length=50, sensor_width=36, sensor_height=None):
def fisheye_lens_polynomial_from_distorted_projective_divisions(
k1, k2, focal_length=50, sensor_width=36, sensor_height=None,
):
import numpy as np
rr = create_grid(sensor_height, sensor_width)
r2 = (rr / focal_length) ** 2

View File

@@ -98,6 +98,7 @@ def render_frame_finish(engine):
import _cycles
_cycles.render_frame_finish(engine.session)
def draw(engine, depsgraph, space_image):
if not engine.session:
return
@@ -168,6 +169,9 @@ def list_render_passes(scene, srl):
# Combined pass.
yield ("Combined", "RGBA", 'COLOR')
# Keep alignment for readability.
# autopep8: off
# Data passes.
if srl.use_pass_z: yield ("Depth", "Z", 'VALUE')
if srl.use_pass_mist: yield ("Mist", "Z", 'VALUE')
@@ -195,9 +199,11 @@ def list_render_passes(scene, srl):
if srl.use_pass_shadow: yield ("Shadow", "RGB", 'COLOR')
if srl.use_pass_ambient_occlusion: yield ("AO", "RGB", 'COLOR')
if crl.use_pass_shadow_catcher: yield ("Shadow Catcher", "RGB", 'COLOR')
# autopep8: on
# Debug passes.
if crl.pass_debug_sample_count: yield ("Debug Sample Count", "X", 'VALUE')
if crl.pass_debug_sample_count:
yield ("Debug Sample Count", "X", 'VALUE')
# Cryptomatte passes.
crypto_depth = (srl.pass_cryptomatte_depth + 1) // 2
@@ -217,16 +223,16 @@ def list_render_passes(scene, srl):
if crl.use_pass_shadow_catcher:
yield ("Noisy Shadow Catcher", "RGBA", 'COLOR')
if crl.denoising_store_passes:
yield ("Denoising Normal", "XYZ", 'VECTOR')
yield ("Denoising Albedo", "RGB", 'COLOR')
yield ("Denoising Depth", "Z", 'VALUE')
yield ("Denoising Normal", "XYZ", 'VECTOR')
yield ("Denoising Albedo", "RGB", 'COLOR')
yield ("Denoising Depth", "Z", 'VALUE')
# Custom AOV passes.
for aov in srl.aovs:
if aov.type == 'VALUE':
yield (aov.name, "X", 'VALUE')
else:
yield (aov.name, "RGB", 'COLOR')
yield (aov.name, "RGBA", 'COLOR')
# Light groups.
for lightgroup in srl.lightgroups:

View File

@@ -34,8 +34,8 @@ class CYCLES_OT_use_shading_nodes(Operator):
class CYCLES_OT_denoise_animation(Operator):
"Denoise rendered animation sequence using current scene and view " \
"layer settings. Requires denoising data passes and output to " \
"OpenEXR multilayer files"
"layer settings. Requires denoising data passes and output to " \
"OpenEXR multilayer files"
bl_idname = "cycles.denoise_animation"
bl_label = "Denoise Animation"
@@ -117,7 +117,7 @@ class CYCLES_OT_denoise_animation(Operator):
class CYCLES_OT_merge_images(Operator):
"Combine OpenEXR multilayer images rendered with different sample " \
"ranges into one image with reduced noise"
"ranges into one image with reduced noise"
bl_idname = "cycles.merge_images"
bl_label = "Merge Images"

View File

@@ -85,6 +85,7 @@ class AddPresetViewportSampling(AddPresetBase, Operator):
preset_subdir = "cycles/viewport_sampling"
classes = (
AddPresetIntegrator,
AddPresetSampling,

View File

@@ -83,7 +83,8 @@ enum_sampling_pattern = (
enum_volume_sampling = (
('DISTANCE', "Distance", "Use distance sampling, best for dense volumes with lights far away"),
('EQUIANGULAR', "Equiangular", "Use equiangular sampling, best for volumes with low density with light inside or near the volume"),
('MULTIPLE_IMPORTANCE', "Multiple Importance", "Combine distance and equi-angular sampling for volumes where neither method is ideal"),
('MULTIPLE_IMPORTANCE', "Multiple Importance",
"Combine distance and equi-angular sampling for volumes where neither method is ideal"),
)
enum_volume_interpolation = (
@@ -181,7 +182,12 @@ def enum_preview_denoiser(self, context):
oidn_items = enum_openimagedenoise_denoiser(self, context)
if len(optix_items) or len(oidn_items):
items = [('AUTO', "Automatic", "Use the fastest available denoiser for viewport rendering (OptiX if available, OpenImageDenoise otherwise)", 0)]
items = [
('AUTO',
"Automatic",
("Use the fastest available denoiser for viewport rendering "
"(OptiX if available, OpenImageDenoise otherwise)"),
0)]
else:
items = [('AUTO', "None", "Blender was compiled without a viewport denoiser", 0)]
@@ -210,11 +216,14 @@ enum_denoising_prefilter = (
)
enum_direct_light_sampling_type = (
('MULTIPLE_IMPORTANCE_SAMPLING', "Multiple Importance Sampling", "Multiple importance sampling is used to combine direct light contributions from next-event estimation and forward path tracing", 0),
('MULTIPLE_IMPORTANCE_SAMPLING', "Multiple Importance Sampling",
"Multiple importance sampling is used to combine direct light contributions from next-event estimation and forward path tracing", 0),
('FORWARD_PATH_TRACING', "Forward Path Tracing", "Direct light contributions are only sampled using forward path tracing", 1),
('NEXT_EVENT_ESTIMATION', "Next-Event Estimation", "Direct light contributions are only sampled using next-event estimation", 2),
('NEXT_EVENT_ESTIMATION', "Next-Event Estimation",
"Direct light contributions are only sampled using next-event estimation", 2),
)
def update_render_passes(self, context):
view_layer = context.view_layer
view_layer.update_render_passes()
@@ -262,7 +271,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
description="Denoise the image with the selected denoiser. "
"For denoising the image after rendering",
items=enum_denoiser,
default=4, # Use integer to avoid error in builds without OpenImageDenoise.
default=4, # Use integer to avoid error in builds without OpenImageDenoise.
update=update_render_passes,
)
denoising_prefilter: EnumProperty(
@@ -1507,7 +1516,7 @@ class CyclesPreferences(bpy.types.AddonPreferences):
col.label(text="and NVIDIA driver version 470 or newer", icon='BLANK1')
elif device_type == 'HIP':
import sys
col.label(text="Requires discrete AMD GPU with Vega architecture", icon='BLANK1')
col.label(text="Requires discrete AMD GPU with RDNA architecture", icon='BLANK1')
if sys.platform[:3] == "win":
col.label(text="and AMD Radeon Pro 21.Q4 driver or newer", icon='BLANK1')
elif device_type == 'METAL':
@@ -1547,7 +1556,6 @@ class CyclesPreferences(bpy.types.AddonPreferences):
row.use_property_split = True
row.prop(self, "use_metalrt")
def draw(self, context):
self.draw_impl(self.layout, context)

View File

@@ -14,6 +14,7 @@ from bl_ui.properties_grease_pencil_common import GreasePencilSimplifyPanel
from bl_ui.properties_render import draw_curves_settings
from bl_ui.properties_view_layer import ViewLayerCryptomattePanel, ViewLayerAOVPanel, ViewLayerLightgroupsPanel
class CyclesPresetPanel(PresetPanel, Panel):
COMPAT_ENGINES = {'CYCLES'}
preset_operator = "script.execute_preset"
@@ -25,16 +26,19 @@ class CyclesPresetPanel(PresetPanel, Panel):
render = context.scene.render
render.filter_size = render.filter_size
class CYCLES_PT_sampling_presets(CyclesPresetPanel):
bl_label = "Sampling Presets"
preset_subdir = "cycles/sampling"
preset_add_operator = "render.cycles_sampling_preset_add"
class CYCLES_PT_viewport_sampling_presets(CyclesPresetPanel):
bl_label = "Viewport Sampling Presets"
preset_subdir = "cycles/viewport_sampling"
preset_add_operator = "render.cycles_viewport_sampling_preset_add"
class CYCLES_PT_integrator_presets(CyclesPresetPanel):
bl_label = "Integrator Presets"
preset_subdir = "cycles/integrator"
@@ -90,6 +94,7 @@ def use_metal(context):
return (get_device_type(context) == 'METAL' and cscene.device == 'GPU')
def use_cuda(context):
cscene = context.scene.cycles
@@ -101,11 +106,13 @@ def use_hip(context):
return (get_device_type(context) == 'HIP' and cscene.device == 'GPU')
def use_optix(context):
cscene = context.scene.cycles
return (get_device_type(context) == 'OPTIX' and cscene.device == 'GPU')
def use_multi_device(context):
cscene = context.scene.cycles
if cscene.device != 'GPU':
@@ -133,7 +140,6 @@ def get_effective_preview_denoiser(context):
return 'OIDN'
class CYCLES_RENDER_PT_sampling(CyclesButtonsPanel, Panel):
bl_label = "Sampling"
@@ -353,6 +359,7 @@ class CYCLES_RENDER_PT_curves(CyclesButtonsPanel, Panel):
if ccscene.shape == 'RIBBONS':
col.prop(ccscene, "subdivisions", text="Curve Subdivisions")
class CYCLES_RENDER_PT_curves_viewport_display(CyclesButtonsPanel, Panel):
bl_label = "Viewport Display"
bl_parent_id = "CYCLES_RENDER_PT_curves"
@@ -361,6 +368,7 @@ class CYCLES_RENDER_PT_curves_viewport_display(CyclesButtonsPanel, Panel):
def draw(self, context):
draw_curves_settings(self, context)
class CYCLES_RENDER_PT_volumes(CyclesButtonsPanel, Panel):
bl_label = "Volumes"
bl_options = {'DEFAULT_CLOSED'}
@@ -478,10 +486,10 @@ class CYCLES_RENDER_PT_light_paths_fast_gi(CyclesButtonsPanel, Panel):
col.prop(cscene, "fast_gi_method", text="Method")
if world:
light = world.light_settings
col = layout.column(align=True)
col.prop(light, "ao_factor", text="AO Factor")
col.prop(light, "distance", text="AO Distance")
light = world.light_settings
col = layout.column(align=True)
col.prop(light, "ao_factor", text="AO Factor")
col.prop(light, "distance", text="AO Distance")
if cscene.fast_gi_method == 'REPLACE':
col = layout.column(align=True)
@@ -1034,7 +1042,8 @@ class CYCLES_OBJECT_PT_motion_blur(CyclesButtonsPanel, Panel):
def poll(cls, context):
ob = context.object
if CyclesButtonsPanel.poll(context) and ob:
if ob.type in {'MESH', 'CURVE', 'CURVE', 'SURFACE', 'FONT', 'META', 'CAMERA', 'CURVES', 'POINTCLOUD'}:
if ob.type in {'MESH', 'CURVE', 'CURVE', 'SURFACE', 'FONT',
'META', 'CAMERA', 'CURVES', 'POINTCLOUD', 'VOLUME'}:
return True
if ob.instance_type == 'COLLECTION' and ob.instance_collection:
return True
@@ -1446,7 +1455,14 @@ class CYCLES_WORLD_PT_surface(CyclesButtonsPanel, Panel):
row.use_property_decorate = False
sub = row.column(align=True)
sub.prop_search(world, "lightgroup", view_layer, "lightgroups", text="Light Group", results_are_suggestions=True)
sub.prop_search(
world,
"lightgroup",
view_layer,
"lightgroups",
text="Light Group",
results_are_suggestions=True,
)
sub = row.column(align=True)
sub.active = bool(world.lightgroup) and not any(lg.name == world.lightgroup for lg in view_layer.lightgroups)
@@ -1572,7 +1588,6 @@ class CYCLES_WORLD_PT_settings_surface(CyclesButtonsPanel, Panel):
sub.prop(cworld, "is_caustics_light", text="Shadow Caustics")
class CYCLES_WORLD_PT_settings_volume(CyclesButtonsPanel, Panel):
bl_label = "Volume"
bl_parent_id = "CYCLES_WORLD_PT_settings"
@@ -1894,6 +1909,7 @@ class CYCLES_RENDER_PT_bake_output(CyclesButtonsPanel, Panel):
if cbk.target == 'IMAGE_TEXTURES':
layout.prop(cbk, "use_clear", text="Clear Image")
class CYCLES_RENDER_PT_bake_output_margin(CyclesButtonsPanel, Panel):
bl_label = "Margin"
bl_context = "render"
@@ -1916,14 +1932,20 @@ class CYCLES_RENDER_PT_bake_output_margin(CyclesButtonsPanel, Panel):
cbk = scene.render.bake
rd = scene.render
if rd.use_bake_multires:
layout.prop(rd, "bake_margin_type", text="Type")
layout.prop(rd, "bake_margin", text="Size")
if (cscene.bake_type == 'NORMAL' and cbk.normal_space == 'TANGENT') or cscene.bake_type == 'UV':
if rd.use_bake_multires:
layout.prop(rd, "bake_margin", text="Size")
else:
if cbk.target == 'IMAGE_TEXTURES':
layout.prop(cbk, "margin", text="Size")
else:
if cbk.target == 'IMAGE_TEXTURES':
layout.prop(cbk, "margin_type", text="Type")
layout.prop(cbk, "margin", text="Size")
if rd.use_bake_multires:
layout.prop(rd, "bake_margin_type", text="Type")
layout.prop(rd, "bake_margin", text="Size")
else:
if cbk.target == 'IMAGE_TEXTURES':
layout.prop(cbk, "margin_type", text="Type")
layout.prop(cbk, "margin", text="Size")
class CYCLES_RENDER_PT_debug(CyclesDebugButtonsPanel, Panel):

View File

@@ -72,7 +72,7 @@ def do_versions(self):
# Device might not currently be available so this can fail
try:
if system.legacy_compute_device_type == 1:
prop.compute_device_type = 'NONE' # Was OpenCL
prop.compute_device_type = 'NONE' # Was OpenCL
elif system.legacy_compute_device_type == 2:
prop.compute_device_type = 'CUDA'
else:
@@ -181,24 +181,24 @@ def do_versions(self):
if version <= (2, 92, 4):
if scene.render.engine == 'CYCLES':
for view_layer in scene.view_layers:
cview_layer = view_layer.cycles
view_layer.use_pass_cryptomatte_object = cview_layer.get("use_pass_crypto_object", False)
view_layer.use_pass_cryptomatte_material = cview_layer.get("use_pass_crypto_material", False)
view_layer.use_pass_cryptomatte_asset = cview_layer.get("use_pass_crypto_asset", False)
view_layer.pass_cryptomatte_depth = cview_layer.get("pass_crypto_depth", 6)
for view_layer in scene.view_layers:
cview_layer = view_layer.cycles
view_layer.use_pass_cryptomatte_object = cview_layer.get("use_pass_crypto_object", False)
view_layer.use_pass_cryptomatte_material = cview_layer.get("use_pass_crypto_material", False)
view_layer.use_pass_cryptomatte_asset = cview_layer.get("use_pass_crypto_asset", False)
view_layer.pass_cryptomatte_depth = cview_layer.get("pass_crypto_depth", 6)
if version <= (2, 93, 7):
if scene.render.engine == 'CYCLES':
for view_layer in scene.view_layers:
cview_layer = view_layer.cycles
for caov in cview_layer.get("aovs", []):
aov_name = caov.get("name", "AOV")
if aov_name in view_layer.aovs:
continue
baov = view_layer.aovs.add()
baov.name = caov.get("name", "AOV")
baov.type = "COLOR" if caov.get("type", 1) == 1 else "VALUE"
for view_layer in scene.view_layers:
cview_layer = view_layer.cycles
for caov in cview_layer.get("aovs", []):
aov_name = caov.get("name", "AOV")
if aov_name in view_layer.aovs:
continue
baov = view_layer.aovs.add()
baov.name = caov.get("name", "AOV")
baov.type = "COLOR" if caov.get("type", 1) == 1 else "VALUE"
if version <= (2, 93, 16):
cscene = scene.cycles

View File

@@ -23,7 +23,7 @@ struct BlenderCamera {
float lens;
float shuttertime;
Camera::MotionPosition motion_position;
MotionPosition motion_position;
array<float> shutter_curve;
Camera::RollingShutterType rolling_shutter_type;
@@ -114,7 +114,7 @@ static void blender_camera_init(BlenderCamera *bcam, BL::RenderSettings &b_rende
bcam->sensor_width = 36.0f;
bcam->sensor_height = 24.0f;
bcam->sensor_fit = BlenderCamera::AUTO;
bcam->motion_position = Camera::MOTION_POSITION_CENTER;
bcam->motion_position = MOTION_POSITION_CENTER;
bcam->border.right = 1.0f;
bcam->border.top = 1.0f;
bcam->viewport_camera_border.right = 1.0f;
@@ -555,10 +555,8 @@ void BlenderSync::sync_camera(BL::RenderSettings &b_render,
curvemapping_to_array(b_shutter_curve, bcam.shutter_curve, RAMP_TABLE_SIZE);
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
bcam.motion_position = (Camera::MotionPosition)get_enum(cscene,
"motion_blur_position",
Camera::MOTION_NUM_POSITIONS,
Camera::MOTION_POSITION_CENTER);
bcam.motion_position = (MotionPosition)get_enum(
cscene, "motion_blur_position", MOTION_NUM_POSITIONS, MOTION_POSITION_CENTER);
bcam.rolling_shutter_type = (Camera::RollingShutterType)get_enum(
cscene,
"rolling_shutter_type",

View File

@@ -16,6 +16,7 @@
#include "scene/shader.h"
#include "scene/shader_graph.h"
#include "scene/shader_nodes.h"
#include "scene/volume.h"
#include "util/foreach.h"
#include "util/hash.h"
@@ -715,13 +716,13 @@ void BlenderSync::sync_motion(BL::RenderSettings &b_render,
float frame_center_delta = 0.0f;
if (scene->need_motion() != Scene::MOTION_PASS &&
scene->camera->get_motion_position() != Camera::MOTION_POSITION_CENTER) {
scene->camera->get_motion_position() != MOTION_POSITION_CENTER) {
float shuttertime = scene->camera->get_shuttertime();
if (scene->camera->get_motion_position() == Camera::MOTION_POSITION_END) {
if (scene->camera->get_motion_position() == MOTION_POSITION_END) {
frame_center_delta = -shuttertime * 0.5f;
}
else {
assert(scene->camera->get_motion_position() == Camera::MOTION_POSITION_START);
assert(scene->camera->get_motion_position() == MOTION_POSITION_START);
frame_center_delta = shuttertime * 0.5f;
}

View File

@@ -272,7 +272,7 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render,
geometry_synced.clear(); /* use for objects and motion sync */
if (scene->need_motion() == Scene::MOTION_PASS || scene->need_motion() == Scene::MOTION_NONE ||
scene->camera->get_motion_position() == Camera::MOTION_POSITION_CENTER) {
scene->camera->get_motion_position() == MOTION_POSITION_CENTER) {
sync_objects(b_depsgraph, b_v3d);
}
sync_motion(b_render, b_depsgraph, b_v3d, b_override, width, height, python_thread_state);

View File

@@ -168,7 +168,8 @@ class BlenderSmokeLoader : public ImageLoader {
AttributeStandard attribute;
};
static void sync_smoke_volume(Scene *scene, BObjectInfo &b_ob_info, Volume *volume, float frame)
static void sync_smoke_volume(
BL::Scene &b_scene, Scene *scene, BObjectInfo &b_ob_info, Volume *volume, float frame)
{
if (!b_ob_info.is_real_object_data()) {
return;
@@ -178,6 +179,18 @@ static void sync_smoke_volume(Scene *scene, BObjectInfo &b_ob_info, Volume *volu
return;
}
float velocity_scale = b_domain.velocity_scale();
/* Motion blur attribute is relative to seconds, we need it relative to frames. */
const bool need_motion = object_need_motion_attribute(b_ob_info, scene);
const float motion_scale = (need_motion) ?
scene->motion_shutter_time() /
(b_scene.render().fps() / b_scene.render().fps_base()) :
0.0f;
velocity_scale *= motion_scale;
volume->set_velocity_scale(velocity_scale);
AttributeStandard attributes[] = {ATTR_STD_VOLUME_DENSITY,
ATTR_STD_VOLUME_COLOR,
ATTR_STD_VOLUME_FLAME,
@@ -234,6 +247,7 @@ class BlenderVolumeLoader : public VDBImageLoader {
};
static void sync_volume_object(BL::BlendData &b_data,
BL::Scene &b_scene,
BObjectInfo &b_ob_info,
Scene *scene,
Volume *volume)
@@ -247,6 +261,20 @@ static void sync_volume_object(BL::BlendData &b_data,
volume->set_step_size(b_render.step_size());
volume->set_object_space((b_render.space() == BL::VolumeRender::space_OBJECT));
float velocity_scale = b_volume.velocity_scale();
if (b_volume.velocity_unit() == BL::Volume::velocity_unit_SECOND) {
/* Motion blur attribute is relative to seconds, we need it relative to frames. */
const bool need_motion = object_need_motion_attribute(b_ob_info, scene);
const float motion_scale = (need_motion) ?
scene->motion_shutter_time() /
(b_scene.render().fps() / b_scene.render().fps_base()) :
0.0f;
velocity_scale *= motion_scale;
}
volume->set_velocity_scale(velocity_scale);
/* Find grid with matching name. */
for (BL::VolumeGrid &b_grid : b_volume.grids) {
ustring name = ustring(b_grid.name());
@@ -267,9 +295,22 @@ static void sync_volume_object(BL::BlendData &b_data,
else if (name == Attribute::standard_name(ATTR_STD_VOLUME_TEMPERATURE)) {
std = ATTR_STD_VOLUME_TEMPERATURE;
}
else if (name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY)) {
else if (name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY) ||
name == b_volume.velocity_grid()) {
std = ATTR_STD_VOLUME_VELOCITY;
}
else if (name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY_X) ||
name == b_volume.velocity_x_grid()) {
std = ATTR_STD_VOLUME_VELOCITY_X;
}
else if (name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY_Y) ||
name == b_volume.velocity_y_grid()) {
std = ATTR_STD_VOLUME_VELOCITY_Y;
}
else if (name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY_Z) ||
name == b_volume.velocity_z_grid()) {
std = ATTR_STD_VOLUME_VELOCITY_Z;
}
if ((std != ATTR_STD_NONE && volume->need_attribute(scene, std)) ||
volume->need_attribute(scene, name)) {
@@ -294,11 +335,11 @@ void BlenderSync::sync_volume(BObjectInfo &b_ob_info, Volume *volume)
if (b_ob_info.object_data.is_a(&RNA_Volume)) {
/* Volume object. Create only attributes, bounding mesh will then
* be automatically generated later. */
sync_volume_object(b_data, b_ob_info, scene, volume);
sync_volume_object(b_data, b_scene, b_ob_info, scene, volume);
}
else {
/* Smoke domain. */
sync_smoke_volume(scene, b_ob_info, volume, b_scene.frame_current());
sync_smoke_volume(b_scene, scene, b_ob_info, volume, b_scene.frame_current());
}
}

View File

@@ -71,11 +71,6 @@ void CUDADeviceQueue::init_execution()
debug_init_execution();
}
bool CUDADeviceQueue::kernel_available(DeviceKernel kernel) const
{
return cuda_device_->kernels.available(kernel);
}
bool CUDADeviceQueue::enqueue(DeviceKernel kernel,
const int work_size,
DeviceKernelArguments const &args)

View File

@@ -27,8 +27,6 @@ class CUDADeviceQueue : public DeviceQueue {
virtual void init_execution() override;
virtual bool kernel_available(DeviceKernel kernel) const override;
virtual bool enqueue(DeviceKernel kernel,
const int work_size,
DeviceKernelArguments const &args) override;

View File

@@ -71,11 +71,6 @@ void HIPDeviceQueue::init_execution()
debug_init_execution();
}
bool HIPDeviceQueue::kernel_available(DeviceKernel kernel) const
{
return hip_device_->kernels.available(kernel);
}
bool HIPDeviceQueue::enqueue(DeviceKernel kernel,
const int work_size,
DeviceKernelArguments const &args)

View File

@@ -27,8 +27,6 @@ class HIPDeviceQueue : public DeviceQueue {
virtual void init_execution() override;
virtual bool kernel_available(DeviceKernel kernel) const override;
virtual bool enqueue(DeviceKernel kernel,
const int work_size,
DeviceKernelArguments const &args) override;

View File

@@ -51,7 +51,7 @@ static inline bool hipSupportsDevice(const int hipDevId)
hipDeviceGetAttribute(&major, hipDeviceAttributeComputeCapabilityMajor, hipDevId);
hipDeviceGetAttribute(&minor, hipDeviceAttributeComputeCapabilityMinor, hipDevId);
return (major >= 9);
return (major > 10) || (major == 10 && minor >= 1);
}
CCL_NAMESPACE_END

View File

@@ -459,7 +459,7 @@ bool MetalDeviceKernels::load(MetalDevice *device, int kernel_type)
tbb::task_arena local_arena(max_mtlcompiler_threads);
local_arena.execute([&]() {
tbb::parallel_for(int(0), int(DEVICE_KERNEL_NUM), [&](int i) {
parallel_for(int(0), int(DEVICE_KERNEL_NUM), [&](int i) {
/* skip megakernel */
if (i == DEVICE_KERNEL_INTEGRATOR_MEGAKERNEL) {
return;

View File

@@ -39,8 +39,6 @@ class MetalDeviceQueue : public DeviceQueue {
virtual void copy_to_device(device_memory &mem) override;
virtual void copy_from_device(device_memory &mem) override;
virtual bool kernel_available(DeviceKernel kernel) const override;
protected:
void prepare_resources(DeviceKernel kernel);

View File

@@ -492,11 +492,6 @@ void MetalDeviceQueue::copy_from_device(device_memory &mem)
}
}
bool MetalDeviceQueue::kernel_available(DeviceKernel kernel) const
{
return metal_device->kernels.available(kernel);
}
void MetalDeviceQueue::prepare_resources(DeviceKernel kernel)
{
std::lock_guard<std::recursive_mutex> lock(metal_device->metal_mem_map_mutex);

View File

@@ -112,9 +112,6 @@ class DeviceQueue {
* Use this method after device synchronization has finished before enqueueing any kernels. */
virtual void init_execution() = 0;
/* Test if an optional device kernel is available. */
virtual bool kernel_available(DeviceKernel kernel) const = 0;
/* Enqueue kernel execution.
*
* Execute the kernel work_size times on the device.

View File

@@ -3,6 +3,7 @@
* Copyright 2022 Blender Foundation */
#include "hydra/camera.h"
#include "hydra/session.h"
#include "scene/camera.h"
#include <pxr/base/gf/frustum.h>
@@ -12,6 +13,19 @@
HDCYCLES_NAMESPACE_OPEN_SCOPE
extern Transform convert_transform(const GfMatrix4d &matrix);
Transform convert_camera_transform(const GfMatrix4d &matrix, float metersPerUnit)
{
Transform t = convert_transform(matrix);
// Flip Z axis
t.x.z *= -1.0f;
t.y.z *= -1.0f;
t.z.z *= -1.0f;
// Scale translation
t.x.w *= metersPerUnit;
t.y.w *= metersPerUnit;
t.z.w *= metersPerUnit;
return t;
}
#if PXR_VERSION < 2102
// clang-format off
@@ -61,13 +75,20 @@ void HdCyclesCamera::Sync(HdSceneDelegate *sceneDelegate,
if (*dirtyBits & DirtyBits::DirtyTransform) {
sceneDelegate->SampleTransform(id, &_transformSamples);
bool transform_found = false;
for (size_t i = 0; i < _transformSamples.count; ++i) {
if (_transformSamples.times[i] == 0.0f) {
_transform = _transformSamples.values[i];
_data.SetTransform(_transform);
transform_found = true;
break;
}
}
if (!transform_found && _transformSamples.count) {
_transform = _transformSamples.values[0];
_data.SetTransform(_transform);
}
}
#else
if (*dirtyBits & DirtyBits::DirtyViewMatrix) {
@@ -236,18 +257,21 @@ void HdCyclesCamera::Finalize(HdRenderParam *renderParam)
HdCamera::Finalize(renderParam);
}
void HdCyclesCamera::ApplyCameraSettings(Camera *cam) const
void HdCyclesCamera::ApplyCameraSettings(HdRenderParam *renderParam, Camera *cam) const
{
ApplyCameraSettings(_data, _windowPolicy, cam);
ApplyCameraSettings(renderParam, _data, _windowPolicy, cam);
const float metersPerUnit = static_cast<HdCyclesSession *>(renderParam)->GetStageMetersPerUnit();
array<Transform> motion(_transformSamples.count);
for (size_t i = 0; i < _transformSamples.count; ++i)
motion[i] = convert_transform(_transformSamples.values[i]) *
transform_scale(1.0f, 1.0f, -1.0f);
for (size_t i = 0; i < _transformSamples.count; ++i) {
motion[i] = convert_camera_transform(_transformSamples.values[i], metersPerUnit);
}
cam->set_motion(motion);
}
void HdCyclesCamera::ApplyCameraSettings(const GfCamera &dataUnconformedWindow,
void HdCyclesCamera::ApplyCameraSettings(HdRenderParam *renderParam,
const GfCamera &dataUnconformedWindow,
CameraUtilConformWindowPolicy windowPolicy,
Camera *cam)
{
@@ -261,20 +285,22 @@ void HdCyclesCamera::ApplyCameraSettings(const GfCamera &dataUnconformedWindow,
GfCamera::Orthographic == CAMERA_ORTHOGRAPHIC);
cam->set_camera_type(static_cast<CameraType>(data.GetProjection()));
const float metersPerUnit = static_cast<HdCyclesSession *>(renderParam)->GetStageMetersPerUnit();
auto viewplane = data.GetFrustum().GetWindow();
auto focalLength = 1.0f;
if (data.GetProjection() == GfCamera::Perspective) {
viewplane *= 2.0 / viewplane.GetSize()[1]; // Normalize viewplane
focalLength = data.GetFocalLength() * 1e-3f;
focalLength = data.GetFocalLength() * GfCamera::FOCAL_LENGTH_UNIT * metersPerUnit;
cam->set_fov(GfDegreesToRadians(data.GetFieldOfView(GfCamera::FOVVertical)));
}
cam->set_sensorwidth(data.GetHorizontalAperture() * GfCamera::APERTURE_UNIT);
cam->set_sensorheight(data.GetVerticalAperture() * GfCamera::APERTURE_UNIT);
cam->set_sensorwidth(data.GetHorizontalAperture() * GfCamera::APERTURE_UNIT * metersPerUnit);
cam->set_sensorheight(data.GetVerticalAperture() * GfCamera::APERTURE_UNIT * metersPerUnit);
cam->set_nearclip(data.GetClippingRange().GetMin());
cam->set_farclip(data.GetClippingRange().GetMax());
cam->set_nearclip(data.GetClippingRange().GetMin() * metersPerUnit);
cam->set_farclip(data.GetClippingRange().GetMax() * metersPerUnit);
cam->set_viewplane_left(viewplane.GetMin()[0]);
cam->set_viewplane_right(viewplane.GetMax()[0]);
@@ -282,14 +308,15 @@ void HdCyclesCamera::ApplyCameraSettings(const GfCamera &dataUnconformedWindow,
cam->set_viewplane_top(viewplane.GetMax()[1]);
if (data.GetFStop() != 0.0f) {
cam->set_focaldistance(data.GetFocusDistance());
cam->set_focaldistance(data.GetFocusDistance() * metersPerUnit);
cam->set_aperturesize(focalLength / (2.0f * data.GetFStop()));
}
cam->set_matrix(convert_transform(data.GetTransform()) * transform_scale(1.0f, 1.0f, -1.0f));
cam->set_matrix(convert_camera_transform(data.GetTransform(), metersPerUnit));
}
void HdCyclesCamera::ApplyCameraSettings(const GfMatrix4d &worldToViewMatrix,
void HdCyclesCamera::ApplyCameraSettings(HdRenderParam *renderParam,
const GfMatrix4d &worldToViewMatrix,
const GfMatrix4d &projectionMatrix,
const std::vector<GfVec4d> &clipPlanes,
Camera *cam)
@@ -298,7 +325,7 @@ void HdCyclesCamera::ApplyCameraSettings(const GfMatrix4d &worldToViewMatrix,
GfCamera data;
data.SetFromViewAndProjectionMatrix(worldToViewMatrix, projectionMatrix);
ApplyCameraSettings(data, CameraUtilFit, cam);
ApplyCameraSettings(renderParam, data, CameraUtilFit, cam);
#else
TF_CODING_ERROR("Not implemented");
#endif

View File

@@ -17,12 +17,14 @@ class HdCyclesCamera final : public PXR_NS::HdCamera {
HdCyclesCamera(const PXR_NS::SdfPath &sprimId);
~HdCyclesCamera() override;
void ApplyCameraSettings(CCL_NS::Camera *targetCamera) const;
void ApplyCameraSettings(PXR_NS::HdRenderParam *renderParam, CCL_NS::Camera *targetCamera) const;
static void ApplyCameraSettings(const PXR_NS::GfCamera &cameraData,
static void ApplyCameraSettings(PXR_NS::HdRenderParam *renderParam,
const PXR_NS::GfCamera &cameraData,
PXR_NS::CameraUtilConformWindowPolicy windowPolicy,
CCL_NS::Camera *targetCamera);
static void ApplyCameraSettings(const PXR_NS::GfMatrix4d &worldToViewMatrix,
static void ApplyCameraSettings(PXR_NS::HdRenderParam *renderParam,
const PXR_NS::GfMatrix4d &worldToViewMatrix,
const PXR_NS::GfMatrix4d &projectionMatrix,
const std::vector<PXR_NS::GfVec4d> &clipPlanes,
CCL_NS::Camera *targetCamera);

View File

@@ -153,7 +153,11 @@ void HdCyclesGeometry<Base, CyclesBase>::Sync(HdSceneDelegate *sceneDelegate,
// Update transforms of all instances
for (size_t i = 0; i < transforms.size(); ++i) {
const Transform tfm = convert_transform(_geomTransform * transforms[i]);
const float metersPerUnit =
static_cast<HdCyclesSession *>(renderParam)->GetStageMetersPerUnit();
const Transform tfm = transform_scale(make_float3(metersPerUnit)) *
convert_transform(_geomTransform * transforms[i]);
_instances[i]->set_tfm(tfm);
}
}

View File

@@ -54,11 +54,16 @@ void HdCyclesLight::Sync(HdSceneDelegate *sceneDelegate,
const SdfPath &id = GetId();
if (*dirtyBits & DirtyBits::DirtyTransform) {
const float metersPerUnit =
static_cast<HdCyclesSession *>(renderParam)->GetStageMetersPerUnit();
const Transform tfm = transform_scale(make_float3(metersPerUnit)) *
#if PXR_VERSION >= 2011
const Transform tfm = convert_transform(sceneDelegate->GetTransform(id));
convert_transform(sceneDelegate->GetTransform(id));
#else
const Transform tfm = convert_transform(
sceneDelegate->GetLightParamValue(id, HdTokens->transform).Get<GfMatrix4d>());
convert_transform(
sceneDelegate->GetLightParamValue(id, HdTokens->transform)
.Get<GfMatrix4d>());
#endif
_light->set_tfm(tfm);

View File

@@ -33,11 +33,12 @@ TF_DEFINE_PRIVATE_TOKENS(_tokens,
);
TF_DEFINE_PRIVATE_TOKENS(HdCyclesRenderSettingsTokens,
(stageMetersPerUnit)
((device, "cycles:device"))
((threads, "cycles:threads"))
((time_limit, "cycles:time_limit"))
((timeLimit, "cycles:time_limit"))
((samples, "cycles:samples"))
((sample_offset, "cycles:sample_offset"))
((sampleOffset, "cycles:sample_offset"))
);
// clang-format on
@@ -424,7 +425,7 @@ HdRenderSettingDescriptorList HdCyclesDelegate::GetRenderSettingDescriptors() co
descriptors.push_back({
"Time Limit",
HdCyclesRenderSettingsTokens->time_limit,
HdCyclesRenderSettingsTokens->timeLimit,
VtValue(0.0),
});
descriptors.push_back({
@@ -434,7 +435,7 @@ HdRenderSettingDescriptorList HdCyclesDelegate::GetRenderSettingDescriptors() co
});
descriptors.push_back({
"Sample Offset",
HdCyclesRenderSettingsTokens->sample_offset,
HdCyclesRenderSettingsTokens->sampleOffset,
VtValue(0),
});
@@ -452,7 +453,11 @@ void HdCyclesDelegate::SetRenderSetting(const PXR_NS::TfToken &key, const PXR_NS
Scene *const scene = _renderParam->session->scene;
Session *const session = _renderParam->session;
if (key == HdCyclesRenderSettingsTokens->time_limit) {
if (key == HdCyclesRenderSettingsTokens->stageMetersPerUnit) {
_renderParam->SetStageMetersPerUnit(
VtValue::Cast<double>(value).GetWithDefault(_renderParam->GetStageMetersPerUnit()));
}
else if (key == HdCyclesRenderSettingsTokens->timeLimit) {
session->set_time_limit(
VtValue::Cast<double>(value).GetWithDefault(session->params.time_limit));
}
@@ -462,7 +467,7 @@ void HdCyclesDelegate::SetRenderSetting(const PXR_NS::TfToken &key, const PXR_NS
samples = std::min(std::max(1, samples), max_samples);
session->set_samples(samples);
}
else if (key == HdCyclesRenderSettingsTokens->sample_offset) {
else if (key == HdCyclesRenderSettingsTokens->sampleOffset) {
session->params.sample_offset = VtValue::Cast<int>(value).GetWithDefault(
session->params.sample_offset);
++_settingsVersion;
@@ -484,19 +489,22 @@ VtValue HdCyclesDelegate::GetRenderSetting(const TfToken &key) const
Scene *const scene = _renderParam->session->scene;
Session *const session = _renderParam->session;
if (key == HdCyclesRenderSettingsTokens->device) {
if (key == HdCyclesRenderSettingsTokens->stageMetersPerUnit) {
return VtValue(_renderParam->GetStageMetersPerUnit());
}
else if (key == HdCyclesRenderSettingsTokens->device) {
return VtValue(TfToken(Device::string_from_type(session->params.device.type)));
}
else if (key == HdCyclesRenderSettingsTokens->threads) {
return VtValue(session->params.threads);
}
else if (key == HdCyclesRenderSettingsTokens->time_limit) {
else if (key == HdCyclesRenderSettingsTokens->timeLimit) {
return VtValue(session->params.time_limit);
}
else if (key == HdCyclesRenderSettingsTokens->samples) {
return VtValue(session->params.samples);
}
else if (key == HdCyclesRenderSettingsTokens->sample_offset) {
else if (key == HdCyclesRenderSettingsTokens->sampleOffset) {
return VtValue(session->params.sample_offset);
}
else {

View File

@@ -117,10 +117,11 @@ void HdCyclesRenderPass::_Execute(const HdRenderPassStateSharedPtr &renderPassSt
#endif
if (const auto camera = static_cast<const HdCyclesCamera *>(renderPassState->GetCamera())) {
camera->ApplyCameraSettings(scene->camera);
camera->ApplyCameraSettings(_renderParam, scene->camera);
}
else {
HdCyclesCamera::ApplyCameraSettings(renderPassState->GetWorldToViewMatrix(),
HdCyclesCamera::ApplyCameraSettings(_renderParam,
renderPassState->GetWorldToViewMatrix(),
renderPassState->GetProjectionMatrix(),
renderPassState->GetClipPlanes(),
scene->camera);

View File

@@ -29,6 +29,16 @@ class HdCyclesSession final : public PXR_NS::HdRenderParam {
void UpdateScene();
double GetStageMetersPerUnit() const
{
return _stageMetersPerUnit;
}
void SetStageMetersPerUnit(double stageMetersPerUnit)
{
_stageMetersPerUnit = stageMetersPerUnit;
}
PXR_NS::HdRenderPassAovBinding GetDisplayAovBinding() const
{
return _displayAovBinding;
@@ -52,6 +62,7 @@ class HdCyclesSession final : public PXR_NS::HdRenderParam {
private:
const bool _ownCyclesSession;
double _stageMetersPerUnit = 0.01;
PXR_NS::HdRenderPassAovBindingVector _aovBindings;
PXR_NS::HdRenderPassAovBinding _displayAovBinding;
};

View File

@@ -44,7 +44,7 @@ inline void PassAccessorCPU::run_get_pass_kernel_processor_float(
const int pixel_stride = destination.pixel_stride ? destination.pixel_stride :
destination.num_components;
tbb::parallel_for(0, buffer_params.window_height, [&](int64_t y) {
parallel_for(0, buffer_params.window_height, [&](int64_t y) {
const float *buffer = window_data + y * buffer_row_stride;
float *pixel = destination.pixels +
(y * buffer_params.width + destination.offset) * pixel_stride;
@@ -69,7 +69,7 @@ inline void PassAccessorCPU::run_get_pass_kernel_processor_half_rgba(
const int destination_stride = destination.stride != 0 ? destination.stride :
buffer_params.width;
tbb::parallel_for(0, buffer_params.window_height, [&](int64_t y) {
parallel_for(0, buffer_params.window_height, [&](int64_t y) {
const float *buffer = window_data + y * buffer_row_stride;
half4 *pixel = dst_start + y * destination_stride;
func(kfilm_convert, buffer, pixel, buffer_params.window_width, pass_stride);

View File

@@ -334,7 +334,7 @@ void PathTrace::init_render_buffers(const RenderWork &render_work)
/* Handle initialization scheduled by the render scheduler. */
if (render_work.init_render_buffers) {
tbb::parallel_for_each(path_trace_works_, [&](unique_ptr<PathTraceWork> &path_trace_work) {
parallel_for_each(path_trace_works_, [&](unique_ptr<PathTraceWork> &path_trace_work) {
path_trace_work->zero_render_buffers();
});
@@ -355,7 +355,9 @@ void PathTrace::path_trace(RenderWork &render_work)
const int num_works = path_trace_works_.size();
tbb::parallel_for(0, num_works, [&](int i) {
thread_capture_fp_settings();
parallel_for(0, num_works, [&](int i) {
const double work_start_time = time_dt();
const int num_samples = render_work.path_trace.num_samples;
@@ -405,7 +407,7 @@ void PathTrace::adaptive_sample(RenderWork &render_work)
const double start_time = time_dt();
uint num_active_pixels = 0;
tbb::parallel_for_each(path_trace_works_, [&](unique_ptr<PathTraceWork> &path_trace_work) {
parallel_for_each(path_trace_works_, [&](unique_ptr<PathTraceWork> &path_trace_work) {
const uint num_active_pixels_in_work =
path_trace_work->adaptive_sampling_converge_filter_count_active(
render_work.adaptive_sampling.threshold, render_work.adaptive_sampling.reset);
@@ -483,7 +485,7 @@ void PathTrace::cryptomatte_postprocess(const RenderWork &render_work)
}
VLOG(3) << "Perform cryptomatte work.";
tbb::parallel_for_each(path_trace_works_, [&](unique_ptr<PathTraceWork> &path_trace_work) {
parallel_for_each(path_trace_works_, [&](unique_ptr<PathTraceWork> &path_trace_work) {
path_trace_work->cryptomatte_postproces();
});
}
@@ -536,7 +538,7 @@ void PathTrace::denoise(const RenderWork &render_work)
if (multi_device_buffers) {
multi_device_buffers->copy_from_device();
tbb::parallel_for_each(
parallel_for_each(
path_trace_works_, [&multi_device_buffers](unique_ptr<PathTraceWork> &path_trace_work) {
path_trace_work->copy_from_denoised_render_buffers(multi_device_buffers.get());
});
@@ -806,7 +808,7 @@ void PathTrace::tile_buffer_read()
}
/* Read buffers back from device. */
tbb::parallel_for_each(path_trace_works_, [&](unique_ptr<PathTraceWork> &path_trace_work) {
parallel_for_each(path_trace_works_, [&](unique_ptr<PathTraceWork> &path_trace_work) {
path_trace_work->copy_render_buffers_from_device();
});
@@ -814,7 +816,7 @@ void PathTrace::tile_buffer_read()
PathTraceTile tile(*this);
if (output_driver_->read_render_tile(tile)) {
/* Copy buffers to device again. */
tbb::parallel_for_each(path_trace_works_, [](unique_ptr<PathTraceWork> &path_trace_work) {
parallel_for_each(path_trace_works_, [](unique_ptr<PathTraceWork> &path_trace_work) {
path_trace_work->copy_render_buffers_to_device();
});
}
@@ -878,20 +880,20 @@ void PathTrace::progress_set_status(const string &status, const string &substatu
void PathTrace::copy_to_render_buffers(RenderBuffers *render_buffers)
{
tbb::parallel_for_each(path_trace_works_,
[&render_buffers](unique_ptr<PathTraceWork> &path_trace_work) {
path_trace_work->copy_to_render_buffers(render_buffers);
});
parallel_for_each(path_trace_works_,
[&render_buffers](unique_ptr<PathTraceWork> &path_trace_work) {
path_trace_work->copy_to_render_buffers(render_buffers);
});
render_buffers->copy_to_device();
}
void PathTrace::copy_from_render_buffers(RenderBuffers *render_buffers)
{
render_buffers->copy_from_device();
tbb::parallel_for_each(path_trace_works_,
[&render_buffers](unique_ptr<PathTraceWork> &path_trace_work) {
path_trace_work->copy_from_render_buffers(render_buffers);
});
parallel_for_each(path_trace_works_,
[&render_buffers](unique_ptr<PathTraceWork> &path_trace_work) {
path_trace_work->copy_from_render_buffers(render_buffers);
});
}
bool PathTrace::copy_render_tile_from_device()
@@ -903,7 +905,7 @@ bool PathTrace::copy_render_tile_from_device()
bool success = true;
tbb::parallel_for_each(path_trace_works_, [&](unique_ptr<PathTraceWork> &path_trace_work) {
parallel_for_each(path_trace_works_, [&](unique_ptr<PathTraceWork> &path_trace_work) {
if (!success) {
return;
}
@@ -1004,7 +1006,7 @@ bool PathTrace::get_render_tile_pixels(const PassAccessor &pass_accessor,
bool success = true;
tbb::parallel_for_each(path_trace_works_, [&](unique_ptr<PathTraceWork> &path_trace_work) {
parallel_for_each(path_trace_works_, [&](unique_ptr<PathTraceWork> &path_trace_work) {
if (!success) {
return;
}
@@ -1021,7 +1023,7 @@ bool PathTrace::set_render_tile_pixels(PassAccessor &pass_accessor,
{
bool success = true;
tbb::parallel_for_each(path_trace_works_, [&](unique_ptr<PathTraceWork> &path_trace_work) {
parallel_for_each(path_trace_works_, [&](unique_ptr<PathTraceWork> &path_trace_work) {
if (!success) {
return;
}

View File

@@ -73,7 +73,7 @@ void PathTraceWorkCPU::render_samples(RenderStatistics &statistics,
tbb::task_arena local_arena = local_tbb_arena_create(device_);
local_arena.execute([&]() {
tbb::parallel_for(int64_t(0), total_pixels_num, [&](int64_t work_index) {
parallel_for(int64_t(0), total_pixels_num, [&](int64_t work_index) {
if (is_cancel_requested()) {
return;
}
@@ -219,7 +219,7 @@ int PathTraceWorkCPU::adaptive_sampling_converge_filter_count_active(float thres
/* Check convergency and do x-filter in a single `parallel_for`, to reduce threading overhead. */
local_arena.execute([&]() {
tbb::parallel_for(full_y, full_y + height, [&](int y) {
parallel_for(full_y, full_y + height, [&](int y) {
CPUKernelThreadGlobals *kernel_globals = &kernel_thread_globals_[0];
bool row_converged = true;
@@ -243,7 +243,7 @@ int PathTraceWorkCPU::adaptive_sampling_converge_filter_count_active(float thres
if (num_active_pixels) {
local_arena.execute([&]() {
tbb::parallel_for(full_x, full_x + width, [&](int x) {
parallel_for(full_x, full_x + width, [&](int x) {
CPUKernelThreadGlobals *kernel_globals = &kernel_thread_globals_[0];
kernels_.adaptive_sampling_filter_y(
kernel_globals, render_buffer, x, full_y, height, offset, stride);
@@ -265,7 +265,7 @@ void PathTraceWorkCPU::cryptomatte_postproces()
/* Check convergency and do x-filter in a single `parallel_for`, to reduce threading overhead. */
local_arena.execute([&]() {
tbb::parallel_for(0, height, [&](int y) {
parallel_for(0, height, [&](int y) {
CPUKernelThreadGlobals *kernel_globals = &kernel_thread_globals_[0];
int pixel_index = y * width;

View File

@@ -92,7 +92,7 @@ bool ShaderEval::eval_cpu(Device *device,
tbb::task_arena local_arena(device->info.cpu_threads);
local_arena.execute([&]() {
tbb::parallel_for(int64_t(0), work_size, [&](int64_t work_index) {
parallel_for(int64_t(0), work_size, [&](int64_t work_index) {
/* TODO: is this fast enough? */
if (progress_.get_cancel()) {
success = false;

View File

@@ -831,6 +831,65 @@ ccl_device_inline void shader_eval_volume(KernelGlobals kg,
/* todo: this is inefficient for motion blur, we should be
* caching matrices instead of recomputing them each step */
shader_setup_object_transforms(kg, sd, sd->time);
if ((sd->object_flag & SD_OBJECT_HAS_VOLUME_MOTION) != 0) {
AttributeDescriptor v_desc = find_attribute(kg, sd, ATTR_STD_VOLUME_VELOCITY);
kernel_assert(v_desc.offset != ATTR_STD_NOT_FOUND);
const float3 P = sd->P;
const float velocity_scale = kernel_tex_fetch(__objects, sd->object).velocity_scale;
const float time_offset = kernel_data.cam.motion_position == MOTION_POSITION_CENTER ?
0.5f :
0.0f;
const float time = kernel_data.cam.motion_position == MOTION_POSITION_END ?
(1.0f - kernel_data.cam.shuttertime) + sd->time :
sd->time;
/* Use a 1st order semi-lagrangian advection scheme to estimate what volume quantity
* existed, or will exist, at the given time:
*
* `phi(x, T) = phi(x - (T - t) * u(x, T), t)`
*
* where
*
* x : position
* T : super-sampled time (or ray time)
* t : current time of the simulation (in rendering we assume this is center frame with
* relative time = 0)
* phi : the volume quantity
* u : the velocity field
*
* But first we need to determine the velocity field `u(x, T)`, which we can estimate also
* using semi-lagrangian advection.
*
* `u(x, T) = u(x - (T - t) * u(x, T), t)`
*
* This is the typical way to model self-advection in fluid dynamics, however, we do not
* account for other forces affecting the velocity during simulation (pressure, buyoancy,
* etc.): this gives a linear interpolation when fluid are mostly "curvy". For better
* results, a higher order interpolation scheme can be used (at the cost of more lookups),
* or an interpolation of the velocity fields for the previous and next frames could also
* be used to estimate `u(x, T)` (which will cost more memory and lookups).
*
* References:
* "Eulerian Motion Blur", Kim and Ko, 2007
* "Production Volume Rendering", Wreninge et al., 2012
*/
/* Find velocity. */
float3 velocity = primitive_volume_attribute_float3(kg, sd, v_desc);
object_dir_transform(kg, sd, &velocity);
/* Find advected P. */
sd->P = P - (time - time_offset) * velocity_scale * velocity;
/* Find advected velocity. */
velocity = primitive_volume_attribute_float3(kg, sd, v_desc);
object_dir_transform(kg, sd, &velocity);
/* Find advected P. */
sd->P = P - (time - time_offset) * velocity_scale * velocity;
}
# endif
}

View File

@@ -32,7 +32,7 @@ ccl_device void svm_node_aov_color(KernelGlobals kg,
kernel_data.film.pass_stride;
ccl_global float *buffer = render_buffer + render_buffer_offset +
(kernel_data.film.pass_aov_color + node.z);
kernel_write_pass_float3(buffer, make_float3(val.x, val.y, val.z));
kernel_write_pass_float4(buffer, make_float4(val.x, val.y, val.z, 1.0f));
}
}

View File

@@ -23,7 +23,7 @@ ccl_device_noinline void svm_node_blackbody(KernelGlobals kg,
/* Input */
float temperature = stack_load_float(stack, temperature_offset);
float3 color_rgb = svm_math_blackbody_color(temperature);
float3 color_rgb = rec709_to_rgb(kg, svm_math_blackbody_color_rec709(temperature));
stack_store_float3(stack, col_offset, color_rgb);
}

View File

@@ -1111,7 +1111,8 @@ ccl_device_noinline int svm_node_principled_volume(KernelGlobals kg,
if (intensity > CLOSURE_WEIGHT_CUTOFF) {
float3 blackbody_tint = stack_load_float3(stack, node.w);
float3 bb = blackbody_tint * intensity * svm_math_blackbody_color(T);
float3 bb = blackbody_tint * intensity *
rec709_to_rgb(kg, svm_math_blackbody_color_rec709(T));
emission_setup(sd, bb);
}
}

View File

@@ -189,10 +189,8 @@ ccl_device float svm_math(NodeMathType type, float a, float b, float c)
}
}
ccl_device float3 svm_math_blackbody_color(float t)
ccl_device float3 svm_math_blackbody_color_rec709(float t)
{
/* TODO(lukas): Reimplement in XYZ. */
/* Calculate color in range 800..12000 using an approximation
* a/x+bx+c for R and G and ((at + b)t + c)t + d) for B
* Max absolute error for RGB is (0.00095, 0.00077, 0.00057),

View File

@@ -489,6 +489,18 @@ enum PanoramaType {
PANORAMA_NUM_TYPES,
};
/* Specifies an offset for the shutter's time interval. */
enum MotionPosition {
/* Shutter opens at the current frame. */
MOTION_POSITION_START = 0,
/* Shutter is fully open at the current frame. */
MOTION_POSITION_CENTER = 1,
/* Shutter closes at the current frame. */
MOTION_POSITION_END = 2,
MOTION_NUM_POSITIONS,
};
/* Direct Light Sampling */
enum DirectLightSamplingType {
@@ -635,6 +647,9 @@ typedef enum AttributeStandard {
ATTR_STD_VOLUME_HEAT,
ATTR_STD_VOLUME_TEMPERATURE,
ATTR_STD_VOLUME_VELOCITY,
ATTR_STD_VOLUME_VELOCITY_X,
ATTR_STD_VOLUME_VELOCITY_Y,
ATTR_STD_VOLUME_VELOCITY_Z,
ATTR_STD_POINTINESS,
ATTR_STD_RANDOM_PER_ISLAND,
ATTR_STD_SHADOW_TRANSPARENCY,
@@ -808,6 +823,8 @@ enum ShaderDataObjectFlag {
SD_OBJECT_CAUSTICS_CASTER = (1 << 9),
/* object is caustics receiver */
SD_OBJECT_CAUSTICS_RECEIVER = (1 << 10),
/* object has attribute for volume motion */
SD_OBJECT_HAS_VOLUME_MOTION = (1 << 11),
/* object is using caustics */
SD_OBJECT_CAUSTICS = (SD_OBJECT_CAUSTICS_CASTER | SD_OBJECT_CAUSTICS_RECEIVER),
@@ -815,7 +832,8 @@ enum ShaderDataObjectFlag {
SD_OBJECT_FLAGS = (SD_OBJECT_HOLDOUT_MASK | SD_OBJECT_MOTION | SD_OBJECT_TRANSFORM_APPLIED |
SD_OBJECT_NEGATIVE_SCALE_APPLIED | SD_OBJECT_HAS_VOLUME |
SD_OBJECT_INTERSECTS_VOLUME | SD_OBJECT_SHADOW_CATCHER |
SD_OBJECT_HAS_VOLUME_ATTRIBUTES | SD_OBJECT_CAUSTICS)
SD_OBJECT_HAS_VOLUME_ATTRIBUTES | SD_OBJECT_CAUSTICS |
SD_OBJECT_HAS_VOLUME_MOTION)
};
typedef struct ccl_align(16) ShaderData
@@ -1040,7 +1058,7 @@ typedef struct KernelCamera {
int rolling_shutter_type;
float rolling_shutter_duration;
int pad;
int motion_position;
} KernelCamera;
static_assert_align(KernelCamera, 16);
@@ -1117,13 +1135,18 @@ typedef struct KernelFilm {
float4 xyz_to_g;
float4 xyz_to_b;
float4 rgb_to_y;
/* Rec709 to rendering color space. */
float4 rec709_to_r;
float4 rec709_to_g;
float4 rec709_to_b;
int is_rec709;
int pass_bake_primitive;
int pass_bake_differential;
int use_approximate_shadow_catcher;
int pad1, pad2;
int pad1;
} KernelFilm;
static_assert_align(KernelFilm, 16);
@@ -1381,7 +1404,8 @@ typedef struct KernelObject {
uint visibility;
int primitive_type;
int pad1;
/* Volume velocity scale. */
float velocity_scale;
} KernelObject;
static_assert_align(KernelObject, 16);

View File

@@ -14,6 +14,15 @@ ccl_device float3 xyz_to_rgb(KernelGlobals kg, float3 xyz)
dot(float4_to_float3(kernel_data.film.xyz_to_b), xyz));
}
ccl_device float3 rec709_to_rgb(KernelGlobals kg, float3 rec709)
{
return (kernel_data.film.is_rec709) ?
rec709 :
make_float3(dot(float4_to_float3(kernel_data.film.rec709_to_r), rec709),
dot(float4_to_float3(kernel_data.film.rec709_to_g), rec709),
dot(float4_to_float3(kernel_data.film.rec709_to_b), rec709));
}
ccl_device float linear_rgb_to_gray(KernelGlobals kg, float3 c)
{
return dot(c, float4_to_float3(kernel_data.film.rgb_to_y));

View File

@@ -360,6 +360,12 @@ const char *Attribute::standard_name(AttributeStandard std)
return "temperature";
case ATTR_STD_VOLUME_VELOCITY:
return "velocity";
case ATTR_STD_VOLUME_VELOCITY_X:
return "velocity_x";
case ATTR_STD_VOLUME_VELOCITY_Y:
return "velocity_y";
case ATTR_STD_VOLUME_VELOCITY_Z:
return "velocity_z";
case ATTR_STD_POINTINESS:
return "pointiness";
case ATTR_STD_RANDOM_PER_ISLAND:
@@ -587,6 +593,9 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
case ATTR_STD_VOLUME_FLAME:
case ATTR_STD_VOLUME_HEAT:
case ATTR_STD_VOLUME_TEMPERATURE:
case ATTR_STD_VOLUME_VELOCITY_X:
case ATTR_STD_VOLUME_VELOCITY_Y:
case ATTR_STD_VOLUME_VELOCITY_Z:
attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_VOXEL);
break;
case ATTR_STD_VOLUME_COLOR:

View File

@@ -397,6 +397,7 @@ void Camera::update(Scene *scene)
/* motion blur */
kcam->shuttertime = (need_motion == Scene::MOTION_BLUR) ? shuttertime : -1.0f;
kcam->motion_position = motion_position;
/* type */
kcam->type = camera_type;

View File

@@ -30,18 +30,6 @@ class Camera : public Node {
public:
NODE_DECLARE
/* Specifies an offset for the shutter's time interval. */
enum MotionPosition {
/* Shutter opens at the current frame. */
MOTION_POSITION_START = 0,
/* Shutter is fully open at the current frame. */
MOTION_POSITION_CENTER = 1,
/* Shutter closes at the current frame. */
MOTION_POSITION_END = 2,
MOTION_NUM_POSITIONS,
};
/* Specifies rolling shutter effect. */
enum RollingShutterType {
/* No rolling shutter effect. */

View File

@@ -1541,7 +1541,7 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro
}
Volume *volume = static_cast<Volume *>(geom);
create_volume_mesh(volume, progress);
create_volume_mesh(scene, volume, progress);
/* always reallocate when we have a volume, as we need to rebuild the BVH */
device_update_flags |= DEVICE_MESH_DATA_NEEDS_REALLOC;

View File

@@ -216,7 +216,7 @@ class GeometryManager {
protected:
bool displace(Device *device, Scene *scene, Mesh *mesh, Progress &progress);
void create_volume_mesh(Volume *volume, Progress &progress);
void create_volume_mesh(const Scene *scene, Volume *volume, Progress &progress);
/* Attributes */
void update_osl_attributes(Device *device,

View File

@@ -64,6 +64,11 @@ struct ToNanoOp {
}
};
# endif
VDBImageLoader::VDBImageLoader(openvdb::GridBase::ConstPtr grid_, const string &grid_name)
: grid_name(grid_name), grid(grid_)
{
}
#endif
VDBImageLoader::VDBImageLoader(const string &grid_name) : grid_name(grid_name)

View File

@@ -17,6 +17,9 @@ CCL_NAMESPACE_BEGIN
class VDBImageLoader : public ImageLoader {
public:
#ifdef WITH_OPENVDB
VDBImageLoader(openvdb::GridBase::ConstPtr grid_, const string &grid_name);
#endif
VDBImageLoader(const string &grid_name);
~VDBImageLoader();

View File

@@ -690,12 +690,16 @@ void Mesh::pack_shaders(Scene *scene, uint *tri_shader)
bool last_smooth = false;
size_t triangles_size = num_triangles();
int *shader_ptr = shader.data();
const int *shader_ptr = shader.data();
const bool *smooth_ptr = smooth.data();
for (size_t i = 0; i < triangles_size; i++) {
if (shader_ptr[i] != last_shader || last_smooth != smooth[i]) {
last_shader = shader_ptr[i];
last_smooth = smooth[i];
const int new_shader = shader_ptr ? shader_ptr[i] : INT_MAX;
const bool new_smooth = smooth_ptr ? smooth_ptr[i] : false;
if (new_shader != last_shader || last_smooth != new_smooth) {
last_shader = new_shader;
last_smooth = new_smooth;
Shader *shader = (last_shader < used_shaders.size()) ?
static_cast<Shader *>(used_shaders[last_shader]) :
scene->default_surface;

View File

@@ -439,6 +439,14 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
flag |= SD_OBJECT_HAS_VERTEX_MOTION;
}
}
else if (geom->is_volume()) {
Volume *volume = static_cast<Volume *>(geom);
if (volume->attributes.find(ATTR_STD_VOLUME_VELOCITY) &&
volume->get_velocity_scale() != 0.0f) {
flag |= SD_OBJECT_HAS_VOLUME_MOTION;
kobject.velocity_scale = volume->get_velocity_scale();
}
}
if (state->need_motion == Scene::MOTION_PASS) {
/* Clear motion array if there is no actual motion. */

View File

@@ -321,7 +321,7 @@ PassInfo Pass::get_info(const PassType type, const bool include_albedo, const bo
break;
case PASS_AOV_COLOR:
pass_info.num_components = 3;
pass_info.num_components = 4;
break;
case PASS_AOV_VALUE:
pass_info.num_components = 1;

View File

@@ -381,7 +381,7 @@ void Scene::device_update(Device *device_, Progress &progress)
}
}
Scene::MotionType Scene::need_motion()
Scene::MotionType Scene::need_motion() const
{
if (integrator->get_motion_blur())
return MOTION_BLUR;
@@ -407,6 +407,10 @@ bool Scene::need_global_attribute(AttributeStandard std)
return need_motion() != MOTION_NONE;
else if (std == ATTR_STD_MOTION_VERTEX_NORMAL)
return need_motion() == MOTION_BLUR;
else if (std == ATTR_STD_VOLUME_VELOCITY || std == ATTR_STD_VOLUME_VELOCITY_X ||
std == ATTR_STD_VOLUME_VELOCITY_Y || std == ATTR_STD_VOLUME_VELOCITY_Z) {
return need_motion() != MOTION_NONE;
}
return false;
}

View File

@@ -257,7 +257,7 @@ class Scene : public NodeOwner {
void need_global_attributes(AttributeRequestSet &attributes);
enum MotionType { MOTION_NONE = 0, MOTION_PASS, MOTION_BLUR };
MotionType need_motion();
MotionType need_motion() const;
float motion_shutter_time();
bool need_update();

View File

@@ -579,6 +579,10 @@ void ShaderManager::device_update_common(Device * /*device*/,
kfilm->xyz_to_g = float3_to_float4(xyz_to_g);
kfilm->xyz_to_b = float3_to_float4(xyz_to_b);
kfilm->rgb_to_y = float3_to_float4(rgb_to_y);
kfilm->rec709_to_r = float3_to_float4(rec709_to_r);
kfilm->rec709_to_g = float3_to_float4(rec709_to_g);
kfilm->rec709_to_b = float3_to_float4(rec709_to_b);
kfilm->is_rec709 = is_rec709;
}
void ShaderManager::device_free_common(Device *, DeviceScene *dscene, Scene *scene)
@@ -740,6 +744,11 @@ float ShaderManager::linear_rgb_to_gray(float3 c)
return dot(c, rgb_to_y);
}
float3 ShaderManager::rec709_to_scene_linear(float3 c)
{
return make_float3(dot(rec709_to_r, c), dot(rec709_to_g, c), dot(rec709_to_b, c));
}
string ShaderManager::get_cryptomatte_materials(Scene *scene)
{
string manifest = "{";
@@ -802,11 +811,29 @@ void ShaderManager::init_xyz_transforms()
{
/* Default to ITU-BT.709 in case no appropriate transform found.
* Note XYZ here is defined as having a D65 white point. */
xyz_to_r = make_float3(3.2404542f, -1.5371385f, -0.4985314f);
xyz_to_g = make_float3(-0.9692660f, 1.8760108f, 0.0415560f);
xyz_to_b = make_float3(0.0556434f, -0.2040259f, 1.0572252f);
const Transform xyz_to_rec709 = make_transform(3.2404542f,
-1.5371385f,
-0.4985314f,
0.0f,
-0.9692660f,
1.8760108f,
0.0415560f,
0.0f,
0.0556434f,
-0.2040259f,
1.0572252f,
0.0f);
xyz_to_r = float4_to_float3(xyz_to_rec709.x);
xyz_to_g = float4_to_float3(xyz_to_rec709.y);
xyz_to_b = float4_to_float3(xyz_to_rec709.z);
rgb_to_y = make_float3(0.2126729f, 0.7151522f, 0.0721750f);
rec709_to_r = make_float3(1.0f, 0.0f, 0.0f);
rec709_to_g = make_float3(0.0f, 1.0f, 0.0f);
rec709_to_b = make_float3(0.0f, 0.0f, 1.0f);
is_rec709 = true;
#ifdef WITH_OCIO
/* Get from OpenColorO config if it has the required roles. */
OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
@@ -857,6 +884,12 @@ void ShaderManager::init_xyz_transforms()
const Transform rgb_to_xyz = transform_inverse(xyz_to_rgb);
rgb_to_y = float4_to_float3(rgb_to_xyz.y);
const Transform rec709_to_rgb = xyz_to_rgb * transform_inverse(xyz_to_rec709);
rec709_to_r = float4_to_float3(rec709_to_rgb.x);
rec709_to_g = float4_to_float3(rec709_to_rgb.y);
rec709_to_b = float4_to_float3(rec709_to_rgb.z);
is_rec709 = transform_equal_threshold(xyz_to_rgb, xyz_to_rec709, 0.0001f);
#endif
}

View File

@@ -208,6 +208,7 @@ class ShaderManager {
static void free_memory();
float linear_rgb_to_gray(float3 c);
float3 rec709_to_scene_linear(float3 c);
string get_cryptomatte_materials(Scene *scene);
@@ -239,6 +240,10 @@ class ShaderManager {
float3 xyz_to_g;
float3 xyz_to_b;
float3 rgb_to_y;
float3 rec709_to_r;
float3 rec709_to_g;
float3 rec709_to_b;
bool is_rec709;
};
CCL_NAMESPACE_END

View File

@@ -5763,7 +5763,9 @@ BlackbodyNode::BlackbodyNode() : ShaderNode(get_node_type())
void BlackbodyNode::constant_fold(const ConstantFolder &folder)
{
if (folder.all_inputs_constant()) {
folder.make_constant(svm_math_blackbody_color(temperature));
const float3 rgb_rec709 = svm_math_blackbody_color_rec709(temperature);
const float3 rgb = folder.scene->shader_manager->rec709_to_scene_linear(rgb_rec709);
folder.make_constant(rgb);
}
}

View File

@@ -10,9 +10,9 @@
# include <openvdb/tools/Dense.h>
# include <openvdb/tools/GridTransformer.h>
# include <openvdb/tools/Morphology.h>
# include <openvdb/tools/Statistics.h>
#endif
#include "util/foreach.h"
#include "util/hash.h"
#include "util/log.h"
#include "util/openvdb.h"
@@ -28,6 +28,7 @@ NODE_DEFINE(Volume)
SOCKET_FLOAT(clipping, "Clipping", 0.001f);
SOCKET_FLOAT(step_size, "Step Size", 0.0f);
SOCKET_BOOLEAN(object_space, "Object Space", false);
SOCKET_FLOAT(velocity_scale, "Velocity Scale", 1.0f);
return type;
}
@@ -482,11 +483,141 @@ static openvdb::GridBase::ConstPtr openvdb_grid_from_device_texture(device_textu
return sparse;
}
static int estimate_required_velocity_padding(openvdb::GridBase::ConstPtr grid,
float velocity_scale)
{
/* TODO: we may need to also find outliers and clamp them to avoid adding too much padding. */
openvdb::math::Extrema extrema;
openvdb::Vec3d voxel_size;
/* External .vdb files have a vec3 type for velocity, but the Blender exporter creates a vec4. */
if (grid->isType<openvdb::Vec3fGrid>()) {
openvdb::Vec3fGrid::ConstPtr vel_grid = openvdb::gridConstPtrCast<openvdb::Vec3fGrid>(grid);
extrema = openvdb::tools::extrema(vel_grid->cbeginValueOn());
voxel_size = vel_grid->voxelSize();
}
else if (grid->isType<openvdb::Vec4fGrid>()) {
openvdb::Vec4fGrid::ConstPtr vel_grid = openvdb::gridConstPtrCast<openvdb::Vec4fGrid>(grid);
extrema = openvdb::tools::extrema(vel_grid->cbeginValueOn());
voxel_size = vel_grid->voxelSize();
}
else {
assert(0);
return 0;
}
/* We should only have uniform grids, so x = y = z, but we never know. */
const double max_voxel_size = openvdb::math::Max(voxel_size.x(), voxel_size.y(), voxel_size.z());
if (max_voxel_size == 0.0) {
return 0;
}
const double estimated_padding = extrema.max() * static_cast<double>(velocity_scale) /
max_voxel_size;
return static_cast<int>(std::ceil(estimated_padding));
}
static openvdb::FloatGrid::ConstPtr get_vdb_for_attribute(Volume *volume, AttributeStandard std)
{
Attribute *attr = volume->attributes.find(std);
if (!attr) {
return nullptr;
}
ImageHandle &handle = attr->data_voxel();
VDBImageLoader *vdb_loader = handle.vdb_loader();
if (!vdb_loader) {
return nullptr;
}
openvdb::GridBase::ConstPtr grid = vdb_loader->get_grid();
if (!grid) {
return nullptr;
}
if (!grid->isType<openvdb::FloatGrid>()) {
return nullptr;
}
return openvdb::gridConstPtrCast<openvdb::FloatGrid>(grid);
}
class MergeScalarGrids {
typedef openvdb::FloatTree ScalarTree;
openvdb::tree::ValueAccessor<const ScalarTree> m_acc_x, m_acc_y, m_acc_z;
public:
MergeScalarGrids(const ScalarTree *x_tree, const ScalarTree *y_tree, const ScalarTree *z_tree)
: m_acc_x(*x_tree), m_acc_y(*y_tree), m_acc_z(*z_tree)
{
}
MergeScalarGrids(const MergeScalarGrids &other)
: m_acc_x(other.m_acc_x), m_acc_y(other.m_acc_y), m_acc_z(other.m_acc_z)
{
}
void operator()(const openvdb::Vec3STree::ValueOnIter &it) const
{
using namespace openvdb;
const math::Coord xyz = it.getCoord();
float x = m_acc_x.getValue(xyz);
float y = m_acc_y.getValue(xyz);
float z = m_acc_z.getValue(xyz);
it.setValue(math::Vec3s(x, y, z));
}
};
static void merge_scalar_grids_for_velocity(const Scene *scene, Volume *volume)
{
if (volume->attributes.find(ATTR_STD_VOLUME_VELOCITY)) {
/* A vector grid for velocity is already available. */
return;
}
openvdb::FloatGrid::ConstPtr vel_x_grid = get_vdb_for_attribute(volume,
ATTR_STD_VOLUME_VELOCITY_X);
openvdb::FloatGrid::ConstPtr vel_y_grid = get_vdb_for_attribute(volume,
ATTR_STD_VOLUME_VELOCITY_Y);
openvdb::FloatGrid::ConstPtr vel_z_grid = get_vdb_for_attribute(volume,
ATTR_STD_VOLUME_VELOCITY_Z);
if (!(vel_x_grid && vel_y_grid && vel_z_grid)) {
return;
}
openvdb::Vec3fGrid::Ptr vecgrid = openvdb::Vec3SGrid::create(openvdb::Vec3s(0.0f));
/* Activate voxels in the vector grid based on the scalar grids to ensure thread safety during
* the merge. */
vecgrid->tree().topologyUnion(vel_x_grid->tree());
vecgrid->tree().topologyUnion(vel_y_grid->tree());
vecgrid->tree().topologyUnion(vel_z_grid->tree());
MergeScalarGrids op(&vel_x_grid->tree(), &vel_y_grid->tree(), &vel_z_grid->tree());
openvdb::tools::foreach (vecgrid->beginValueOn(), op, true, false);
/* Assume all grids have the same transformation. */
openvdb::math::Transform::Ptr transform = openvdb::ConstPtrCast<openvdb::math::Transform>(
vel_x_grid->transformPtr());
vecgrid->setTransform(transform);
/* Make an attribute for it. */
Attribute *attr = volume->attributes.add(ATTR_STD_VOLUME_VELOCITY);
ImageLoader *loader = new VDBImageLoader(vecgrid, "merged_velocity");
ImageParams params;
attr->data_voxel() = scene->image_manager->add_image(loader, params);
}
#endif
/* ************************************************************************** */
void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress)
void GeometryManager::create_volume_mesh(const Scene *scene, Volume *volume, Progress &progress)
{
string msg = string_printf("Computing Volume Mesh %s", volume->name.c_str());
progress.set_status("Updating Mesh", msg);
@@ -495,7 +626,7 @@ void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress)
Shader *volume_shader = NULL;
int pad_size = 0;
foreach (Node *node, volume->get_used_shaders()) {
for (Node *node : volume->get_used_shaders()) {
Shader *shader = static_cast<Shader *>(node);
if (!shader->has_volume) {
@@ -529,7 +660,9 @@ void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress)
VolumeMeshBuilder builder;
#ifdef WITH_OPENVDB
foreach (Attribute &attr, volume->attributes.attributes) {
merge_scalar_grids_for_velocity(scene, volume);
for (Attribute &attr : volume->attributes.attributes) {
if (attr.element != ATTR_ELEMENT_VOXEL) {
continue;
}
@@ -567,9 +700,17 @@ void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress)
}
if (grid) {
/* Add padding based on the maximum velocity vector. */
if (attr.std == ATTR_STD_VOLUME_VELOCITY && scene->need_motion() != Scene::MOTION_NONE) {
pad_size = max(pad_size,
estimate_required_velocity_padding(grid, volume->get_velocity_scale()));
}
builder.add_grid(grid, do_clipping, volume->get_clipping());
}
}
#else
(void)scene;
#endif
/* If nothing to build, early out. */

View File

@@ -18,6 +18,7 @@ class Volume : public Mesh {
NODE_SOCKET_API(float, clipping)
NODE_SOCKET_API(float, step_size)
NODE_SOCKET_API(bool, object_space)
NODE_SOCKET_API(float, velocity_scale)
virtual void clear(bool preserve_shaders = false) override;
};

View File

@@ -32,6 +32,12 @@
# define SIMD_SET_FLUSH_TO_ZERO \
_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); \
_MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
#elif defined(__aarch64__) || defined(_M_ARM64)
# define _MM_FLUSH_ZERO_ON 24
# define __get_fpcr(__fpcr) __asm__ __volatile__("mrs %0,fpcr" : "=r"(__fpcr))
# define __set_fpcr(__fpcr) __asm__ __volatile__("msr fpcr,%0" : : "ri"(__fpcr))
# define SIMD_SET_FLUSH_TO_ZERO set_fz(_MM_FLUSH_ZERO_ON);
# define SIMD_GET_FLUSH_TO_ZERO get_fz(_MM_FLUSH_ZERO_ON)
#else
# define SIMD_SET_FLUSH_TO_ZERO
#endif
@@ -104,6 +110,23 @@ static struct PosInfTy {
static struct StepTy {
} step ccl_attr_maybe_unused;
#endif
#if defined(__aarch64__) || defined(_M_ARM64)
__forceinline int set_fz(uint32_t flag)
{
uint64_t old_fpcr, new_fpcr;
__get_fpcr(old_fpcr);
new_fpcr = old_fpcr | (1ULL << flag);
__set_fpcr(new_fpcr);
__get_fpcr(old_fpcr);
return old_fpcr == new_fpcr;
}
__forceinline int get_fz(uint32_t flag)
{
uint64_t cur_fpcr;
__get_fpcr(cur_fpcr);
return (cur_fpcr & (1ULL << flag)) > 0 ? 1 : 0;
}
#endif
/* Utilities used by Neon */

View File

@@ -25,6 +25,17 @@ CCL_NAMESPACE_BEGIN
using tbb::blocked_range;
using tbb::enumerable_thread_specific;
using tbb::parallel_for;
using tbb::parallel_for_each;
static inline void thread_capture_fp_settings()
{
#if TBB_INTERFACE_VERSION_MAJOR >= 12
tbb::task_group_context *ctx = tbb::task::current_context();
#else
tbb::task_group_context *ctx = tbb::task::self().group();
#endif
ctx->capture_fp_settings();
}
static inline void parallel_for_cancel()
{

View File

@@ -285,6 +285,21 @@ ccl_device_inline bool operator!=(const Transform &A, const Transform &B)
return !(A == B);
}
ccl_device_inline bool transform_equal_threshold(const Transform &A,
const Transform &B,
const float threshold)
{
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 4; y++) {
if (fabsf(A[x][y] - B[x][y]) > threshold) {
return false;
}
}
}
return true;
}
ccl_device_inline float3 transform_get_column(const Transform *t, int column)
{
return make_float3(t->x[column], t->y[column], t->z[column]);

View File

@@ -30,8 +30,10 @@ extern GHOST_SystemHandle GHOST_CreateSystem(void);
/**
* Specifies whether debug messages are to be enabled for the specific system handle.
* \param systemhandle: The handle to the system.
* \param debug: Flag for systems to debug.
*/
extern void GHOST_SystemInitDebug(GHOST_SystemHandle systemhandle, int is_debug_enabled);
extern void GHOST_SystemInitDebug(GHOST_SystemHandle systemhandle, GHOST_Debug debug);
/**
* Disposes the one and only system.

View File

@@ -452,8 +452,9 @@ class GHOST_ISystem {
/**
* Specify whether debug messages are to be shown.
* \param debug: Flag for systems to debug.
*/
virtual void initDebug(bool is_debug_enabled) = 0;
virtual void initDebug(GHOST_Debug debug) = 0;
/**
* Check whether debug messages are to be shown.

View File

@@ -573,6 +573,16 @@ typedef struct {
uint32_t frequency;
} GHOST_DisplaySetting;
typedef enum {
/** Axis that cursor grab will wrap. */
GHOST_kDebugDefault = (1 << 1),
GHOST_kDebugWintab = (1 << 2),
} GHOST_TDebugFlags;
typedef struct {
int flags;
} GHOST_Debug;
#ifdef _WIN32
typedef void *GHOST_TEmbedderWindowID;
#endif // _WIN32

View File

@@ -30,11 +30,11 @@ GHOST_SystemHandle GHOST_CreateSystem(void)
return (GHOST_SystemHandle)system;
}
void GHOST_SystemInitDebug(GHOST_SystemHandle systemhandle, int is_debug_enabled)
void GHOST_SystemInitDebug(GHOST_SystemHandle systemhandle, GHOST_Debug debug)
{
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
system->initDebug(is_debug_enabled);
system->initDebug(debug);
}
GHOST_TSuccess GHOST_DisposeSystem(GHOST_SystemHandle systemhandle)

View File

@@ -390,9 +390,9 @@ void GHOST_System::useWindowFocus(const bool use_focus)
m_windowFocus = use_focus;
}
void GHOST_System::initDebug(bool is_debug_enabled)
void GHOST_System::initDebug(GHOST_Debug debug)
{
m_is_debug_enabled = is_debug_enabled;
m_is_debug_enabled = debug.flags & GHOST_kDebugDefault;
}
bool GHOST_System::isDebugEnabled()

View File

@@ -334,8 +334,9 @@ class GHOST_System : public GHOST_ISystem {
/**
* Specify whether debug messages are to be shown.
* \param debug: Flag for systems to debug.
*/
virtual void initDebug(bool is_debug_enabled);
virtual void initDebug(GHOST_Debug debug);
/**
* Check whether debug messages are to be shown.

View File

@@ -872,6 +872,13 @@ GHOST_EventButton *GHOST_SystemWin32::processButtonEvent(GHOST_TEventType type,
int msgPosY = GET_Y_LPARAM(msgPos);
system->pushEvent(new GHOST_EventCursor(
::GetMessageTime(), GHOST_kEventCursorMove, window, msgPosX, msgPosY, td));
if (type == GHOST_kEventButtonDown) {
WINTAB_PRINTF("HWND %p OS button down\n", window->getHWND());
}
else if (type == GHOST_kEventButtonUp) {
WINTAB_PRINTF("HWND %p OS button up\n", window->getHWND());
}
}
window->updateMouseCapture(type == GHOST_kEventButtonDown ? MousePressed : MouseReleased);
@@ -914,6 +921,8 @@ void GHOST_SystemWin32::processWintabEvent(GHOST_WindowWin32 *window)
break;
}
case GHOST_kEventButtonDown: {
WINTAB_PRINTF("HWND %p Wintab button down", window->getHWND());
UINT message;
switch (info.button) {
case GHOST_kButtonMaskLeft:
@@ -939,9 +948,12 @@ void GHOST_SystemWin32::processWintabEvent(GHOST_WindowWin32 *window)
/* Test for Win32/Wintab button down match. */
useWintabPos = wt->testCoordinates(msg.pt.x, msg.pt.y, info.x, info.y);
if (!useWintabPos) {
WINTAB_PRINTF(" ... but associated system button mismatched position\n");
continue;
}
WINTAB_PRINTF(" ... associated to system button\n");
/* Steal the Win32 event which was previously peeked. */
PeekMessage(&msg, window->getHWND(), message, message, PM_REMOVE | PM_NOYIELD);
@@ -958,9 +970,14 @@ void GHOST_SystemWin32::processWintabEvent(GHOST_WindowWin32 *window)
mouseMoveHandled = true;
break;
}
else {
WINTAB_PRINTF(" ... but no system button\n");
}
}
case GHOST_kEventButtonUp: {
WINTAB_PRINTF("HWND %p Wintab button up", window->getHWND());
if (!useWintabPos) {
WINTAB_PRINTF(" ... but Wintab position isn't trusted\n");
continue;
}
@@ -986,10 +1003,14 @@ void GHOST_SystemWin32::processWintabEvent(GHOST_WindowWin32 *window)
if (PeekMessage(&msg, window->getHWND(), message, message, PM_REMOVE | PM_NOYIELD) &&
msg.message != WM_QUIT) {
WINTAB_PRINTF(" ... associated to system button\n");
window->updateMouseCapture(MouseReleased);
system->pushEvent(
new GHOST_EventButton(info.time, info.type, window, info.button, info.tabletData));
}
else {
WINTAB_PRINTF(" ... but no system button\n");
}
break;
}
default:
@@ -1318,6 +1339,12 @@ void GHOST_SystemWin32::setTabletAPI(GHOST_TTabletAPI api)
}
}
void GHOST_SystemWin32::initDebug(GHOST_Debug debug)
{
GHOST_System::initDebug(debug);
GHOST_Wintab::setDebug(debug.flags & GHOST_kDebugWintab);
}
void GHOST_SystemWin32::processMinMaxInfo(MINMAXINFO *minmax)
{
minmax->ptMinTrackSize.x = 320;
@@ -1593,6 +1620,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
// Wintab events, processed
////////////////////////////////////////////////////////////////////////
case WT_CSRCHANGE: {
WINTAB_PRINTF("HWND %p HCTX %p WT_CSRCHANGE\n", window->getHWND(), (void *)lParam);
GHOST_Wintab *wt = window->getWintab();
if (wt) {
wt->updateCursorInfo();
@@ -1601,6 +1629,20 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
break;
}
case WT_PROXIMITY: {
WINTAB_PRINTF("HWND %p HCTX %p WT_PROXIMITY\n", window->getHWND(), (void *)wParam);
if (LOWORD(lParam)) {
WINTAB_PRINTF(" Cursor entering context.\n");
}
else {
WINTAB_PRINTF(" Cursor leaving context.\n");
}
if (HIWORD(lParam)) {
WINTAB_PRINTF(" Cursor entering or leaving hardware proximity.\n");
}
else {
WINTAB_PRINTF(" Cursor neither entering nor leaving hardware proximity.\n");
}
GHOST_Wintab *wt = window->getWintab();
if (wt) {
bool inRange = LOWORD(lParam);
@@ -1616,6 +1658,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
break;
}
case WT_INFOCHANGE: {
WINTAB_PRINTF("HWND %p HCTX %p WT_INFOCHANGE\n", window->getHWND(), (void *)wParam);
GHOST_Wintab *wt = window->getWintab();
if (wt) {
wt->processInfoChange(lParam);
@@ -1632,6 +1675,32 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
eventHandled = true;
break;
////////////////////////////////////////////////////////////////////////
// Wintab events, debug
////////////////////////////////////////////////////////////////////////
case WT_CTXOPEN:
WINTAB_PRINTF("HWND %p HCTX %p WT_CTXOPEN\n", window->getHWND(), (void *)wParam);
break;
case WT_CTXCLOSE:
WINTAB_PRINTF("HWND %p HCTX %p WT_CTXCLOSE\n", window->getHWND(), (void *)wParam);
break;
case WT_CTXUPDATE:
WINTAB_PRINTF("HWND %p HCTX %p WT_CTXUPDATE\n", window->getHWND(), (void *)wParam);
break;
case WT_CTXOVERLAP:
WINTAB_PRINTF("HWND %p HCTX %p WT_CTXOVERLAP", window->getHWND(), (void *)wParam);
switch (lParam) {
case CXS_DISABLED:
WINTAB_PRINTF(" CXS_DISABLED\n");
break;
case CXS_OBSCURED:
WINTAB_PRINTF(" CXS_OBSCURED\n");
break;
case CXS_ONTOP:
WINTAB_PRINTF(" CXS_ONTOP\n");
break;
}
break;
////////////////////////////////////////////////////////////////////////
// Pointer events, processed
////////////////////////////////////////////////////////////////////////
case WM_POINTERUPDATE:
@@ -1692,6 +1761,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
break;
case WM_MOUSEMOVE:
if (!window->m_mousePresent) {
WINTAB_PRINTF("HWND %p mouse enter\n", window->getHWND());
TRACKMOUSEEVENT tme = {sizeof(tme)};
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = hwnd;
@@ -1740,6 +1810,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
}
break;
case WM_MOUSELEAVE: {
WINTAB_PRINTF("HWND %p mouse leave\n", window->getHWND());
window->m_mousePresent = false;
if (window->getTabletData().Active == GHOST_kTabletModeNone) {
event = processCursorEvent(window);

View File

@@ -259,6 +259,16 @@ class GHOST_SystemWin32 : public GHOST_System {
*/
void setTabletAPI(GHOST_TTabletAPI api) override;
/***************************************************************************************
** Debug Info
***************************************************************************************/
/**
* Specify which debug messages are to be shown.
* \param debug: Flag for systems to debug.
*/
void initDebug(GHOST_Debug debug) override;
protected:
/**
* Initializes the system.

View File

@@ -960,6 +960,7 @@ GHOST_Wintab *GHOST_WindowWin32::getWintab() const
void GHOST_WindowWin32::loadWintab(bool enable)
{
if (!m_wintab) {
WINTAB_PRINTF("Loading Wintab for window %p\n", m_hWnd);
if (m_wintab = GHOST_Wintab::loadWintab(m_hWnd)) {
if (enable) {
m_wintab->enable();
@@ -982,6 +983,7 @@ void GHOST_WindowWin32::loadWintab(bool enable)
void GHOST_WindowWin32::closeWintab()
{
WINTAB_PRINTF("Closing Wintab for window %p\n", m_hWnd);
delete m_wintab;
m_wintab = NULL;
}

View File

@@ -11,7 +11,6 @@
GHOST_Wintab *GHOST_Wintab::loadWintab(HWND hwnd)
{
/* Load Wintab library if available. */
auto handle = unique_hmodule(::LoadLibrary("Wintab32.dll"), &::FreeLibrary);
if (!handle) {
return nullptr;
@@ -116,6 +115,15 @@ GHOST_Wintab *GHOST_Wintab::loadWintab(HWND hwnd)
}
}
int sanityQueueSize = queueSizeGet(hctx.get());
WINTAB_PRINTF("HCTX %p %s queueSize: %d, queueSizeGet: %d\n",
hctx.get(),
__func__,
queueSize,
sanityQueueSize);
WINTAB_PRINTF("Loaded Wintab context %p\n", hctx.get());
return new GHOST_Wintab(std::move(handle),
info,
get,
@@ -183,7 +191,17 @@ GHOST_Wintab::GHOST_Wintab(unique_hmodule handle,
m_pkts{queueSize}
{
m_fpInfo(WTI_INTERFACE, IFC_NDEVICES, &m_numDevices);
WINTAB_PRINTF("Wintab Devices: %d\n", m_numDevices);
updateCursorInfo();
/* Debug info. */
printContextDebugInfo();
}
GHOST_Wintab::~GHOST_Wintab()
{
WINTAB_PRINTF("Closing Wintab context %p\n", m_context.get());
}
void GHOST_Wintab::enable()
@@ -249,6 +267,7 @@ void GHOST_Wintab::updateCursorInfo()
BOOL pressureSupport = m_fpInfo(WTI_DEVICES, DVC_NPRESSURE, &Pressure);
m_maxPressure = pressureSupport ? Pressure.axMax : 0;
WINTAB_PRINTF("HCTX %p %s maxPressure: %d\n", m_context.get(), __func__, m_maxPressure);
BOOL tiltSupport = m_fpInfo(WTI_DEVICES, DVC_ORIENTATION, &Orientation);
/* Check if tablet supports azimuth [0] and altitude [1], encoded in axResolution. */
@@ -259,6 +278,11 @@ void GHOST_Wintab::updateCursorInfo()
else {
m_maxAzimuth = m_maxAltitude = 0;
}
WINTAB_PRINTF("HCTX %p %s maxAzimuth: %d, maxAltitude: %d\n",
m_context.get(),
__func__,
m_maxAzimuth,
m_maxAltitude);
}
void GHOST_Wintab::processInfoChange(LPARAM lParam)
@@ -266,6 +290,7 @@ void GHOST_Wintab::processInfoChange(LPARAM lParam)
/* Update number of connected Wintab digitizers. */
if (LOWORD(lParam) == WTI_INTERFACE && HIWORD(lParam) == IFC_NDEVICES) {
m_fpInfo(WTI_INTERFACE, IFC_NDEVICES, &m_numDevices);
WINTAB_PRINTF("HCTX %p %s numDevices: %d\n", m_context.get(), __func__, m_numDevices);
}
}
@@ -456,3 +481,144 @@ bool GHOST_Wintab::testCoordinates(int sysX, int sysY, int wtX, int wtY)
return false;
}
}
bool GHOST_Wintab::m_debug = false;
void GHOST_Wintab::setDebug(bool debug)
{
m_debug = debug;
}
bool GHOST_Wintab::getDebug()
{
return m_debug;
}
void GHOST_Wintab::printContextDebugInfo()
{
if (!m_debug) {
return;
}
/* Print button maps. */
BYTE logicalButtons[32] = {0};
BYTE systemButtons[32] = {0};
for (int i = 0; i < 3; i++) {
printf("initializeWintab cursor %d buttons\n", i);
UINT lbut = m_fpInfo(WTI_CURSORS + i, CSR_BUTTONMAP, &logicalButtons);
if (lbut) {
printf("%d", logicalButtons[0]);
for (int j = 1; j < lbut; j++) {
printf(", %d", logicalButtons[j]);
}
printf("\n");
}
else {
printf("logical button error\n");
}
UINT sbut = m_fpInfo(WTI_CURSORS + i, CSR_SYSBTNMAP, &systemButtons);
if (sbut) {
printf("%d", systemButtons[0]);
for (int j = 1; j < sbut; j++) {
printf(", %d", systemButtons[j]);
}
printf("\n");
}
else {
printf("system button error\n");
}
}
/* Print context information. */
/* Print open context constraints. */
UINT maxcontexts, opencontexts;
m_fpInfo(WTI_INTERFACE, IFC_NCONTEXTS, &maxcontexts);
m_fpInfo(WTI_STATUS, STA_CONTEXTS, &opencontexts);
printf("%u max contexts, %u open contexts\n", maxcontexts, opencontexts);
/* Print system information. */
printf("left: %d, top: %d, width: %d, height: %d\n",
::GetSystemMetrics(SM_XVIRTUALSCREEN),
::GetSystemMetrics(SM_YVIRTUALSCREEN),
::GetSystemMetrics(SM_CXVIRTUALSCREEN),
::GetSystemMetrics(SM_CYVIRTUALSCREEN));
auto printContextRanges = [](LOGCONTEXT &lc) {
printf("lcInOrgX: %d, lcInOrgY: %d, lcInExtX: %d, lcInExtY: %d\n",
lc.lcInOrgX,
lc.lcInOrgY,
lc.lcInExtX,
lc.lcInExtY);
printf("lcOutOrgX: %d, lcOutOrgY: %d, lcOutExtX: %d, lcOutExtY: %d\n",
lc.lcOutOrgX,
lc.lcOutOrgY,
lc.lcOutExtX,
lc.lcOutExtY);
printf("lcSysOrgX: %d, lcSysOrgY: %d, lcSysExtX: %d, lcSysExtY: %d\n",
lc.lcSysOrgX,
lc.lcSysOrgY,
lc.lcSysExtX,
lc.lcSysExtY);
};
LOGCONTEXT lc;
/* Print system context. */
m_fpInfo(WTI_DEFSYSCTX, 0, &lc);
printf("WTI_DEFSYSCTX\n");
printContextRanges(lc);
/* Print system context, manually populated. */
m_fpInfo(WTI_DEFSYSCTX, CTX_INORGX, &lc.lcInOrgX);
m_fpInfo(WTI_DEFSYSCTX, CTX_INORGY, &lc.lcInOrgY);
m_fpInfo(WTI_DEFSYSCTX, CTX_INEXTX, &lc.lcInExtX);
m_fpInfo(WTI_DEFSYSCTX, CTX_INEXTY, &lc.lcInExtY);
m_fpInfo(WTI_DEFSYSCTX, CTX_OUTORGX, &lc.lcOutOrgX);
m_fpInfo(WTI_DEFSYSCTX, CTX_OUTORGY, &lc.lcOutOrgY);
m_fpInfo(WTI_DEFSYSCTX, CTX_OUTEXTX, &lc.lcOutExtX);
m_fpInfo(WTI_DEFSYSCTX, CTX_OUTEXTY, &lc.lcOutExtY);
m_fpInfo(WTI_DEFSYSCTX, CTX_SYSORGX, &lc.lcSysOrgX);
m_fpInfo(WTI_DEFSYSCTX, CTX_SYSORGY, &lc.lcSysOrgY);
m_fpInfo(WTI_DEFSYSCTX, CTX_SYSEXTX, &lc.lcSysExtX);
m_fpInfo(WTI_DEFSYSCTX, CTX_SYSEXTY, &lc.lcSysExtY);
printf("WTI_DEFSYSCTX CTX_*\n");
printContextRanges(lc);
for (unsigned int i = 0; i < m_numDevices; i++) {
/* Print individual device system context. */
m_fpInfo(WTI_DSCTXS + i, 0, &lc);
printf("WTI_DSCTXS %u\n", i);
printContextRanges(lc);
/* Print individual device system context, manually populated. */
m_fpInfo(WTI_DSCTXS + i, CTX_INORGX, &lc.lcInOrgX);
m_fpInfo(WTI_DSCTXS + i, CTX_INORGY, &lc.lcInOrgY);
m_fpInfo(WTI_DSCTXS + i, CTX_INEXTX, &lc.lcInExtX);
m_fpInfo(WTI_DSCTXS + i, CTX_INEXTY, &lc.lcInExtY);
m_fpInfo(WTI_DSCTXS + i, CTX_OUTORGX, &lc.lcOutOrgX);
m_fpInfo(WTI_DSCTXS + i, CTX_OUTORGY, &lc.lcOutOrgY);
m_fpInfo(WTI_DSCTXS + i, CTX_OUTEXTX, &lc.lcOutExtX);
m_fpInfo(WTI_DSCTXS + i, CTX_OUTEXTY, &lc.lcOutExtY);
m_fpInfo(WTI_DSCTXS + i, CTX_SYSORGX, &lc.lcSysOrgX);
m_fpInfo(WTI_DSCTXS + i, CTX_SYSORGY, &lc.lcSysOrgY);
m_fpInfo(WTI_DSCTXS + i, CTX_SYSEXTX, &lc.lcSysExtX);
m_fpInfo(WTI_DSCTXS + i, CTX_SYSEXTY, &lc.lcSysExtY);
printf("WTI_DSCTX %u CTX_*\n", i);
printContextRanges(lc);
/* Print device axis. */
AXIS axis_x, axis_y;
m_fpInfo(WTI_DEVICES + i, DVC_X, &axis_x);
m_fpInfo(WTI_DEVICES + i, DVC_Y, &axis_y);
printf("WTI_DEVICES %u axis_x org: %d, axis_y org: %d axis_x ext: %d, axis_y ext: %d\n",
i,
axis_x.axMin,
axis_y.axMin,
axis_x.axMax - axis_x.axMin + 1,
axis_y.axMax - axis_y.axMin + 1);
}
/* Other stuff while we have a log-context. */
printf("sysmode %d\n", lc.lcSysMode);
}

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