1
1

Compare commits

...

1191 Commits

Author SHA1 Message Date
6fc81d6bca Merge branch 'master' into xr-controller-support 2021-10-03 12:22:05 +09:00
85e1f28fca Fix controller model loading for no stb image 2021-10-03 12:16:07 +09:00
c4f65fa5da Cleanup
- Use doxygen style comments
- Improve comment for XR region type
- Improve RNA descriptions for XR nav location/rotation/scale
- Split controller draw callback into separate model and aim functions
2021-10-03 12:11:10 +09:00
d3afe0c126 Geometry Nodes: Resample Curve Fields Update
This update of the Resample Curve node allows a field to populate the
count or length input of the node depending on the current mode. The
field is evaluated on the spline domain.

Differential Revision: https://developer.blender.org/D12735
2021-10-02 21:45:51 -05:00
e863e05697 Data Transfer: Remove unnecessary noisy error message
I've seen requests to remove this or complaints about this error message
quite frequently. In lots of production files it's just always going off.
It's not an actionable warning, and since "slow" is relative, it isn't
always even correct.

Differential Revision: https://developer.blender.org/D12694
2021-10-02 20:33:15 -05:00
b57b4dfab1 Cleanup: clang-format 2021-10-03 12:13:29 +11:00
f49dff97d4 Cleanup: spelling in strings 2021-10-03 12:13:29 +11:00
74f45ed9c5 Cleanup: spelling in comments 2021-10-03 12:13:29 +11:00
Jarrett Johnson
c5c94e3eae Geometry Nodes: Add Rotate Euler Node
This commit introduces the Rotate Euler function node which modifies
an input euler rotation. The node replaces the "Point Rotate" node.

Addresses T91375.

Differential Revision: https://developer.blender.org/D12531
2021-10-02 20:04:45 -05:00
34cf33eb12 Geometry Nodes: Switch Node Fields Update
This update of the Switch node allows for field compatible types
to be switched through the node. This includes the following:

Float, Int, Bool, String, Vector, and Color

The remaining types are processed with the orginal code:

Geometry, Object, Collection, Texture, and Material

Because the old types require a diffent "switch" socket than the
field types, versioning for old files is included to move links
of those types to a new switch socket. Once fields of other types
are supported, this node can be updated to support them as well.

Differential Revision: https://developer.blender.org/D12642
2021-10-02 17:34:47 -05:00
Leon Leno
54927caf4f Geometry Nodes: Add side and fill segments to Cone/Cylinder nodes
This commit extends the 'Cone' and 'Cylinder' mesh primitive nodes,
with two inputs to control the segments along the side and in the fill.
This makes the nodes more flexible and brings them more in line with
the improved cube node.

Differential Revision: https://developer.blender.org/D12463
2021-10-02 17:29:25 -05:00
12e8c78353 Fix T91888: Pivot point settings shown in timeline
Added to timeline by accident in f9e0981976.
2021-10-01 23:26:59 +02:00
1476d35870 Geometry Nodes: Set Handle Type Node Field Update
This update of the Set Handle Type node allows for a bool field to be
used as the selection of the affected control point handles for
bezier splines. If no bezier splines are provided a info message is
shown.

Differential Revision: https://developer.blender.org/D12526
2021-10-01 14:22:24 -05:00
1fb364491b Geometry Nodes: Set Spline Type Node Field Update
This update of the Set Spline Type node allows for a bool field to be
used as the selection of the affected splines.

Differential Revision: https://developer.blender.org/D12522
2021-10-01 11:59:29 -05:00
eacdc0ab4a VSE: Draw active strips with a different color in the preview window 2021-10-01 18:03:18 +02:00
dc30a9087c Geometry Nodes: Spline Length Input Node
The Spline Length Input node provides a field containing the
length of the current evaluated spline to the Point and Spline
domains.

Differential Revision: https://developer.blender.org/D12706
2021-10-01 09:58:49 -05:00
9e456ca695 Asset Browser: expose current catalog ID in RNA
Add read-only access to the active catalog ID via
`context.space_data.params.catalog_id` in the Asset Browser context.

The UUID is exposed as string to Python.
2021-10-01 16:47:16 +02:00
aae96176e8 Geometry Nodes: Curve Subdivide Node with Fields
The curve subdivide node can now take an int field to specify the
number of subdivisions to make at each curve segment.

Reviewed by: Hans Goudey
Differential Revision: https://developer.blender.org/D12534
2021-10-01 09:43:04 -05:00
e1952c541a Cleanup: unused function declaration
This should have been removed during the recent velocity attribute
refactor.
2021-10-01 16:41:50 +02:00
Johan Walles
fb820496f5 Tracking: Sort motion tracking tracks by start and end frames
Enable sorting motion tracking tracks by start / end times.

Help identifying what cases reconstructed camera jumps, based
on information about whether any track starts/ends at the frame.

Based on revision eb0eb54d96.

{F10563305}

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D12621
2021-10-01 16:29:38 +02:00
f497e471f8 Asset Catalogs: always have an Asset Catalog Tree available
Always create an `AssetCatalogTree` in the `AssetCatalogService`. This
ensures that newly-created catalogs are immediately visible in the UI
(because they insert themselves into an already-existing tree).
2021-10-01 16:15:50 +02:00
3be4cb5b27 Cleanup: Asset Catalog Test, fix clang-tidy warnings
No functional changes.
2021-10-01 15:24:04 +02:00
56ce51d1f7 Asset Catalogs: add catalog filter for the asset browser
Given an "active catalog" (i.e. the one selected in the UI), construct
an `AssetCatalogFilter` instance. This filter can determine whether an
asset should be shown or not. It returns `true` when The asset's catalog
ID is:

- the active catalog,
- an alias of the active catalog (so different UUID that maps to the
  same path),
- a sub-catalog of the active catalog.

Not yet hooked up to the UI.
2021-10-01 15:22:05 +02:00
1c7ce7e0b4 Cleanup: asset catalogs, make function const
Declare `AssetCatalogService::find_catalog()` as `const`, as it's not
requiring modification off the service object.

No functional changes.
2021-10-01 15:22:05 +02:00
271210126e Fix T91834: Appending objects with shape keys into new file is broken.
Recent append refactor 'broke' this, we need special recursive care and
handling of those nasty shpae keys... again.
2021-10-01 14:49:04 +02:00
f9acf21063 Python API Docs: add an example of Bone.convert_local_to_pose usage.
The use case for this method is quite obscure and difficult to
understand without an example. Despite how big looks, this is
actually the simplest example that makes sense.
2021-10-01 15:47:30 +03:00
bdc66c9569 GPU: set 'GL_PACK_ALIGNMENT' 1 as default
This fixes T91828.

The current value of `GL_PACK_ALIGNMENT` may result in crash in the `gpu` module if the buffer is not aligned.

Differential Revision: https://developer.blender.org/D12720
2021-10-01 09:11:37 -03:00
eb3a8fb4e8 Fix T91872: incorrect socket inspection on group nodes
This bug was introduced in rBef45399f3be0955ba8.
2021-10-01 13:21:03 +02:00
798e593002 Fix T87189: Copy/pasting IDs does not handle properly instantiation.
Copy/Paste uses its own code path for ID linking, which was not setting
`LIB_TAG_DOIT` for proper instantiation later on.

Would be nice the make this logic closer to the rest of the link/append
code at some point, but for now this fix will do.
2021-10-01 12:21:08 +02:00
21c29480c3 Fix paste code linking 'direct' IDs with 'INDIRECT' flag.
No idea why this was done that way (it originate from initial paste
commit, rB12b642062c6f).

But the IDs 'selected' as direct paste in `BLO_library_link_copypaste`
should be 'directly' linked, it's similar case to actual append of
selected IDs by the user.

Related to T87189.
2021-10-01 12:21:08 +02:00
928d644895 Append: Fix appended objects potentially auto-instantiated in more than one collection.
Related to T87189.
2021-10-01 12:21:08 +02:00
af0b7925db Fix T87536: incorrect socket types in reroute nodes
This refactors and fixes the code that propagates socket types
through reroute nodes. In my tests it is faster than the previous
code. The difference becomes larger the more reroute nodes
there are, because the old code had O(n^2) runtime, while the
new code runs in linear time.

Differential Revision: https://developer.blender.org/D12716
2021-10-01 11:42:00 +02:00
7843cd63d8 Fix T91839: incorrect active vertex group index
Differential Revision: https://developer.blender.org/D12712
2021-10-01 11:36:10 +02:00
ae4b45145c Cleanup: Asset Catalog Paths, move default constructor to header file
No functional changes.
2021-10-01 10:58:33 +02:00
2e6c6426d3 Asset Catalogs: test that missing catalogs are created once
Add asset catalogs test, to ensure missing catalogs are only created once,
and not for every originally defined catalog.

No functional changes to Blender (the code was already doing the right
thing).
2021-10-01 10:58:16 +02:00
bdb7d262aa Cleanup: clang-tidy warnings 2021-10-01 16:20:31 +10:00
b559fb178e Gizmo: hide 2D gizmos while transforming
Hide gizmos in the sequencer & UV editor while transforming.
2021-10-01 16:19:12 +10:00
4485dc483c Cleanup: use C-style comments, nullptr for C++
Minor changes extracted from D6408
2021-10-01 10:45:09 +10:00
Vitor Boschi
3a59ddb292 Fix: Incorrect warning in curve to mesh node with instances
The node was setting a warning when used with instances on input,
even though it worked fine.

Differential Revision: https://developer.blender.org/D12718
2021-09-30 18:27:58 -05:00
66fe1c79f3 Compositor: Fix Composite node using alpha when "Use Alpha" is off
Alpha input was not receiving the final composite canvas 
as preferred causing a Translate operation being inserted 
for centering. This resulted in a transparent background.
The issue only affects Full Frame mode.
2021-09-30 23:56:53 +02:00
e2df5c8a56 Compositor: Fix Flip node not flipping translation on Full Frame
To match tiled implementation, flip center should not be translated
when canvas has offset. Instead the canvas offset needs to be flipped.
2021-09-30 23:56:53 +02:00
f3274bfa70 Compositor: Fix Dilate/Erode node crash with Step option
It was writing the buffer out of bounds.
Only "Full Frame" mode was affected.
2021-09-30 23:56:53 +02:00
4569d9c0c3 Compositor: Fix Movie Distortion node rendering an empty image
Input area of interest calculation was incorrect because `m_margin`
was uninitialized.
Only "Full Frame" mode was affected.
2021-09-30 23:10:27 +02:00
Pratik Borhade
33dc584b37 Fix T91285: Bad tooltip for VSE Slip operator
This patch is created to change the tooltip for Slip Strip Contents
As per the present info, only active strip will be affected.
But in reality selected strips can be trimmed with this operator.

Word Trim changed to Slip in tooltip

Reviewed By: campbellbarton

Differential Revision: https://developer.blender.org/D12450
2021-09-30 21:11:09 +02:00
Josef Raschen
213554f24a VSE: Add ASC CDL color correction method
Add Offset/Slope/Power controls to the color balance modifier. This is
already available in compositor.

Reviewed By: sergey, ISS

Differential Revision: https://developer.blender.org/D12575
2021-09-30 21:09:47 +02:00
8d60ac2bb0 Cleanup: Fix unused variable warning 2021-09-30 14:01:56 -05:00
Brecht Van Lommel
1a134c4c30 Cycles: refactor API for render output
* Add OutputDriver, replacing function callbacks in Session.
* Add PathTraceTile, replacing tile access methods in Session.
* Add more detailed comments about how this driver should be implemented.
* Add OIIOOutputDriver for Cycles standalone to output an image.

Differential Revision: https://developer.blender.org/D12627
2021-09-30 20:53:27 +02:00
a754e35198 Cycles: refactor API for GPU display
* Split GPUDisplay into two classes. PathTraceDisplay to implement the Cycles side,
  and DisplayDriver to implement the host application side. The DisplayDriver is now
  a fully abstract base class, embedded in the PathTraceDisplay.
* Move copy_pixels_to_texture implementation out of the host side into the Cycles side,
  since it can be implemented in terms of the texture buffer mapping.
* Move definition of DeviceGraphicsInteropDestination into display driver header, so
  that we do not need to expose private device headers in the public API.
* Add more detailed comments about how the DisplayDriver should be implemented.

The "driver" terminology might not be obvious, but is also used in other renderers.

Differential Revision: https://developer.blender.org/D12626
2021-09-30 20:48:08 +02:00
ac582056e2 Geometry Nodes: Swap order of geometry proximity inputs
"Target" is the most important, so it goes at the top.
2021-09-30 13:41:55 -05:00
Charlie Jolly
be70827e6f Nodes: Add Float Curve for GN and Shader nodes.
Replacement for float curve in legacy Attribute Curve Map node.

Float Curve defaults to [0.0-1.0] range.

Reviewed By: JacquesLucke, brecht

Differential Revision: https://developer.blender.org/D12683
2021-09-30 19:24:40 +01:00
827e30bd15 Geometry Nodes: Change default for mesh to points node
While "Vertices" may be less useful since mesh vertices are already
points, the output is more easily understandable, so it's a better
default.
2021-09-30 11:53:48 -05:00
6cff1d6480 Fix T91734: Crash snapping mesh if a beveled curve is present
`BKE_mesh_boundbox_get` cannot be called for objects of type Curve.

The BoundBox however does not match the object seen in the scene.
This will be dealt with in another commit.
2021-09-30 02:48:02 -03:00
dd3391dd99 Asset Catalogs: create missing parent catalogs
For every known catalog, ensure its parent catalog also exists. This
ensures that assets can be assigned to parent catalogs, even when they
didn't exist in the Catalog Definition File yet.
2021-09-30 17:34:58 +02:00
4389067929 Fix possible use-after-free in drag-drop handling logic
Would happen when there were multiple drag items in parallel. There was
a listbase constructed with twice the same item, even though that item
would be deleted after it was handled the first time.
2021-09-30 16:39:09 +02:00
4ee2d9df42 UI: Support easy dropping into/onto rows in new tree-view API
Adds an easy way to add drop support for tree-view rows.

Most of the work is handled by the tree-view UI code. The tree items can
simply override a few functions (`can_drop()`, `on_drop()`,
`drop_tooltip()`) to implement their custom drop behavior.

While dragging over a tree-view item that can be dropped into/onto, the
item can show a custom and dynamic tooltip explaining what's gonna
happen on drop.

This isn't used yet, but will soon be for asset catalogs.

See documentation here:
https://wiki.blender.org/wiki/Source/Interface/Views#Further_Customizations
2021-09-30 16:39:09 +02:00
42ce88f15c Cleanup: remove CatalogPath alias
The `CatalogPath` name was an alias for `std::string`, so that it could
be easily switched over to something else. This happened in the previous
commit (switched to `AssetCatalogPath`), so the alias is no longer
necessary.

This commit removes the `CatalogPath` alias.

No functional changes.
2021-09-30 16:34:30 +02:00
628fab696c Asset Catalog: introduce AssetCatalogPath class
So far we have used `std::string` for asset catalog paths. Some
operations are better described on a dedicated class for this, though.
This commits switches catalog paths from using `std::string` to a
dedicated `blender::bke::AssetCatalogPath` class.

The `using CatalogPath = AssetCatalogPath` alias is still there, and
will be removed in a following cleanup commit.

New `AssetCatalogPath` code reviewed by @severin in D12710.
2021-09-30 16:29:14 +02:00
5d42ea0369 GPencil: Change default template for better contrast in header
Patch created by Pablo Vazquez

This change darkens the header area a bit to create more contrast with the texts.

Differential Revision: https://developer.blender.org/D12711
2021-09-30 16:14:44 +02:00
d754d85845 Fix RigidBodyWorld copy using NO_MAIN instead of COW flag for cache handling.
We only want to share caches in case of CoW copying for the depsgraph,
not for regular `NO_MAIN` data.
2021-09-30 16:00:29 +02:00
1a72744ddc Fix T90246: Full Copy'ing a scene confuses physics in the original scene.
Handling of RigidBody data in duplicate of scenes/collections was very
wrong. This commit:
 - Add handling of duplication of RB collections when fully duplicating
   a scene.
 - Fix Object duplication trying to add duplicated RB objects to
   matching RBW collections.

While the later behavior is desired when only duplicated objects, when
duplicating their collections and/or scenes it is actually very bad, as
it would add back new object duplicates to old (RBW) collections.
2021-09-30 16:00:29 +02:00
779ea49af7 Cleanup: move node_common.c to c++
Buildbot compiled without problems.
2021-09-30 15:44:08 +02:00
07c5d02a11 Asset Browser: Support activating catalogs in the "Current File" library
If the "Current File" asset library is selected in the Asset Browser,
now asssets are filtered based on the active asset catalog. Previously
it would just show all assets. This was marked as a TODO in the code
already.

Maniphest Task: https://developer.blender.org/T91820
2021-09-30 15:23:13 +02:00
3453b22b1e Fix: Curve to Mesh node outputs original curve
It should only output the new mesh (and potentially instances
that are processed separately).
2021-09-30 13:33:21 +02:00
9628ef4135 Fix: wrong field input deduplication with Material Selection node 2021-09-30 12:51:09 +02:00
80d7cac22d Fix T91773: improve numerical stability in Curve Spiral node 2021-09-30 12:33:34 +02:00
ae0f944a57 Fix Cycles viewport flickering
Caused by a lack of synchronization between update process which sets
clear flag and the draw code checking the flag outside of a lock.
2021-09-30 11:44:53 +02:00
5f632f9f6e Fix color width regression in 66e24ce35b
Color buttons were drawing single icon width.
2021-09-30 17:45:09 +10:00
af13168a3f Cleanup: remove unused SpaceImage.curtile 2021-09-30 17:32:48 +10:00
e9dac3eab8 Cleanup: reduce Sequence size by 8 bytes
Also use int8_t for color tag.
2021-09-30 17:32:46 +10:00
fdcae48663 Cleanup: isolate UDIM parameters into a struct
Passing multiple UDIM arguments into the packing function
is awkward especially since the caller may not be using UDIM.

Use an argument to store UDIM packing parameters which can be NULL,
which operates without any UDIM support.

Add a function that extracts these parameters out of the image space
allowing for multiple functions to take UDIM parameters in the future.
2021-09-30 17:32:45 +10:00
2c2516bfc9 Fix(unreported): LineArt curve objects garbled result.
This is caused by line art loading curve objects twice from curve and converted mesh instances (when instance option is on). Now only load mesh when instance option is on.
2021-09-30 13:30:10 +08:00
66e24ce35b Fix menu width regression in c7d94a7827
Icon only popup buttons needed to be adjusted too,
add an uiTextIconPadFactor.icon_only to support this.
2021-09-30 12:43:52 +10:00
84dcf12ceb UI: Increase Area Resize Edge Hit Size
This patch increases the size of the Area BORDERPADDING a bit to make
it easier to hit the edges when initiating area resizing.

See D11925 for details and examples.

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

Reviewed by Campbell Barton
2021-09-29 15:05:58 -07:00
81f552e9ad Geometry Nodes: Expose Bezier handle positions as an attribute
This commit exposes left and right bezier handles as an attribute.
Interaction basically works like edit mode. If you move an aligned
handle, it also moves the opposite handle of the control point.
The difference is that you can't edit "Auto" or "Vector" handles,
you have to first use the "Set Handle Type" node. That gives the handle
types a bit more meaning in the node tree-- changing them in edit mod
is more like a "UI override".

The attributes are named `handle_start` and `handle_end`,
which is the same name used in the curve RNA API.

A new virtual array implementation is added which handles the case of
splines that don't have these attributes, and it also calls two new
functions on `BezierSpline` to set the handle position accounting
for aligned handles.

The virtual arrays and attribute providers will be refactored
(probably templated) in the future, as a next step after the last
built-in curve attribute provider has landed.

Differential Revision: https://developer.blender.org/D12005
2021-09-29 15:29:29 -05:00
cd03f5b6e5 Add RNA path funcs for VolumeRender & VolumeDisplay
Without proper RNA paths, Alt-click editing properties on multiple
selected objects doesn not work (as well as the 'Copy To Selected'
operator).

Fixes T91806.

Maniphest Tasks: T91806

Differential Revision: https://developer.blender.org/D12700
2021-09-29 21:39:56 +02:00
0cddbcf1d7 Fix T91803: Freestyle rendering as pass broken after recent changes 2021-09-29 21:14:37 +02:00
a2e321aa6d Cleanup: Compositor: Migrate most converter nodes to new socket builder
This migrates most nodes except for the switch view node.
This node requires dynamic sockets so its implementation will be more involved.
2021-09-29 14:48:30 -04:00
d3d021601d Nodes: Fix Split View missing identifier
Mistake from rB84251acfcc4534059d6ccd6682f8e37d529b9063
2021-09-29 14:48:30 -04:00
19785cb022 Fix Cycles CPU performance regression after recent change for intersections size
This struct is much bigger now, and does not actually need to be fully zero
initialized.
2021-09-29 20:25:16 +02:00
Himanshi Kalra
22c61e8060 Tests: Disable tests for non-compiled libraries
This diff disables tests for Boolean, subdivision surface and volume
when GMP, Opensubdiv and Openvdb are not compiled respectively.
It also changes the existing file structure and adds sub-folders for
boolean and subdivison tests. The volume folder only has one test and
is as unchanged structure-wise.

Reviewed By: JacquesLucke, LazyDodo

Differential Revision: https://developer.blender.org/D12448
2021-09-29 23:52:52 +05:30
6f23e4484d Fix non-finite curve normal causing Cycles to crash
Similar to the previous change in the area: need to avoid ray
point and direction becoming a non-finite value.

Use the view direction when the geometrical normal can not be
calculated.

Collaboration and sanity inspiration with Brecht!

Differential Revision: https://developer.blender.org/D12703
2021-09-29 19:49:59 +02:00
1d478851f8 GPencil: Avoid double depsgraph tag
The eval data is updated at the end of the function and this call just adds a calculation not used.
2021-09-29 19:21:54 +02:00
214baf5422 Assets: Enable recursive reading for the asset view template as well
This makes asset view templates, e.g. as used by the Pose Library add-on
use recursive asset loading, see

Also works around an issue that made assets not show up at all anymore
since fc7beac8d6. I'm creating a separate report for that regression,
but in the Asset Browser and Viewer it shouldn't be apparent currently.
2021-09-29 18:51:10 +02:00
45a312fd8f Fix build failure on Windows + wrong buffer size
Was using `NAME_MAX` which is defined in `limits.h`, which again may be
implicitly included by the compiler. Intend was to use the Blender
define `MAX_NAME`.
2021-09-29 17:49:42 +02:00
9d9f205dc4 Asset Browser: Initial Asset Catalog UI
The Asset Browser now displays a tree with asset catalogs in the left
sidebar.
This replaces the asset categories. It uses the new UI tree-view API
(https://wiki.blender.org/wiki/Source/Interface/Views#Tree-View).
Buttons are displayed for adding and removing of catalogs. Parent items
can be collapsed, but the collapsed/uncollapsed state is not stored in
files yet.
Note that edits to catalogs (e.g. new or removed catalogs) are only
written to the asset library's catalog definition files when saving a
.blend.

In the "Current File" asset library, we try to show asset catalogs from
a parent asset library, or if that fails, from the directory the file is
stored in. See adaf4f56e1.

There are plenty of TODOs and smaller glitches to be fixed still. Plus a
UI polishing pass should be done.

Important missing UI features:
* Dragging assets into catalogs (WIP, close to being ready).
* Renaming catalogs
* Proper handling of catalogs in the "Current File" asset library
  (currently not working well).

The "Current File" asset library is especially limited still. Since this
is the only place where you can assign assets to a catalog, this makes
the catalogs very cumbersome in general. To assign an asset to a
catalog, one has to manually copy the Catalog ID (a random hash like
number) to the asset metadata through a temporary UI in the Asset
Browser Sidebar. These limitations should be addressed over the next few
days, they are high priority.

Differential Revision: https://developer.blender.org/D12670
2021-09-29 17:15:23 +02:00
df9120b365 Fix T89864: Adding an asset referencing other objects adds it to scene but only adds data-blocks of referenced objects.
Link/append code needs proper access to scene/view3d data to handle
collections/objects instantiation.

Note that this is a temporary hack more than a proper fix, which would require
a deeper redesign of drag&drop code.

Also note that this will not handle 'properly' (i.e. as user would
expect it) cases like implicitely appended parent objects, in that only
the explicitely appended object will be dropped to the nes location, the
others will remain at their original coordinates.

Differential Revision: https://developer.blender.org/D12696
2021-09-29 17:10:42 +02:00
6aac892fad Cleanup: Enforce C linkage for internal File Browser header
This will be used by C++ code in the upcoming asset catalog UI commit.
2021-09-29 16:59:48 +02:00
367775ac6a Fix Cycles use of uninitialized value in volume stack intersection on CPU
Could cause an actual bug but probability is low in practice.
2021-09-29 16:37:32 +02:00
4d4113adc2 Cycles: record large number of transparent shadow intersections on CPU
So we can do fewer intersection calls, only on the GPU do we need to save
memory and do this in small steps.

Ref T87836
2021-09-29 16:37:32 +02:00
fe070fe33b Fix Cycles crash in certain hair configurations
The issue was caused by hair shader setup setting normal to a non
finite value, which then gets used to create a ray with non-finite
direction, making BVH traversal to run out of stack memory.

Happens with 150_0040_A.lighting.blend frame 112 of the Sprites
project.

Differential Revision: https://developer.blender.org/D12692
2021-09-29 16:14:23 +02:00
901fa96b7f Keymap: New preference to open folders on single click in file browser
Introduce a new keymap preference to navigate into folders by clicking on them once instead of twice.
Makes browsing folders faster albeit non-standard, so keeping this off by default for now.

Does not affect Industry Compatible or other keymaps.

It is still the possible to right-click to open context menu, hold Ctrl or Shift to select multiple items:

{F10651030, size=full}

----

Keymap preference:

{F10652759, size=full}

Part of T91537

Reviewed By: fsiddi, campbellbarton

Differential Revision: https://developer.blender.org/D12667
2021-09-29 15:57:57 +02:00
1f4545dc9c Cleanup: else-after-return 2021-09-29 15:48:16 +02:00
b80ed8396d Fix T89164: Sculpt "Smooth" brush crash with zero pressure
Caused by {rB3e5431fdf439}

Issue is that sculpting could start with using `SCULPT_smooth` and
(because of the Pressure sensitivity dropping to zero) code would switch
to `SCULPT_enhance_details_brush` at strength zero.
Issue with this though is that this can be in the middle or end of a
stroke and the necessary `ss->cache->detail_directions` are only
initialized for the first brush step (see
`SCULPT_stroke_is_first_brush_step` in `SCULPT_enhance_details_brush`).
With these missing, it could only go downhill from there.

Suggest to prevent the "mode-flip" from `SCULPT_smooth` to
`SCULPT_enhance_details_brush` (happening solely because of pressure
strength) by changing the condition.
Now do `SCULPT_enhance_details_brush` only if strength is **below** zero
and `SCULPT_smooth` else (flipping from enhance_details to regular smooth
is fine).

If inverting the brush in the middle of the stroke will be supported at
some point, the codepath of `smooth` would have to inform the cache that
invert changed and detail_directions would have to be initialized then
(even if not at the start of the stroke).

Maniphest Tasks: T89164

Differential Revision: https://developer.blender.org/D12676
2021-09-29 15:07:45 +02:00
c33a005297 Texts in Outliner dont activate
Texts in Outliner dont activate on selecting (Text Editor did not change
to selected text) which is a bit inconsistent to other ID types.

ref T90862

Maniphest Tasks: T90862

Differential Revision: https://developer.blender.org/D12412
2021-09-29 15:07:13 +02:00
ef29bf9023 Assets: Expose option to reuse data-block data when appending
With 794c2828af & f48a4aa0f9 it's possible to reuse possibly
expensive, nested data of a data-block when appending. E.g. the
texture of a material, or the mesh of an object. Without this it's easy
to bloat memory and the file size. Duplicated textures also cause
unnecessary shader recompilations.

The feature was intended to be the new default behavior for the Asset
Browser, but it wasn't actually added to the UI yet. This patch adds a
new import type option to the Asset Browser. So from the menu in the
header, you can now choose between:

* Link
* Append
* Append (Reuse Data)

The latter is the new default.

Maniphest Task: https://developer.blender.org/T91741

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

Reviewed by: Sybren Stüvel, Bastien Montagne
2021-09-29 15:02:38 +02:00
Falk David
5cebcb415e VSE: Add color tags to strips
This patch adds color tags to VSE strips, an overlay option to toggle the colors
on and off, a section in the theme settings to define the 9 possible colors and
two ways of changing the color tag through the UI. You can change the color
through the right-click context menu, or in the strip side panel next to the
strip name.

Color tags are defined in user preferences and they can be disabled in overlay
settings.

Reviewed By: campbellbarton, ISS

Differential Revision: https://developer.blender.org/D12405
2021-09-29 14:34:01 +02:00
ffb9577ac9 Cycles: Ensure finite displacement and background evaluation
Avoids possible numerical issues in the path tracing kernel, which
is most important for displacement as non-finite values in BVH can
lead to infinite node recursion during traversal.

Differential Revision: https://developer.blender.org/D12690
2021-09-29 14:06:10 +02:00
731325a022 Cycles: Make sure GPU transfer is finished prior display update
Noticed while looking into flickering issues in viewport.

Doesn't seem to solve the flicker issue for me, but is something
what is supposed to be happening anyway.

Differential Revision: https://developer.blender.org/D12673
2021-09-29 14:05:51 +02:00
adaf4f56e1 Support loading catalogs in the Current File asset library
When the Asset Browser shows the "Current File" asset library, now it
also attempts to load an asset catalog definition file from location of
the current .blend file. This happens as follows:
* First, see if the file is inside of an asset library that is "mounted" in the
  Preferences. Load the catalogs from there if so.
* Otherwise, if the file is saved, load the catalogs from the directory the
  file is saved in.
* If the file is not saved, no catalogs will be loaded.

Unit tests are being worked on in D12689.

Creating catalogs from the "Current File" asset library still doesn't work, as
the asset catalog service doesn't construct an in-memory catalog definition
file in that case yet.

Differential Revision: https://developer.blender.org/D12675
2021-09-29 13:18:44 +02:00
Gaia Clary
78b9a8c7b9 Add an option to silence bpy.ops.anim.keyframe_delete_v3d when used in Addons
The issues:

1.) When we want to remove keyframes from a range of frames in an
action,
then we can use bpy.ops.anim.keyframe_delete_v3d to remove the keys
frame by frame. However, whenever the operator hits a frame with no
keyframes, then it generates an error. While when it hits a frame
with keyframes, then it reports the numbner of removed keys.

This creates a lot of unnecessary noise in the Blender console.

2.) Furthermore a related issue is that WM_event_add_notifier() is
called also when no frames where removed. This seems to significantly
slow down the removal of keyframes in a range of frames at least
when i use vscode for debugging.

A proposal for improvement:
This patch adds an attribute 'confirm_success' which controls
if the operator reports back what it did (or did not) while
executing. Silent mode would then be called like this:

bpy.ops.anim.keyframe_delete_v3d(confirm_success=False)

Note: confirm_success is True by default so this patchj does not
change the behavior of Blender, it only gives the option to scripts.

3.) Personal note:
I have chosen the attribute name to be equal as it is used
in other related operators. However i rather would rename the
attribute to "verbose" (preferred) or "with_confirm". But i let this
to be decided by the reviewers. Thanks for your time to review!

Reviewed By: campbellbarton

Differential Revision: https://developer.blender.org/D12629
2021-09-29 13:09:17 +02:00
6351c73b75 Fix T88954: Rearranging of modifiers for linked objects no longer works.
There would be no modifier set in context in drag and drop case, in that
case try to get active modifier from active object instead.
2021-09-29 12:53:57 +02:00
0c32e3b312 Fix T91756: String to Curve node produces NaN when size is zero 2021-09-29 12:40:36 +02:00
4cf4bb2664 UI: swap tool and regular header
Swap the tool-header and header order so the tool-header
so the header is always next to the window edge.

Note that files saved in 3.0 will have overlapping headers when opened
in any version of Blender before this commit.

Reviewed By: Severin, fsiddi

Maniphest Tasks: T91536

Ref D12631
2021-09-29 20:03:47 +10:00
eabb134840 Fix T91802: vertex color layer name collides with itself
Vertex colors are already included in `mesh.attributes`. So they don't
have to be added to the collision checks separately.
2021-09-29 11:01:17 +02:00
24a965bb16 Fix T91767: crash when instancing geometry coming from modifier
The issue was that the `GeometrySet` that comes from the modifier does
not have full ownership of the mesh for legacy reasons to avoid copies.
Calling `ensure_owns_direct_data` makes sure that the geometry set
actually owns the geometry so that it can be instanced.
2021-09-29 10:55:32 +02:00
f51bef75f4 Geometry Nodes: instance on points in instances
For consistency with other nodes, we also want to process
all instances in the Points input independently. This allows
for more efficient instancing of many objects but also leads
to nested instancing. All instances are processed in their
local space, so that instances don't have to be realized.

Differential Revision: https://developer.blender.org/D12660
2021-09-29 10:10:12 +02:00
8cbec0beb2 Fix/bypass doversion for wire new colors
Some cases were not covered by the original doversion in
4a0ddeb62b. For now we make it always change the wire color regardless
of whether it was changed before or not.

This do a subversion bump.
2021-09-29 09:58:55 +02:00
Siddhartha Jejurkar
a285299ebb UV: Pack to closest/active UDIM
Implements T78397
Extends the functionality of pack islands operator to allow packing UVs
to either the closest or active UDIM tile.
This provides 2 new options for packing UVs :

* Closest UDIM: Selected UVs will be packed to the UDIM tile they were
  placed on. If not present on a valid UDIM tile, the UVs will be packed
  to the closest UDIM in UV space
* Active UDIM: Selected UVs will be packed to the active UDIM image tile
  In case, no image is present in the UV editor, then UVs will be packed
  to the tile on the UDIM grid where the 2D cursor is located.

Reviewed By: campbellbarton

Maniphest Tasks: T78397

Ref D12680
2021-09-29 17:53:09 +10:00
Siddhartha Jejurkar
bf06f76be6 UV Editor: Grid and snapping improvements
Implements T89789, T89792, custom grid (described as dynamic grid in
T78389) and UV grid snapping (T78391)
Replaces the default UV editor grid with 2 new types of grid :

* Custom grid: Allows the user to create an NxN grid, where the value
  of N is specified by the user.
* Subdividing grid: Subdivides the UV editor grid when the user
  zooms in the viewport and vice versa when zooming out.

UV snapping improvements :
* Increment snapping: Increment values for snapping are calculated based
  on which grid type is being used in the UV editor
  (subdividing or custom). In general the increment value is equal to
  the distance between 2 visible grid lines.
* Absolute grid snap: New toggle added to increment snapping option in
  the UV editor, allows UV grid snapping during translation.

Reviewed By: campbellbarton

Ref D12684
2021-09-29 17:48:35 +10:00
008ae26712 Fix T91237: Wrong Editors could sync animation 'Visible Range'
This was reported for the Outliner.

It was possible to set 'show_locked_time' on any space (via python, not
sure if there are other ways to achieve this).
Navigating in an animation editor obviously ruined the layout in certain
Editors that are not made for this.

Now restrict syncing to editors that support it well (the ones that have
this setting exposed in their menus) and prevent setting this in RNA.

Maniphest Tasks: T91237

Differential Revision: https://developer.blender.org/D12512
2021-09-29 09:12:47 +02:00
eddc3f5bc8 Cleanup: Add constructor for AttributeFieldInput 2021-09-28 23:19:33 -05:00
756c22bb41 Cleanup: Compositor: Migrate color nodes to new socket builder 2021-09-29 00:09:41 -04:00
d1220f795f UI: Update Levels Nodes
- Instead of making the enum expanded leave it in menu form.
- Use full words instead of letters.

Differential Revision: https://developer.blender.org/D12686
2021-09-28 21:36:15 -04:00
8e40bb2dea Nodes: Fix compositor viewer nodes having wrong alpha channel
Default should be black image with an alpha value of 1.
2021-09-28 20:33:42 -04:00
84251acfcc Cleanup: Compositor: Migrate most output nodes to new socket builder
This migrates most nodes except for the file output node.
This node requires dynamic sockets so its implementation will be more involved.
2021-09-28 20:13:42 -04:00
e81533b25e Cleanup: Simplify compositor Z Combine operation conversion 2021-09-28 18:46:10 -04:00
f0f70729b1 Fix: Knife undo with no cut segments left
Now if a user presses the knife tool undo key when there are no more cut segments to undo, the operator exits. Previously, it did nothing.
2021-09-28 23:09:54 +01:00
7f5d62dfc6 Cleanup: Make format 2021-09-28 18:03:33 -04:00
4a48482247 Cleanup: Compositor: Migrate most input nodes to new socket builder
This migrates most nodes except for the image/render layer nodes.
These nodes require dynamic sockets so their implementation will be more involved.
2021-09-28 18:00:14 -04:00
960b21e1d7 Cleanup: sort cmake file lists 2021-09-29 07:30:34 +10:00
6dceaafe5a Cleanup: trailing space, newlines at EOF 2021-09-29 07:30:34 +10:00
b524153d61 Cleanup: use C comments for plain text 2021-09-29 07:30:34 +10:00
79290f5160 Cleanup: spelling in comments 2021-09-29 07:29:15 +10:00
efe3a13b55 Cleanup: Removed redundant if macro 2021-09-28 21:57:42 +01:00
9f0a3a99ab Geometry Nodes: Fields version of attribute proximity node
Add a fields-aware implementation of the attribute proximity node.
The Source position is an implicit position field, but can be
connected with a position input node with alterations before use.
The target input and mode function the same as the original node.

Patch by Johnny Matthews with edits from Hans Goudey (@HooglyBoogly).

Differential Revision: https://developer.blender.org/D12635
2021-09-28 15:21:36 -05:00
283d76a70d Compositor: Full frame Glare node
Part of T88150.
2021-09-28 22:00:17 +02:00
0830211c95 Cleanup: Remove XRange and YRange in Compositor
Mostly unused and originally meant for areas with positive values.
With canvas compositing areas position may be negative.
2021-09-28 22:00:17 +02:00
f84fb12f5d Compositor: Add support for canvas compositing
This commit adds functionality for operations that require pixel
translation or resizing on "Full Frame" mode, allowing to adjust
their canvas. It fixes most cropping issues in translate, scale,
rotate and transform nodes by adjusting their canvas to the result,
instead of the input canvas.

Operations output buffer is still always on (0,0) position for
easier image algorithm implementation, even when the
canvas is not.

Current limitations (will be addressed on bcon2):
- Displayed translation in Viewer node is limited to 6000px.
- When scaling up the canvas size is limited to the
 scene resolution size x 1.5 . From that point it crops.

If none of these limitations are hit, the Viewer node displays
the full input with any translation.

Differential Revision: https://developer.blender.org/D12466
2021-09-28 22:00:17 +02:00
76377f0176 Compositor: Replace resolution concept by canvas
This is a code refactor in preparation of supporting canvas
compositing. See {D12466}.

No functional changes, all canvases are at (0,0) position matching
tiled implementation.

Differential Revision: https://developer.blender.org/D12465
2021-09-28 22:00:16 +02:00
2ecd963d87 Fix error in previous commit
`v_other` -> `v_step`
2021-09-28 16:57:49 -03:00
5cdb2aadfc Fix flag wrongly set in 'BM_face_split_edgenet_connect_islands'
Sometimes the `use_partial_connect` option could trigger the assert:
```
BLI_assert(!BM_elem_flag_test(l_iter->v, VERT_NOT_IN_STACK));
```

This can happen when `v_delimit->e` is not part of edgenet, so `v_other` will not have the flag.
2021-09-28 16:54:23 -03:00
Aaron Carlisle
c7a7c3f5e5 Cleanup: convert compositor nodes to c++
- Many cleanups of to use list base
- Some variable changes

These change is needed to migrate to the new socket builder API

Reviewed By: manzanilla

Differential Revision: https://developer.blender.org/D12366
2021-09-28 15:30:23 -04:00
87e315c237 Cleanup: Sort node types alphabetically 2021-09-28 14:20:29 -05:00
Johnny Matthews
85aac0ef6a Geometry Nodes: Field version of curve reverse node
The updated version has a selection input as a field
and does not realize instances implicitly.

Differential Revision: https://developer.blender.org/D12506
2021-09-28 13:53:20 -05:00
cc653c9b02 Fix potential render tests error with invalid utf-8 characters
In general should not happen, but better to report the actual error instead
of the Python test code failing.
2021-09-28 20:50:38 +02:00
95fca22bfe Geometry Nodes: Remove experimental option for fields
This enables fields as the official workflow for geometry nodes.
While many features are converted to use fields rather than the old
attribute workflow, many are not yet converted. In that case, the
unconverted nodes are still accessible with an experimental option.
In the coming weeks the rest of the nodes will be converted.

Differential Revision: https://developer.blender.org/D12672
2021-09-28 13:22:52 -05:00
86ec9d79ec Fix build without Cycles HIP device 2021-09-28 20:00:55 +02:00
e45ffce5fa Geometry Nodes: Use factor slider for distribution density factor
Though the factor isn't so useful to adjust by itself, and is mostly
useful when used with a field connected, the slider from 0 to 1 can
help to make it clear that it's just used as a multiplier for the max
density after distribution.

Differential Revision: https://developer.blender.org/D12654
2021-09-28 12:44:50 -05:00
Erik Abrahamsson
faedfd5740 Fix VS2017 compile error in String to Curves node
Because of a bug in VS2017 codecvt is replaced with Blender
BLI functions to convert from UTF8 to UTF32.

Differential Revision: https://developer.blender.org/D12655
2021-09-28 12:37:56 -05:00
Brian Savery
044a77352f Cycles: add HIP device support for AMD GPUs
NOTE: this feature is not ready for user testing, and not yet enabled in daily
builds. It is being merged now for easier collaboration on development.

HIP is a heterogenous compute interface allowing C++ code to be executed on
GPUs similar to CUDA. It is intended to bring back AMD GPU rendering support
on Windows and Linux.

https://github.com/ROCm-Developer-Tools/HIP.

As of the time of writing, it should compile and run on Linux with existing
HIP compilers and driver runtimes. Publicly available compilers and drivers
for Windows will come later.

See task T91571 for more details on the current status and work remaining
to be done.

Credits:

Sayak Biswas (AMD)
Arya Rafii (AMD)
Brian Savery (AMD)

Differential Revision: https://developer.blender.org/D12578
2021-09-28 19:18:55 +02:00
262b211856 Geometry Nodes: Mesh Point Cloud Conversion Nodes
This commit adds nodes to do direct conversion between meshes and point
clouds in geometry nodes. The conversion from mesh to points is helpful
to instance once per face, or once per edge, which was previously only
possibly with ugly work-arounds. Fields can be evaluated on the mesh
to pass them to the points with the attribute capture node.

The other conversion, point cloud to mesh vertices, is a bit less
obvious, though it is still a common request from users. It's helpful
for flexibility when passing data around, better visualization in the
viewport (and in the future, cycles), and the simplicity of points.

This is a step towards T91754, where point clouds are currently
combined with meshes when outputing to the next modifier after geometry
nodes. Since we're removing the implicit behavior for realizing
instances, it feels natural to use an explicit node to convert points
to vertices too.

Differential Revision: https://developer.blender.org/D12657
2021-09-28 12:14:13 -05:00
797064544e Geometry Nodes: Only show attribute toggle for field inputs
Change the toggle to switch between an attribute and a single value to
only display for inputs that are fields, as determined statically by
the field inferencing added in rB61f3d4eb7c7db7. This means the field
inferencing must be calculated on file load, since it's used in the UI.

Differential Revision: https://developer.blender.org/D12623
2021-09-28 12:05:42 -05:00
44e4f077a9 Geometry Nodes: Run nodes once on unique instance data
As described in T91672, often it can be much more efficient to run each
node only on the unique geometry of the instances, rather than realizing
all instances and potentially processing redundant data. Sometimes the
performance difference can be completely smooth vs. completely unusable.

Geometry nodes used to hide that choice from users by always realizing
instances, but recently we have decided to expose it. So this commit
makes nodes run once per unique reference in the entire tree of nested
instances in their input geometries, continuing the work started in
rB0559971ab377 and rBf94164d89629f0d2. For the old behavior, a realize
instances node can be added before the nodes, which is done in the
versioning code.

Differential Revision: https://developer.blender.org/D12656
2021-09-28 11:36:28 -05:00
b32b38b380 Fix T89400: Possible to delete objects used by overrides of collections.
This should not be allowed in general, added some initial call to check
when user is allowed to delete a data to search for mandatory override
usages...
2021-09-28 18:30:33 +02:00
f35ea668a1 Geometry Nodes: Move more nodes to legacy
- Curve to Points: Needs output sockets
- Curve Endpoitns: Needs the same output sockets
- Edge Split: Should have a selection input instead
- Subdivision Surface: Should not use "crease" implicitly
All new versions of these nodes should also not implicitly
realize instances.
2021-09-28 11:03:12 -05:00
e694165123 VSE: fix versioning code to the new maximum zoom level (128)
Since we bumped the number of channels to 128, I forgot to doversion the
editors. So new files (new editors) would have this right, but not
existing files.

Fixup to: 8fecc2a852
2021-09-28 17:58:41 +02:00
6ee2f2da96 Cleanup: asset catalog, remove obsolete TODO
No functional changes.
2021-09-28 17:47:34 +02:00
10d926cd4a Cleanup: asset catalogs, move file header definition to constant
Define the standard catalog definition file header in a constant,
separating it from the function that writes the entire file.

No functional changes.
2021-09-28 17:47:34 +02:00
3acf3e9e2f Geometry Nodes: don't realize instances in Instance on Points node
Part of T91672.
2021-09-28 17:46:32 +02:00
330a04d7c7 Fix T91393: Duplicating an action with python crashes Blender.
Own mistake when making NLA overridable, instead of assuming things
about the ID owner of the animation data being processed, properly
return and use the one found by `ED_actedit_animdata_from_context`.
2021-09-28 17:41:40 +02:00
53fa4801a0 Fix: Fluid/Cloth/DynamicPaint: Only share pointcaches in CoW case.
Particle copying code was already properly sharing pointcache between
orig data and its copy only when `LIB_ID_COPY_SET_COPIED_ON_WRITE` is
set, do the same for the other point cache users.

Using `LIB_ID_CREATE_NO_MAIN` here is waaaaaaay to much wide scope for
such a dangerous/advanced behavior, that kind of things has to be
strictly restricted in scope.
2021-09-28 17:41:40 +02:00
34ba6968b2 Cleanup: asset catalog service, remove obsolete write_to_disk function
Remove `AssetCatalogService::write_to_disk()` function. It has been
superseded by `write_to_disk_on_blendfile_save()`; the handful of test
functions that called the old function have been adjusted to use the
new one.

No functional changes to Blender itself.
2021-09-28 17:32:58 +02:00
f17ca53cdd Fix wrong update with shadow catcher and transparent film
This change fixes an issue when scene has a shadow catcher and film is
configured to be transparent. Starting viewport render and making the
background non-transparent will cause bad memory access (wrong render
and possibly crash).

Film passes depends on transparency of background, so check for this.

Demo file: F10650585

Differential Revision: https://developer.blender.org/D12666
2021-09-28 17:06:16 +02:00
640c4ace0b Cycles: Disable tile-level denoising
Only do denoising on the full-frame result. Saves render time.

Can re-consider in the future when/if we'll want to support
denoising during rendering (similar to viewport) to allow artists
to stop rendering when they see image to be good enough. Until
there is a design for that workflow stick to a more time efficient
rendering.

Differential Revision: https://developer.blender.org/D12662
2021-09-28 17:05:47 +02:00
ff7e67afd5 Geometry Nodes: Dashed lines for function flow
Use dashes to represent the function flow (while keeping continuous
lines for the data-flow).

It is important to tell both flows apart (the data and the function
 flow). The sockets help with that, the noodles help this further.

The "data flow" is evaluated at every single node. A user can inspect
the output sockets of those nodes and have a glimpse at their values.

The "function flow" (nodes) however is only evaluated in the geometry
nodes. The noodles are not transporting data in the same sense of the
"data flow". All that can be inspected are the attributes the functions
depend on.

Having this clearly communicated should help users to inspect the
nodetrees, read and understand the different flows in the same tree.

---

Known limitations:

At the moment the dash lines are not equidistant:

* It would be nice to get the "uv.x" to be resampled for the bezier curve
so the dashes are equally distributed in the curve.

* Using distance between the P3 and P0 instead of the real bezier curve
length seems to be fine.

---

Full disclaimer:

Changes with that much of a visual impact tend to be controversial. So
far the main feedback is that dashed lines can be associated to broken
link, and that there are better ways to represent the flows (or
different information that should be visually represented).

I'm fully aware of that. However dashed lines are already used in the
viewport and outliner to indicate (hierarchical) relation. Besides,
other approaches (double-lines, having the data flow to be more
distinct, ...) didn't pan out in the end (or didn't look as good as
this).

---

Impact in other editors:

The compositor uses mostly a "data flow" nodetree, so no change is
expected there.

The shader nodetree is one that could but doesn't have to change its
visual language.

The shader nodetree uses mostly "function flow" with some "data flow" nodes.
One can argue that it should be adapted to follow the
same pattern as geometry nodes (with the new noodles and the diamond
sockets). Oh the other hand, a shader nodetree has a single context.
When a node depends on the "UV", there is only one UV at a time for the
entire nodetree. So it can also be treated as a psedo "data flow"
nodetree if we want to avoid too many changes in other parts of Blender.

Differential Revision: https://developer.blender.org/D12602
2021-09-28 17:03:03 +02:00
728ae33f37 Cycles: Improve handling of tile file error
Expose them to the interface, and stop rendering as soon as possible.

Differential Revision: https://developer.blender.org/D12617
2021-09-28 16:58:27 +02:00
52a702468a Asset Catalog Service: add function to change catalog path
Add `AssetCatalogService::update_catalog_path()` to change the catalog
path of the given catalog, and also change the path of all the catalogs
contained within the given catalog.

Rebuilds the tree structure for the UI, but does not save the new catalog
definitions to disk.

No user-facing changes, just backend preparation for UI work.
2021-09-28 16:09:12 +02:00
d2004326a1 Geometry Nodes: remove empty mesh component in distribute node output 2021-09-28 15:52:31 +02:00
3e78c9e5bb Fix T91766: NLA Editor - Segmentation fault on strip resize
NLA and Dope Sheet use a specific transform operation to scale.

Unlike the conventional resize operation, `TIME_SCALE` operates on `td->val`.

This is a bit outside the convention of transform operators.

The expected thing in this case would be to work in `td->loc` and use the conventional resize operator.

But for now, to fix the problem, use `td->loc` in the `TIME_SCALE` operation.

This commit also brings a cleanup in the style of some comments and removing unnecessary `memset`.
2021-09-28 10:24:02 -03:00
3674347849 Assets: Clear Asset operator variants for clearing/setting Fake User
The Clear Asset operator (`ASSET_OT_clear`) now clears the Fake User.
This makes it symmetrical with the Mark Asset (`ASSET_OT_mark`)
operator, which sets Fake User to ensure assets are always saved to
disk.

Clear Asset now also has a `set_fake_user` boolean option, which allows
users to Clear Asset and set Fake User in one go.

The asset browser now shows these options in the context menu:
- Clear Asset: also clears Fake User. This makes it possible to actually
  remove assets from the blend file without leaving the Asset Browser.
- Clear Asset (Set Fake User): keeps the Fake User bit set. This makes
  it possible to "hide" the asset from the asset browser, without
  loosing the actual data.

Internally, the `ED_asset_clear_id(id)` function now always clears the
Fake User bit. If it was intended that this bit was kept set, it's up to
the caller to explicitly call `id_fake_user_set(id)` afterwards.

Manifest Task: T90844

Reviewed By: Severin

Differential Revision: https://developer.blender.org/D12663
2021-09-28 15:04:55 +02:00
73b2ecb297 Cleanup: typo in comment
Noticed by @david_black in D12392, thx!
2021-09-28 14:37:06 +02:00
Vitor Boschi da Silva
9490db1ad2 Cleanup: remove unused variable
As the title says

Reviewed By: lichtwerk, campbellbarton

Differential Revision: https://developer.blender.org/D12665
2021-09-28 14:29:02 +02:00
6a745e54f6 Cleanup: remove incorrect assert
The method works perfectly fine when `resource` is empty.
2021-09-28 13:32:22 +02:00
5d160dec3b Geometry Nodes: move legacy nodes to separate folder
Previously, we were moving them one by one. It's a lot easier
to just move all files at the same time.
2021-09-28 11:31:46 +02:00
b3431a8846 Fix Drivers Editor showing playhead on the X Axis
Currently the Drivers Editor shows this (the blue thing can be dragged
to change frame):
{F10647661}

But the Drivers Editors X axis is the output of the driver [which can be
further tweaked by the curve] not time(frame).
So it seems better to not mix them here, it is just confusing to have
two different units on one axis.
Especially since what we really want to look at in X (the drivers output
value) can be in a totally unrelated range compared to frames, so e.g.
we might be interested in a drivers range from 0.0 to 1.0 and a
framerange of 100 to 200, so putting this on one axis just does not make
sense. Better to use a separate timeline for this.

Note 2.79 also did not do this.

Maniphest Tasks: T91157

Differential Revision: https://developer.blender.org/D12392
2021-09-28 11:14:44 +02:00
6f29801f1b Fix Drivers Editor not hiding vertical part of cursor
When "Show Cursor" is unchecked, the Drivers Editor would still display
the vertical line representing the cursor x.

Probably overseen in {rB65072499c65a} (historically the vertical line
could represent either the current frame of the cursor X in drawing, but
this is now much more separate).

There is no point in seeing part of the cursor in the Drivers Editor if
this is disabled.

Also correct outdated comments.

ref. T91157

Maniphest Tasks: T91157

Differential Revision: https://developer.blender.org/D12391
2021-09-28 11:14:44 +02:00
b91946780c Path util: BLI_path_contains() case-insensitive on Windows
Make `BLI_path_contains()` case-insensitive on Windows. This behaviour
is dependent on the platform Blender is running on, like the rest of
BLI_path, and not on the style of paths (Windows-style paths will be
treated case-sensitively when Blender is running on Linux/macOS).
2021-09-28 11:05:45 +02:00
741fa8180c Fix T91679: Crash when saving bordered render as multilayer exr
The related issue which is fixed by this change is the missing noisy
image pass when denoising and border render is used,

Need to allocate passes after the passes has been copied from the
original render result.
2021-09-28 10:49:01 +02:00
e5ff9f3615 Cleanup: Move VSE channels check into own util function
Differential Revision: https://developer.blender.org/D12661
2021-09-28 10:44:39 +02:00
a64782b133 VSE: Implement sanity check for files with more channels than supported
This is a follow up to 8fecc2a852.

This makes sure future .blend files that have more channels than the
limit won't break Blender.

It can be backported to LTS.

This is part of https://developer.blender.org/D12645

Differential Revision: https://developer.blender.org/D12648
2021-09-28 10:23:13 +02:00
7cd43a9d28 Fix: field inferencing fails when there are undefined nodes 2021-09-28 10:19:16 +02:00
def8fd6330 Cleanup: support moving InstanceReference 2021-09-28 10:17:49 +02:00
e7b9423623 Geometry Nodes: multi-threading when modifying multiple geometry sets
Differential Revision: https://developer.blender.org/D12652
2021-09-28 10:17:00 +02:00
c7d94a7827 UI: avoid excessive padding for labels in headers
Labels in headers reserved space for an icon even when no icon was used.

This is caused by the shared function ui_text_icon_width adding 1.5x
a buttons X-units width the the width of the string.

Menu buttons detected this and subtracted the extra padding.

Instead of adding the same workaround for labels,
add ui_text_icon_width_ex that takes a padding argument.

Add presets for 'default', 'compact' and 'none' to avoid duplicating
padding values.

This allows removal of hard-coded label scaling for the add-object tool.
2021-09-28 14:36:52 +10:00
986d60490c Asset Browser: Allow World assets to be drag/dropped onto the viewport
While World data has always been able to be marked as an asset, there
was no way to actually use them from the asset browser. This change
allows users to drag-drop world assets onto the Viewport and have them
appended/linked to their scene.

Differential Revision: https://developer.blender.org/D12566
2021-09-27 21:00:17 -07:00
c53ffda8a4 Cleanup: Fix incorrect comments 2021-09-27 13:29:53 -05:00
f94164d896 Geometry Nodes: Do not realize instances in the material assign node
Only run the node once for every unique geometry set in the input's
instance heirarchy. This can massively improve performance when
there are many instances, but it will mean that the result is the same
for every instance. For the previous behavior, a "Realize Instances"
node can be used before this one.

This node can be changed without versioning since the old material
assign node was already deprecated and replaced.
2021-09-27 13:22:44 -05:00
5d70a4d7ee Geometry Nodes: Move output attribute names to a subpanel
In a sub-panel it will be clearer that they are outputs, since they
just look like more inputs now. Unfortunately it is not possible to
make sub-panels display conditionally currently, so the output
sub-panel will always be visible whether or not it is empty.

Differential Revision: https://developer.blender.org/D12653
2021-09-27 13:04:58 -05:00
e6aabcae14 Fix part of T91516: Cycles not rendering geometry nodes instances
Part of the fix is by Jacques. This fixes the most obvious case, but it's
still not clear how to deal with non-mesh geometry instances or how to handle
motion blur for such instances.
2021-09-27 19:49:43 +02:00
50b7253257 Cleanup: fix (harmless) uninitialized variable usage 2021-09-27 19:49:43 +02:00
8da23fd5aa Constraints: change default Stretch To rotation type to Swing.
As also explained in D6134, in most case of Stretch To usage in
rigs, it is desirable to use swing rotation, either via the old
method of pairing the constraint with Damped Track, or via the
Swing rotation type introduced in 2.82. This is for instance true
for all usages of the constraint in Rigify.

The reason can be understood by realizing that unlike order-
dependent euler rotations, swing is not biased to an axis, and
isn't affected by gimbal lock effects at merely 90 degrees
of rotation (it has only one singularity at 180 degrees).

Thus it makes sense to change the default for newly created
constraints to the Swing mode. This has no backward compatibility
concerns except for old tutorials and rig generation scripts.

Differential Revision: https://developer.blender.org/D12643
2021-09-27 20:45:03 +03:00
8967bcb755 Update RNA to user manual url mappings 2021-09-27 13:42:41 -04:00
847d355cab File/Asset Browser: Don't deselect other items when dragging
Basically this enables the select-tweaking behavior as per the
guidelines:
https://wiki.blender.org/wiki/Human_Interface_Guidelines/Selection#Select-tweaking.

We use this in most other other editors that allow selecting and
dragging multiple items. But besides the consistency improvement, this
is important if we want to support dragging multiple assets (or files)
in future. We want to support this at least for dragging multiple assets
into an asset catalog for the upcoming asset catalog UI.
2021-09-27 18:52:16 +02:00
c76ccd85be Cleanup: incorrect null check in asset library
Found by clang tidy (P2439).
2021-09-27 18:42:19 +02:00
11bfbc3337 Fix: Incorrect node socket name after recent refactor
Caused by rBc99cb814520480379
2021-09-27 11:21:33 -05:00
c75c08a737 Geometry Nodes: Distribute points once per instance reference
With this commit, the distribute points on faces node runs only
once for every unique mesh in its input. That means if there are
100 instances of the same mesh, it will only run once.

This basically reverts rB84a4f2ae68d408301. The optimization there
didn't end up being worth it in the end, since it complicates code
quite a lot. It's also incompatible with this method of dealing with
instances, and it breaks field evaluation for instances, where we would
have to make sure to handle each instance transform properly otherwise,
evaluating the field separately for every instance.

Differential Revision: https://developer.blender.org/D12630
2021-09-27 11:16:25 -05:00
efa9667c09 Cleanup: Asset catalogs, fix clang-tidy warning
Change `auto &catalog` to `const auto &catalog`.

No functional changes.
2021-09-27 18:14:44 +02:00
10061ee18a Asset Catalogs: write catalogs to disk when saving the blend file
The Asset Catalog Definition File is now saved whenever the blend file
is saved. The location of the CDF depends on where the blend file is
saved, and whether previously a CDF was already loaded, according to the
following rules. The first matching rule wins:

1. Already loaded a CDF from disk? -> Always write to that file.
2. The directory containing the blend file has a
   `blender_assets.cats.txt` file? -> Merge with & write to that file.
3. The directory containing the blend file is part of an asset library,
   as per the user's preferences? -> Merge with & write to
   `${ASSET_LIBRARY_ROOT}/blender_assets.cats.txt`
4. Create a new file `blender_assets.cats.txt` next to the blend file.
2021-09-27 18:14:21 +02:00
90aa0a5256 BKE Preferences: find asset library containing a path
Add `BKE_preferences_asset_library_containing_path(&U, some_path)` that
finds the asset library that contains the given path.

This is a simple linear search, returning the first asset library that
matches. There is no smartness when it comes to nested asset libraries
(like returning the library with the best-matching path), although this
could be a useful feature to add later.
2021-09-27 18:10:47 +02:00
aafbe111fc BLI Path: add function BLI_path_contains()
Add function `BLI_path_contains(container, containee)` that returns true
if and only `container` contains `containee`.

Paths are normalised and converted to native path separators before
comparing. Relative paths are *not* made absolute, to simplify the
function call; if this is necessary the caller has to do this conversion
first.
2021-09-27 18:10:47 +02:00
6578db57cd Fix T91691: Selecting "Remove unused slots" in Materials panel removes slots that are assigned to particle systems/hair.
`BKE_object_material_slot_used` would only check obdata usages, but
particle settings can also (weirdly enough) use objects' material slots.

So now, as its name suggests, `BKE_object_material_slot_used` does take
an object as parameter, and also checks for potential slot usage from
psys in the object.
2021-09-27 18:09:20 +02:00
824733ea47 Assets: Additions/fixes to the catalog system in preparation for the UI
* Fixes missing update of the catalog tree when adding catalogs.
* Adds iterators for the catalogs, needed for UI code.
* Store catalog ID in the catalog tree items, needed for UI code.
* Other smaller API additions for the UI.
* Improve comments and smaller cleanups.

New functions are covered with unit tests.

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

Reviewed by: Sybren Stüvel
2021-09-27 17:49:31 +02:00
5bea5e25d5 Fix T91728: Cycles render artifacts with motion blur and object attributes 2021-09-27 17:40:03 +02:00
0559971ab3 Geometry Nodes: add utility to process all instances separately
This adds a new `GeometrySet::modify_geometry_sets` method that can be
used to update each sub-geometry-set separately without making any
instances real.

Differential Revision: https://developer.blender.org/D12650
2021-09-27 17:35:45 +02:00
2189dfd6e2 Cycles: Rework OptiX visibility flags handling
Before the visibility test against the visibility flags was performed in an any-hit program in OptiX
(called `__anyhit__kernel_optix_visibility_test`), which was using the `__prim_visibility` array.
This is not entirely correct however, since `__prim_visibility` is filled with the merged visibility
flags of all objects that reference that primitive, so if one object uses different visibility flags
than another object, but they both are instances of the same geometry, they would appear the same
way. The reason that the any-hit program was used rather than the OptiX instance visibility mask is
that the latter is currently limited to 8 bits only, which is not sufficient to contain all Cycles
visibility flags (12 bits).

To mostly fix the problem with multiple instances and different visibility flags, I changed things to
use the OptiX instance visibility mask for a subset of the Cycles visibility flags (`PATH_RAY_CAMERA`
to `PATH_RAY_VOLUME_SCATTER`, which fit into 8 bits) and only fall back to the visibility test any-hit
program if that isn't enough (e.g. the ray visibility mask exceeds 8 bits or when using the built-in
curves from OptiX, since the any-hit program is then also used to skip the curve endcaps).

This may also improve performance in some cases, since by default OptiX can now perform the normal
scene intersection trace calls entirely on RT cores without having to jump back to the SM on every
hit to execute the any-hit program.

Fixes T89801

Differential Revision: https://developer.blender.org/D12604
2021-09-27 17:12:43 +02:00
7270ba011c Fix two issues with recent new Append code.
* ID pointer returned by `wm_file_link_append_datablock_ex` was
  improperly extracted from `WMLinkAppendDataItem` before append step.

* Code deleting linked IDs when their local matching version was re-used
  did not properly clear `LIB_TAG_DOIT` beforehand.
2021-09-27 16:36:07 +02:00
4a0ddeb62b Nodes: Change wire color to increase contrast
If the theme used by the user did not touch the wire or the wire outline
colors this will update them as well.

This was supposed to be a part of a bigger UI theme change for 3.0. But
it was expedited because of the recent change in line thickness for the
noodles (2bd0205215).

Theme change by Pablo Vazquez.

Differential Revision: https://developer.blender.org/D12649
2021-09-27 16:09:40 +02:00
3d2ce25afd Geometry Nodes: support creating new attributes in modifier
This patch allows passing a field to the modifier as output. In the
modifier, the user can choose an attribute name. The attribute
will be filled with values computed by the field. This only works
for realized mesh/curve/point data. As mentioned in T91376, the
output domain is selected in the node group itself. We might want
to add this functionality to the modifier later as well, but not now.

Differential Revision: https://developer.blender.org/D12644
2021-09-27 15:39:47 +02:00
43167a2c25 Fix T90570: Constraint validity not updated with library overrides.
For some reason was assuming setting a property in RNA would call its
update callback if any, but this actually needs to be done separately.

So add this call to `rna_property_override_operation_apply`.
2021-09-27 15:33:58 +02:00
5949d598bc RNA: Make is clear that Scene parameter of update callback may be NULL.
There are cases where there is no way to ensure we do have/know about an
active scene. Further more, this should not be required to perform
'real' updates on data, only to perform additional special handling in
current scene (mostly related to editing tools, UI, etc.).

This pointer is actually almost never used in practice, and half of its current
 usages are fairly close to abuse of the system (like calls to
`ED_gpencil_tag_scene_gpencil` or `BKE_rigidbody_cache_reset`).

This commit ensures that the few places using this 'active scene' pointer are
safely handling the `NULL` case, and clearly document the fact that a
NULL scene pointer is valid.
2021-09-27 15:33:58 +02:00
b077f0684e RNA: Fix bad usages of scene pointer in Update callbacks.
Scene passed to the update callback is the active scene it //may// not
be that actual ID owner of the affected data (although in practice it
should always be currently).
2021-09-27 15:33:58 +02:00
a6b53ef994 Cycles: print name of kernels on errors in CUDA queue, for debugging 2021-09-27 15:24:12 +02:00
2bd0205215 Geometry Nodes: make field links thinner than other links
This makes it easier to spot which links contain fields and which
contain data. Actually, the patch makes all other links a bit thicker.
However, with soon-to-be-implemented theme changes, the
perceived thickness will be the same as before.

This is part of T91563.

Differential Revision: https://developer.blender.org/D12646
2021-09-27 15:10:28 +02:00
8fecc2a852 Increase VSE strip channels limit from 32 to 128
The original limit dates back from 2002 when Blender went open source.
After that many years some productions (e.g., Sprite Fright) are already
experiencing limitations for complex edits.

The future plans is to support an initial shorter (2?) number of
channels with support to "unlimited" channels.

Finally, I'm bumping the minimum file requirement since files with more
than 32 channels won't work well in old Blender versions.

In a future commit I will implement a sanitization so that we only read (and write)
128 channels. Making sure future changes of this number won't corrupt Blender.

Differential Revision: https://developer.blender.org/D12645
2021-09-27 14:58:03 +02:00
Peter Fog
0419c74ae8 VSE: Clamp resulting frame in multiply mode
The clamp added will ensure immediate speed direction change on
changing to/from positive/negative speed factor when using the Speed
effect strip's Multiply mode.

Reviewed By: ISS, sergey

Differential Revision: https://developer.blender.org/D12462
2021-09-27 14:41:56 +02:00
4a562f5077 Fix T91714: Cycles direct/indirect clamp distinction not working correctly 2021-09-27 14:25:22 +02:00
2a0db195c9 Fix viewport roll working wrong
Mistake in own {rB69893ef27c91}.
Was mixing screen on region coordinates.
2021-09-27 14:19:38 +02:00
e87783a5ec Cleanup: spelling in comments 2021-09-27 21:04:34 +10:00
95af9317f0 Cleanup: remove unnecessary use of MEM_SAFE_FREE macro 2021-09-27 21:04:34 +10:00
2c2e1b3d61 Fix T81922: Pose bones F-Curves hidden for unselected objects
Whilst in pose-mode, the selection filter only includes other objects in
pose-mode instead of the object selection.

This makes sense as the selection of the pose bones what the user as
acting on in the 3D view.
The object selection only makes sense to use in object mode.

Reviewed By: sybren

Maniphest Tasks: T81922

Ref D12494
2021-09-27 21:04:34 +10:00
32ffb858d6 Keymap: resolve conflict with use_alt_cursor/Ctrl-LMB to add/extrude
While the option allows tools be be activated on press instead of tweak,
this meant box-select was catching Ctrl-LMB which is also used for
add/extrude in edit mode.

Resolve this by always using tweak for selection tools,
only supporting activation on press for other tools.

Note that this doesn't impact the default configuration.
2021-09-27 21:04:34 +10:00
c618075541 Cleanup: make format 2021-09-27 12:43:54 +02:00
a13b9d20b5 Cleanup: Move asset library remove function next to add function
Better to keep such related operations close together in code.
2021-09-27 12:32:21 +02:00
d90f542b04 Cleanup: Remove function declaration without definition
There is no function definition for this declaration. Instead there is
`BKE_preferences_asset_library_remove()`.
2021-09-27 12:31:06 +02:00
5d5504d8a4 3DView: ability to cancel out of viewport roll
This adds the ability to cancel out of the roll using ESC or RMB
(which is not common for viewops -- but makes sense in the case of roll
I think). This resets the view as well as potential locked cameras to
the original orientations (but does not remove potential autokeys --
which no transform does on cancel btw.)

Maniphest Tasks: T89883

Differential Revision: https://developer.blender.org/D12582
2021-09-27 11:54:25 +02:00
69893ef27c 3DView: Use "real" angle for viewport roll
Since its introduction in {rB5c569d227b64}, the view roll was based on
horizontal movement only. Using a "real" angle not only feels more
natural but also has the benefit of getting more precission the further
away from the center you are (just like regular rotation, brush/stencil
rotation etc.). A similar thing has already been implemented in the
Grease Pencil Tools Addon, now make the blender standard roll the same.

Since this is not using the transform system, we are still lacking a
line in the viewport (this could be added but since this is always based
on the center of the view we dont necessarily need this), as well as the
additional Shift-extra-precission behavior.

Fixes T89883

Maniphest Tasks: T89883

Differential Revision: https://developer.blender.org/D12582
2021-09-27 11:53:26 +02:00
8dcddbcc07 Fix T91711: Blender 3.0 - The Rain demo scene breaks (Proxy to Override auto conversion).
Proxy conversion is a fairly particular case of liboverride creation, in
which remapping all local usages of linked data probably makes more
sense, rather than only doing so whitin the overridden 'group' of IDs.
2021-09-27 11:11:43 +02:00
30ef197c7b Kernel: allow unregistering BKE callback functions
Introduce `BKE_callback_remove()`, which undoes the effect of
`BKE_callback_add()`. It also respects `funcstore->alloc` by freeing the
removed `funcstore` when needed.

This allows for shorter-lived objects in memory to unregister their
callbacks at the end of their lifespan.

`BKE_callback_global_finalize()` has been adjusted so that the
responsibility "remove a callback" is given to one function only.

Reviewed by: campbellbarton

Differential Revision: https://developer.blender.org/D12625
2021-09-27 10:57:23 +02:00
617954c143 Geometry Nodes: new Instance on Points node
This adds a new Instance on Points node that is a replacement
for the old Point Instance node. Contrary to the old node,
it does not have a mode to instance objects or collections
directly. Instead, the node has to be used with an Object/
Collection Info to achieve the same effect.

Rotation and scale of the instances can be adjusted in the node
directly or can be controlled with a field to get some variation
between instances.

The node supports placing different instances on different points.
The user has control over which instance is placed on which point
using an Instance Index input. If that functionality is used, the
Instance Geometry has to contain multiple instances that can are
instanced separately.

Differential Revision: https://developer.blender.org/D12478
2021-09-27 10:17:17 +02:00
547f7d23ca Geometry Nodes: support outputting collection children as instances
This adds two new input sockets to the Collection Info node:
* `Separate Children`: When turned off, the entire collection is output as a single
  collection instance (same behavior as before). When turned on, each child of
  the collection is output as a separate instance (children can be objects and collections).
  Toggling this input should not change the visual transforms of the output geometry.
* `Reset Children`: Only used when `Separate Children` is on. When used, the transforms
  of the instances are reset to the origin. This is useful when one wants to e.g. instance
  the collection children separately in the upcoming instancing node.

Part of D12478.
2021-09-27 10:17:17 +02:00
William Leeson
f3ace5aa80 Fixes T91632 by stopping the sample correlation between dimensions which was causing rendering artifacts on simple scenes.
Fix T91632: Stops the sample correlation between dimensions which was causing rendering artefacts on simple scenes.

This is done by increasing the amount of jitter the Cranley Patterson Rotation is allowed to add. Also, it uses the y dimension of the of the sample table for 1D sampling which causes further decorrelation between dimensions. As an additional measure the x and y dimensions are swapped randomly to provide further decorrelation.

Maniphest Tasks: T91632

Differential Revision: https://developer.blender.org/D12610
2021-09-27 09:54:37 +02:00
fe49904646 Fix: wrong socket shape in Vector input node 2021-09-27 09:34:17 +02:00
ddb0dc2527 Fix knife tool missing refresh changing the lock axes 2021-09-27 16:28:01 +10:00
10a26d583d Fix knife tool using an invalid event value check
The events value was checked without checking the expected modal state.
2021-09-27 16:28:01 +10:00
Lasse Foster
037e66999a FIX: T91697 Eevee Generated texture coordinates completly missing
This patch fixes Eevee-regression https://developer.blender.org/T91697

Reviewed By: jbakker

Differential Revision: https://developer.blender.org/D12634
2021-09-27 08:07:23 +02:00
d2dda0e8b9 Fix T91694: VSE crashes when creating new scene
Crash happened due to NULL dereference. Add NULL checks.
2021-09-27 06:58:07 +02:00
Peter Fog
ad3e5d2bf5 VSE: Expose Zoom to Fit in all display modes
Zoom to Fit is working in all display modes, but was only exposed in
Image mode. This patch exposes it in all Image modes.

Reviewed By: ISS

Differential Revision: https://developer.blender.org/D12632
2021-09-27 04:40:05 +02:00
f9e0981976 Fix T91666: Missing pivot point in VSE
Add pivot point setting for combined timeline and preview mode.
2021-09-27 04:20:37 +02:00
d046a1f2fa Functions: fail early when multi-function throws an exception
Multi-functions are not allowed to throw exceptions that are not
caught in the same multi-function. Previously, it was difficult to
backtrack a crash to a previously thrown exception.
2021-09-26 23:28:14 +02:00
1cd8a438bb Cleanup: simplify field evaluation 2021-09-26 23:28:14 +02:00
88a2b054da Fix T91732: crash in Set Position node on empty mesh 2021-09-26 23:28:14 +02:00
93b36fad68 Knife: Expose XYZ axis locking in modal keymap
A small quality of life improvement that will allow users to change the keys used for axis locking.
2021-09-26 22:18:24 +01:00
80f7bc6d8e LineArt: Smooth tolerance value for chaining.
smooth out jaggy lines with a given threshold. For each point in a stroke, the ones with in a given distance of its previous segment will be removed,
thus "zig-zag" artefacts can be cleaned up.

Reviewed By: Antonio Vazquez (antoniov)

Differential Revision: https://developer.blender.org/D12050
2021-09-26 19:43:12 +08:00
505422220d Cleanup: use override/final for derived classes.
This will help detecting missing API changes. Those keywords were added
on classes which did not already use them. Also added missing
`accepts_object_type()` on NURBS reader.
2021-09-25 09:31:00 +02:00
43394e41a8 Fix Alembic point cloud streaming.
Point clouds are not imported and read anymore. This was caused by an
API change in rB128eb6cbe928e58dfee1c64f340fd8d663134c26 which was not
applied to `AbcPointsReader`. It did not cause a compile error as the
base class as a default implementation for this method.
2021-09-25 09:31:00 +02:00
ab09844be8 Cleanup: typos in code and comments.
No functional changes.
2021-09-25 09:31:00 +02:00
a3027fb094 Fix T91662: VSE Image overlay is drawn for backdrop
Don't draw image overlay in timeline, image manipulation only works in
preview.
2021-09-24 21:18:03 +02:00
b314d3e787 Fix T91639: Cycles crash rendering high resolution images with multiple passes
We were writing large 2048x2048 tiles into EXR files, which appears to cause
integer overflow inside the OpenEXR library when there are multiple passes. Now
use smaller tiles in the image file, while still rendering large tiles.

This adds the requirement that the render tile size must be a multiple of 128
or be smaller than 128, this is adjusted automatically.
2021-09-24 21:08:14 +02:00
2dd3968335 Geometry Nodes: Add versioning and legacy warning for random float node 2021-09-24 14:06:41 -05:00
Johnny Matthews
536f9eb82e Geometry Nodes: Random Value Node
This node replaces the deprecated Attribute Randomize node, populating
a vector, float, integer or boolean field with random values. Vector,
float, and integer have min/max settings, which are also field aware.
The boolean type has a probability value for controlling what portion
of the output should be true. All four types have a field seed input
which is implicitly driven by the index, otherwise, all values would
be the same "random" value.

The Random Float node is now deprecated like other nodes, since it is
redundant with this node.

Differential Revision: https://developer.blender.org/D12603
2021-09-24 14:03:42 -05:00
c87e6b23be Assets: Read catalogs immediately when loading a library
Until now, the asset catalogs would only show up after all assets from
the library were loaded. Now the catalogs are read first, which makes
them appear pretty much immediately. This makes the UI more responsive
and feel less heavy.

I added a dedicated file-list type for asset libraries now. While not
necessarily needed, I prefer that so asset library specific stuff can be
handled in there.
2021-09-24 20:17:04 +02:00
Erik Abrahamsson
be16794ba1 Geometry Nodes: String to Curves Node
This commit adds a node that generates a text paragraph as curve
instances. The inputs on the node control the overall shape of the
paragraph, and other nodes can be used to move the individual instances
afterwards. To output more than one line, the "Special Characters" node
can be used.

The node outputs instances instead of real geometry so that it doesn't
have to duplicate work for every character afterwards. This is much
more efficient, because all of the curve evaluation and nodes like fill
curve don't have to repeat the same calculation for every instance of
the same character.

In the future, the instances component will support attributes, and the
node can output attribute fields like "Word Index" and "Line Index".

Differential Revision: https://developer.blender.org/D11522
2021-09-24 12:41:49 -05:00
Erik Abrahamsson
5c0017e85a Geometry Nodes: Special string characters node
This patch adds a new node called "Special Characters" with two string
outputs: "Line Break" and "Tab". This is necessary because the newline
character cannot be easily typed with a keyboard, but is necessary for
the string to curve node.

Differential Revision: https://developer.blender.org/D12620
2021-09-24 11:00:21 -05:00
bdb8ee9717 Fix Cycles memory leak in baking, after recent changes 2021-09-24 17:46:34 +02:00
Johnny Matthews
ef45399f3b Nodes: initial support for socket tooltips
This adds initial limited support for socket tooltips. It's limited
in a couple of ways for now:
* Only works when hovering over the socket shape, not when hovering
  over the value in the socket.
* Only works for built-in nodes that already use the new node
  declaration system. This can later be extended to support pynodes.

Those limitations are well worth it for now, given that the
implementation is quite simple and the impact on usability is quite
large. More complex updates to the layout system, that would allow
showing socket tooltips in the nodes, can be done later. With the
current implementation we can at least start writing tooltips for
geometry nodes now.

This commit already adds tooltips for the Cylinder node as an example.

Differential Revision: https://developer.blender.org/D12607
2021-09-24 17:13:40 +02:00
4a2c63f4bd Nodes: hide socket value when input is a field implicitly 2021-09-24 16:42:20 +02:00
90b410fe74 Fix: field evaluation crash when the domain size is zero 2021-09-24 16:42:20 +02:00
25d4de92fa Cleanup: UUID, add some documenting comments
No functional changes.
2021-09-24 16:34:25 +02:00
c0db8e3b41 Fix T91660: Cycles remaining render time does not take into account time limit 2021-09-24 16:34:15 +02:00
585998987a Cycles: some steps towards getting standalone compiling again
Render output and display still need to be rewritten to work with the new
system.
2021-09-24 16:34:14 +02:00
ab8f24811d Cleanup: remove unused device code and includes 2021-09-24 16:34:14 +02:00
9cf593f305 GPencil: Reorganize list of modifiers
As we have a now a new `Modify` column, we move some modifers to this column.
2021-09-24 16:27:58 +02:00
45e432b894 GPencil: Change Proximity distance properties to distance type
This keep consistency with mesh modifer.
2021-09-24 16:16:40 +02:00
ede14b3856 GPencil: Invert weight in Weight Proximity modifier
In meshes modifer the Lowest is 0 and Highest is 1.0 and this was working inverted for grease pencil. Now, it works equals to meshes modifier.

Also changed the tooltip to keep consistency with meshes modifier.
2021-09-24 16:16:40 +02:00
95ec6e4dd3 Geometry Nodes: make index field more reusable
Some inputs will be the index field implicitly, so we want this
class to be available outside of `node_geo_input_index.cc`.
2021-09-24 16:03:07 +02:00
1a1c546124 Fix T91240: Object duplication was duplicating its action twice.
Weird that this was not reported before, this was creating a lot of
extra actions everytime...
2021-09-24 15:25:49 +02:00
e1e380ba38 Asset Catalogs: write catalogs sorted by path & UUID
When writing asset catalog definition files, order the catalogs by
(path, UUID). This ensures that every write produces the same file, playing
nice with versioning / synchronisation systems.
2021-09-24 14:42:48 +02:00
ab9644382d UUID: add less-than operator
Add `operator<` to C++ class to allow lexicographic ordering of UUIDs.

This will be necessary when writing asset catalogs to disk in a predictable
(i.e. ordered) manner.
2021-09-24 14:42:48 +02:00
2b9ca0f112 Codestyle: Add brackets around body of if statements. 2021-09-24 13:38:03 +02:00
7e904139a3 Nodes: make dot in socket shape circular
Previously, it was a diamond shape when the overall
shape was a diamond.
2021-09-24 13:33:28 +02:00
2b5733ff01 Fix T91192: Context.copy() crashes on file load
The `ui_list` lookup from 87c1c8112f
didn't account for the region being unset.
2021-09-24 21:10:02 +10:00
dfe01628b0 Cleanup: old-style-declaration warning 2021-09-24 21:10:01 +10:00
e8c6e32348 Asset Catalogs: fix trailing slash test case
The "path with trailing slash" test catalog was using the same path as
another catalog, which meant it was ignored after doing the path
cleanup. It's now different in the test file in SVN, so it'll actually
show up in the test.
2021-09-24 12:53:14 +02:00
59387aabe8 LibOverride: deprecate Proxies: Remove 'Make Proxy' operator. 2021-09-24 12:40:04 +02:00
501b0190d6 LibOverride: Deprecate Proxies: Add auto-conversion on file load.
This commit also add an experimental userPreferences to prevent proxies
conversions on file load, and reporting for amount of coverted proxies
(and possible issues).

Note that potentially linked proxies from other libraries are not
hamdled here (this feature seems to be broken anyway in master
currently?).
2021-09-24 12:40:04 +02:00
cdcdd2c479 LibOverride: Add utils to convert all proxies to overrides. 2021-09-24 12:40:03 +02:00
e7ae2840a5 Geometry Nodes: new Distribute Points on Faces node
This adds a replacement for the deprecated Point Distribute node.

Arguments for the name change can be found in T91155.
Descriptions of the sockets are available in D12536.

Thanks to Jarrett Johnson for the initial patch!

Differential Revision: https://developer.blender.org/D12536
2021-09-24 11:50:02 +02:00
d8a5b768f0 BLI: expose more noise hash functions in header
This is a follow up of the previous commit.
These functions are useful for other areas of Blender as well.
2021-09-24 11:24:15 +02:00
bc27bafa54 BLI: make noise hash functions available in header 2021-09-24 10:55:23 +02:00
7ca48a3814 Fix: incorrect socket shape for noise texture input 2021-09-24 10:55:23 +02:00
f8a0e102cf Weightpaint Gradient tool: expose falloff to the UI
By default, we'll always get a falloff like this from the tool:
{F10559413}

But in the context of using vertexgroups in modifiers/modeling, a choice
on how the gradient falloff of the Weightpaint Gradient tool is shaped
would be desirable:
"real" linear:
{F10559416}
Custom:
{F10559421}
{F10559428}

The way the Weightpaint gradient tool works is a bit outside the usual
tools that use brushes [even though it creates a brush on the fly in
`WPGradient_userData`].
However, it does not have an entry in `eBrushWeightPaintTool` and adding
one there does not play nice for the same reasons (not "really" being
integrated in the brush-based tools).

So in order to expose the brush curve in the UI, we would have to do one
of the following:
- [1] try to use `VIEW3D_PT_tools_brush_falloff`, for this to work:
-- make all kinds of exception in python super classes [`FalloffPanel`,
`BrushPanel`, `UnifiedPaintPanel`, ... -- including making real entries
in `eBrushWeightPaintTool`] to get a proper tool mode and...
-- .. to also make sure Falloff Shape and Front-Face Falloff are not
available [which the tool seems to just not support in its current form]
- [2] just have a simple, contained panel for this tool alone

This patch implements [2] and adds it as part of the ToolDef (could also
be done in `VIEW3D_HT_tool_header`, but again, I think this is nice to
keep separate from the usual tools)
{F10559482}
{F10559485}

Testfile:
{F10559442}

Fixes T91636

Maniphest Tasks: T91636

Differential Revision: https://developer.blender.org/D12614
2021-09-24 10:52:12 +02:00
3ac342dc6d Cleanup: clang format 2021-09-24 10:45:36 +02:00
9a45a4c525 Cleanup: asset catalogs, fix clang-tidy warning
Remove unnecessary call to `std::string::c_str()`.

No functional changes.
2021-09-24 10:29:52 +02:00
e161f39660 Cleanup: clang-tidy 2021-09-24 10:25:16 +02:00
Jeroen Bakker
fc7beac8d6 FileBrowser: Reduce Overhead Browsing Libraries.
When Browsing libraries the asset files were opened multiple times.
once to determine the needed groups to query and once for each
group to query the items in the group. For file browsing this makes sense
but for asset browsing this can be reduced.

This patch will load the asset files recursively and only opens them once.
Another change is that only the assets are requested and not filtered out
later in the process.

This patch is needed to simplify the library indexing. Where
we need access to the full library content.

## The numbers ##

Benchmarked by adding scenes of the spring open movie to the default
asset library. Refreshing the asset library would recursively load all the files
there.

| **8bc27c508a** | Processed 317 'directories/libraries' | 7.573986s |
| **Patch** | Processed 42 'directories/libraries' | 0.821013s |

{F10442811}

Reviewed By: mont29, Severin

Maniphest Tasks: T91406

Differential Revision: https://developer.blender.org/D12499
2021-09-24 08:41:40 +02:00
Jeroen Bakker
6a88f83d67 Hair Info Length Attribute
Goal is to add the length attribute to the Hair Info node, for better control over color gradients or similar along the hair.

Reviewed By: #eevee_viewport, brecht

Differential Revision: https://developer.blender.org/D10481
2021-09-24 07:44:22 +02:00
0f764ade1a Fix T91661: Vector rotate output socket diconnects on file load
An incorrect name was used in the socket declaration refactor.
2021-09-23 23:56:15 -05:00
0e039749e3 Fix: Incorrect field visualization for some shader nodes
These need to be tagged as function nodes in their declaration.
2021-09-23 22:23:14 -05:00
bc65c7d0e5 Cleanup: spelling in comments 2021-09-24 11:31:23 +10:00
599d96e8f9 UI: keymap preference tweaks
- Expose option to use shortcuts to activate tools as an enum.
- "Emulate 3 Button Mouse" now disables preferences
  that depend on Alt-LMB.
2021-09-24 11:07:01 +10:00
bffda4185d Cleanup: group convenience assignments in the keymap 2021-09-24 11:07:01 +10:00
26141664f0 Fix: Curve fill node doesn't fill real geometry with instances
A misplaced return in the middle of the function made it so
the node didn't fill real geometry.
2021-09-23 17:45:41 -05:00
f7608276e3 Audaspace: port bugfix from upstream.
Fixes T91615: Instant crash when dragging video file into video editor sequencer
2021-09-23 23:27:49 +02:00
61f3d4eb7c Geometry Nodes: Initial socket visualization for fields.
This implements the update logic for the vizualization of which
sockets pass data or constants directly, and which pass functions.
The socket shapes may still have to be updated. That should be
done separately, because it might be a bit more involved, because
socket shapes are currently linked to keyframe shapes. Currently
the circle and diamond shapes are used with the following meanings:

 - Input Sockets:
    - Circle: Required to be a single value.
    - Diamond: This input supports fields.
 - Output Sockets:
    - Circle: This output is a single value.
    - Diamond: This output may be a field.

Connecting a field to a circle input socket is an error, since a
field cannot be converted to a single value. If the socket shape
is a diamond with a dot in the middle, it means it is currently
a single value, but could be a field.

In addition to socket shapes, the intention is to draw node links
differently based on the field status. However, the exact method for
conveying that isn't decided yet.

Differential Revision: https://developer.blender.org/D12584
2021-09-23 15:21:31 -05:00
c1b925f7ff Fix build error caused by typo 2021-09-23 15:20:57 -05:00
1bdaf0ebec Fix T91638: image editor Open Cached Render not loading some passes
Previously this was only loading built-in render passes. Now instead of trying
to load the scene render passes, load whatever passes exist in the cache file.
2021-09-23 20:45:42 +02:00
Charlie Jolly
7fb2b50e5d Fix: Build issue with MSVC
header for std::function was not included

reported/fixed by Charlie on chat
2021-09-23 12:33:27 -06:00
fc2255135e Paint: prevent RenderResults and Viewers where unappropriate
Using a RenderResult (or a Viewer) was never really working (think you
cant get a real ImBuff from these) -- cannot use it as a clone, stencil
or canvas [Single Image paint texture slot].

In the case of using it as a 2D paint clone image this would also crash
[due to the Image Editor drawing refactor in 2.91].

Now [in the spirit of T73182 / D11179], prevent using these where
unappropriate by using rna pointer polling functions.

Also add a security check for the 2D paint clone image crash in case a
stencil ImBuff cannot be provided for some reason, but generally old
files are now patched in do_versions_after_linking_300 (thx @brecht!).

Fixes T91625.

Maniphest Tasks: T91625

Differential Revision: https://developer.blender.org/D12609
2021-09-23 20:11:45 +02:00
b8a30c7664 Cleanup: Use const in previously committed function 2021-09-23 19:39:26 +02:00
323fd80aad UI: Tree-View API for easy creation of tree UIs
This follows three main targets:

* Make creation of new tree UIs easy.
* Groundwork to generalize tree UIs (so e.g. Outliner, animation
  channels, asset catalogs and spreadsheet data-sets don't have to
  re-implement basic tree UI code) or even other data-view UIs.
* Better separate data and UI state. E.g. with this, tree-item selection
  or the open/collapsed state can be stored on the UI level, rather than
  in data. (Asset Catalogs need this, storing UI state info in them is
  not an option.)

In addition, the design should be well testable and could even be
exposed to Python.

Note that things will likely change in master still. E.g. the actually
resulting UI isn't very nice visually yet.

The design is documented here:
https://wiki.blender.org/wiki/Source/Interface/Views

Differential Revision: https://developer.blender.org/D12573
2021-09-23 19:33:54 +02:00
eb0eb54d96 Fix D12533: Simplify curve object to mesh conversion
This patch simplifies the curve object to mesh conversion
used by the object convert operator and exporters.

The existing code had a convoluted model of ownership, and did quite
a bit of unnecessary work. It also assumed that curve objects always
evaluated to a mesh, which is not the case anymore.

Now the code checks if the object it receives is evaluated. If so,
it can simply return a copy of the evaluated mesh (or convert the
evaluated curve wire edges to a mesh if there was no evaluated mesh).
If the object isn't evaluated, it uses a temporary copy of the object
with modifiers removed to create the mesh in the same way.

This follows up on the recent changes to curve evaluation,
namely that the result is always either a mesh or a wire curve.

Differential Revision: https://developer.blender.org/D12533
2021-09-23 11:41:46 -05:00
ed541de29d Fix T91626: Cycles sss behind fully transparent object renders differently 2021-09-23 18:32:30 +02:00
354c3eee40 Cycles: improve Auto Tile option description
Ref T91645
2021-09-23 18:32:30 +02:00
0a8a726014 bUUID: make it explicit the default constructor produces the nil value
The implicit default constructor zeroes all plain data fields, and now
this behaviour is explicit & tested for in a unit test.
2021-09-23 18:27:19 +02:00
18a4dc869d Cleanup: UUID, fix clang-tidy warnings
Use explicit `uint32_t` instead of `uint`, add a missing end-of-namespace
comment, and change `auto` to `const auto *`.

No functional changes.
2021-09-23 18:27:19 +02:00
502543e46b Geometry Nodes: remove old method to iterate over attributes
The previous commit added a new method to the same in a better way.
2021-09-23 17:59:44 +02:00
38af29df5c Geometry Nodes: simplify looping over attributes in geometry set
This adds three new methods:
* `InstancesComponent::foreach_reference_as_geometry(...)`
* `GeometrySet::attribute_foreach(...)`
* `GeometrySet::gather_attributes_for_propagation(...)`

The goal is that these iteration primitives can be used in places
where we use more specialized iterators currently.

Differential Revision: https://developer.blender.org/D12613
2021-09-23 17:59:44 +02:00
105115da9f UUID: add != operator for comparing UUIDs
Make it possible to unit test with `EXPECT_NE(uuid1, uuid2)`.
2021-09-23 17:58:20 +02:00
bd63944a73 UUID: place C++ code in correct namespace
Put the `bUUID` class in the `blender` namespace, instead of the
`blender::bke` namespace.

As a result, some C++ code now correctly uses the C++ class, where
previously it would use the C struct and use implicit casting where
necessary. As a result, support for initializer lists had to be
explicitly coded and in another place an explicit `::bUUID` was
necessary to avoid ambiguity.
2021-09-23 17:58:20 +02:00
942fc9f467 Cleanup: bUUID, document the constructors
No functional changes.
2021-09-23 17:58:20 +02:00
93997f9d0a Cleanup: asset catalogs, correct assertion message
There is no such thing as a "relative path" when it comes to asset catalog
paths (they're always absolute).

No functional changes.
2021-09-23 17:58:20 +02:00
d7f803f522 Fix T91641: crash rendering with 16k environment map in Cycles
Protect against integer overflow.
2021-09-23 17:48:16 +02:00
6279efbb78 Fix Cycles compiler warning on GCC 11
For shadow rays there are no closures, leave out the closure merging code
there to avoid warnings about accessing closure memory that does not exist.
2021-09-23 17:48:16 +02:00
d0493796a6 Cleanup: Remove hardcoded values and rename keyframe shape shaders
No functional change.

The shader is complicated by itself, having hardcoded values makes it
even more cryptic.

I also renamed the shader because the shader is not for the keyfarme diamond only,
but for all the keyframe shapes.

Differential Revision: https://developer.blender.org/D12615
2021-09-23 17:41:11 +02:00
f11bcb5a80 Fix T91557: Texture Paint Stencil doesnt use assigned UV Layer
Choosing a UV layer would actually affect the overlay in the viewport
and also painting with the mask brush was in that UV space, but the
resulting stencil mask was always applied with the active UV (not the
explicitly selected stencil UV -- the one one is looking at in the
viewport!) to painting.

This has been like that as far as I have checked back (at least 2.79b),
I am surprised this has not come up before, but it does not seem to make
sense at all...

Now use the UV specified for the stencil layer when applying the mask for
painting, so it corresponds to the stencil mask one is looking at in the
viewport.

Maniphest Tasks: T91557

Differential Revision: https://developer.blender.org/D12583
2021-09-23 16:56:03 +02:00
490425d56e Asset Catalogs: explicit version number in catalog definition files
Declare the current format used for asset catalog definition files as
version 1, and write that to the files. Files without that version number
will be rejected.

This makes it much easier to move to different versions later, with the
opportunity to do versioning on file load.

The version is not associated with any version of Blender, but a separate
integer that's simply incremented when a non-backward-compatible change
happens.
2021-09-23 16:06:25 +02:00
aa2493e2e7 Fix unused variable warning in release builds
The variable is only used in debug builds.
2021-09-23 15:04:41 +02:00
Sybren A. Stüvel
9b12b23d0b Assets: add Asset Catalog system
Catalogs work like directories on disk (without hard-/symlinks), in that
an asset is only contained in one catalog.

See T90066 for design considerations.

#### Known Limitations

Only a single catalog definition file (CDF), is supported, at
`${ASSET_LIBRARY_ROOT}/blender_assets.cats.txt`. In the future this is
to be expanded to support arbitrary CDFs (like one per blend file, one
per subdirectory, etc.).

The current implementation is based on the asset browser, which in
practice means that the asset browser owns the `AssetCatalogService`
instance for the selected asset library. In the future these instances
will be accessible via a less UI-bound asset system.

The UI is still very rudimentary, only showing the catalog ID for the
currently selected asset. Most notably, the loaded catalogs are not
shown yet. The UI is being implemented and will be merged soon.

#### Catalog Identifiers

Catalogs are internally identified by UUID. In older designs this was a
human-readable name, which has the problem that it has to be kept in
sync with its semantics (so when renaming a catalog from X to Y, the
UUID can be kept the same).

Since UUIDs don't communicate any human-readable information, the
mapping from catalog UUID to its path (stored in the Catalog Definition
File, CDF) is critical for understanding which asset is stored in which
human-readable catalog. To make this less critical, and to allow manual
data reconstruction after a CDF is lost/corrupted, each catalog also has
a "simple name" that's stored along with the UUID. This is also stored
on each asset, next to the catalog UUID.

#### Writing to Disk

Before saving asset catalogs to disk, the to-be-overwritten file gets
inspected. Any new catalogs that are found thre are loaded to memory
before writing the catalogs back to disk:

- Changed catalog path: in-memory data wins
- Catalogs deleted on disk: they are recreated based on in-memory data
- Catalogs deleted in memory: deleted on disk as well
- New catalogs on disk: are loaded and thus survive the overwriting

#### Tree Design

This implements the initial tree structure to load catalogs into. See
T90608, and the basic design in T90066.

Reviewed By: Severin

Maniphest Tasks: T91552

Differential Revision: https://developer.blender.org/D12589
2021-09-23 15:00:45 +02:00
222fd1abf0 Asset Browser: Disable metadata editing for external asset libraries
Buttons to edit asset metadata are now disabled for assets from an
external library (i.e. assets not stored in the current .blend file).
Their tooltips explain why they are disabled.

Had to do some RNA trickery to disable the metadata properties at RNA
level, not at UI script level.
The basic idea is:
* Local data-block assets set the data-block as owning ID for the asset
  metadata RNA pointer now.
* That way we can use the owner ID to see where the metadata belongs to
  and decide if it's editable that way.
* Additionaly, some Python operators needed better polling so they show
  as grayed out, and don't just fail.

One important thing: Custom properties of the metadata can still be
edited. The edits won't be saved however. Would be nice to disable that,
but it's currently not supported on BPY/IDProperty/RNA level.

Addresses T82943.

Differential Revision: https://developer.blender.org/D12127
2021-09-23 14:46:13 +02:00
059d01d42e Fileops: call BLI_path_slash_native() in BLI_dir_create_recursive()
Make the Windows version of `BLI_dir_create_recursive()` call
`BLI_path_slash_native()` before it tries to handle the path. This
should make it possible to call it with non-native path separators.

This change was provided by our Windows platform maintainer @LazyDodo in
P2414, so I assume he agrees with this change.
2021-09-23 14:42:14 +02:00
83975965a7 Keymap: RMB select option to place cursor on Alt-LMB
This allows most tools to activate on press, removing a small but
noticeable distance between the initial press and detection of a drag
event.

Gizmo tweak no longer actives when Alt is held, to avoid conflicting
with cursor placement.

This has the advantage that the gizmo doesn't get in the way when Alt
is used for activating tools or placing the cursor.
2021-09-23 22:10:56 +10:00
88692baace WM: gestures now activate immediately on mouse press
Some gestures were activating immediately on tweak events,
extend this to mouse-press and click-drag.

Without this change, box-select for example wouldn't be automatically
activated on mouse-press.
2021-09-23 22:08:02 +10:00
b659d1a560 Cleanup: spelling in comments 2021-09-23 22:08:02 +10:00
d431b91995 Cleanup: assign variable for LMB select 2021-09-23 22:06:47 +10:00
4d2ca33a8a LibLink: Modify WM API to link/append one ID to take flag parameter.
There is no reason to lock behavior into a specific configuration in
those calls, make them properly configurable like the rest of the
link/append code.

This also enable users of those functions to activate 'ID reuse'
behavior.
2021-09-23 13:48:41 +02:00
aadb7ef071 Geometry Nodes: add utility to print an attribute id. 2021-09-23 13:46:26 +02:00
e86cf55667 Fix T91629: Crash in "Open Cached Render" function 2021-09-23 13:03:36 +02:00
f48a4aa0f9 LibLink Append: Expose 'reuse ID' through new BLO flag, and add basic tests.
Option is now available to append operator, alsthough hidden and
disabled by default.
2021-09-23 12:56:05 +02:00
cb173d05dc LibLink Append: Fix 'reused ID' case keeping linked data around.
When we re-use a local ID, we need to delete the matching linked data.
2021-09-23 12:54:23 +02:00
6f53988e7a Cleanup: proper handling of LIB_TAG_DOIT in append code. 2021-09-23 12:46:51 +02:00
ce96a75c2c Cleanup: eBLOLibLinkFlags: Add 'space' between APPEND flags and INSTANCE ones. 2021-09-23 12:45:40 +02:00
3558ae3b6c Cleanup: Silence unused var warning in release builds. 2021-09-23 12:30:07 +02:00
b63f777950 Add missing GPencil IDTYPE_FLAGS_APPEND_IS_REUSABLE flag.
Forgot that one in rB794c2828af60.

Noted by Antonio Vazquez (@antoniov), thanks.
2021-09-23 11:28:39 +02:00
b801e86f8b Append: Reuse local data: remove limitation on directly selected data.
in asset context, when user drag & drop a material several time, they
would still expect to re-use existing one instead of getting new copies
of it, even if this material is directly appended (and not an indirect
dependency of an object e.g.).
2021-09-23 11:15:58 +02:00
3042994c91 Link/Append: Refactor flags.
Flags controlling link/append code are split between two enums, one in
`DNA_space_types.h` and one in `BLO_readfile.h`.

This commit:
 - Moves flags exclusively used in WM and BLO code to `eBLOLibLinkFlags`
   in `BLO_readfile.h`. Flags in `eFileSel_Params_Flag` from
   `DNA_space_types.h` are now only the ones effectively used by the
   file browser editor code too.
 - Fixes some internal utils in `readfile.c` still taking `short` flag
   parameter instead of proper `int` one.

NOTE: there are a few other flags that could probably be moved to
`eBLOLibLinkFlags` (at the very least `FILE_LINK`, probably also
`FILE_AUTOSELECT` and `FILE_ACTIVE_COLLECTION`), since those are not
effectively used by the file browser, and control linking/appending
behavior, not filebrowser behavior.

However for now think it's safer to not touch that.
2021-09-23 11:01:00 +02:00
12924ed573 Fix last Cycles tile highlighted while file from disk is being processed 2021-09-23 10:41:06 +02:00
a351023bd5 Fix default surface resolution U/V mis-match
The resolution for surfaces was 12 for U, 4 for V,
where both should have been set to 4.

Regression in 9a076dd95a
2021-09-23 15:54:32 +10:00
754d56dcc1 Cleanup: spelling in comments 2021-09-23 15:42:44 +10:00
bf948b2cef Custom Properties: Rewrite edit operator, improve UX
This commit changes the custom property edit operator to make editing
different properties types more obvious and expose more of the data,
made more easily possible by the recent UI data refactor.

Previously, the operator guessed the type you wanted based on what you
wrote in a text box. That was problematic, you couldn't make a string
property with a value of `1234`, and you had to know about the Python
syntax for lists in order to create an array property. It was also slow
and error prone; it was too easy to make a typo.

Improvements compared to the old operator:
 - A type drop-down to choose between the property types.
 - Step and precision values are exposed.
 - Buttons that have the correct type based on the property.
 - String properties no longer display min, max, etc. buttons.
 - Generally works in more cases. The old operator tended to break.
 - Choose array length with a slider.
 - Easy to choose to use python evaluation when necessary.
 - Code is commented, split up, and much easier to understand.

The custom property's value is purposefully not exposed, since the Edit
operator is for changing the property's metadata now, rather than the
value itself. Though in the "Python" mode the value is still available.

More improvements are possible in the future, like exposing different
subtypes, and improving the UI of the custom properties panel.

Differential Revision: https://developer.blender.org/D12435
2021-09-22 21:57:33 -05:00
dda9762a16 Remove old TinyGLTF files 2021-09-22 19:38:33 -07:00
fa23369373 Merge branch 'master' into xr-controller-support 2021-09-22 19:24:20 -07:00
1ef02d8f4b Update with changes from D10948, D12472 2021-09-22 19:16:52 -07:00
6e77afe6ec Applying patch D12600, GSOC Knife Tools branch
This adds constrained angle mode improvements,
snapping to global and local orientation,
visible distance and angle measurements,
undo capability,
x-ray mode,
multi-object edit mode.

See https://developer.blender.org/D12600 for more details.

Note: this project moved some of the default keymappings
around a bit, as discussed with users in the thread
https://devtalk.blender.org/t/gsoc-2021-knife-tool-improvements-feedback/19047
We'll change the manual documentation in the next couple of days.
2021-09-22 21:23:44 -04:00
a78d3c5261 Fix: T91602 ffmpeg crash
Issue caused by our patch in rB1af722b81912
we replaced an array with a memory allocation
but we forgot to update the assert which now
used an invalid method to calculate the array
size.

SVN libs will have to be updated before
T91602 will be fixed for end users.
2021-09-22 17:29:23 -06:00
79bcc19240 Cleanup: Move more shader nodes to socket declaration API
I had to add `no_muted_links` to the declaration API. The name could
change there, but I think it's more obvious than "internal"
2021-09-22 17:34:09 -05:00
6fb4c8f040 Fix: Incorrect socket names after previous commit 2021-09-22 16:58:29 -05:00
c99cb81452 Cleanup: Use new node socket declaration API for some shader nodes
This converts socket declarations for most shader nodes that had already
been converted to C++, but skips those that needed a special flag.
2021-09-22 14:39:09 -05:00
bd01f4761c GPencil: Fix compiler warnings 2021-09-22 21:17:04 +02:00
ee49991999 Cleanup: Silence missing switch case warning 2021-09-22 12:00:21 -07:00
6611f2cb74 Fix T91607: GPencil Tint modifier "apply" removes the effect 2021-09-22 20:07:35 +02:00
f893dea586 BLI: support initializing empty FunctionRef with nullptr
This may sometimes be desired because it is more explicitely
shows that the `FunctionRef` will be empty.
2021-09-22 19:55:44 +02:00
02bde2c1d5 Cleanup: add using declarations 2021-09-22 19:45:47 +02:00
a28ec92088 BLI: avoid warning when copying empty StringRef 2021-09-22 19:45:18 +02:00
188de4bc31 BLI: initialize MutableSpan in default constructor 2021-09-22 19:44:58 +02:00
bd1c4a781f Geometry Nodes: fix evaluating field to span 2021-09-22 18:45:11 +02:00
3180c6b4a7 Cleanup: Themes: Remove invalid theme option
`font_kerning_style` was removed in rBa1e91fbef3dc9a5d5c8456cd9a887aac1bdb652c
2021-09-22 12:33:12 -04:00
e1a0983b3c Fix T91608: Cycles crash with tile size 0 2021-09-22 18:12:46 +02:00
4068b6b5a7 Fix T91598: Decreasing sample count causes viewport to reset
Differential Revision: https://developer.blender.org/D12601
2021-09-22 18:09:06 +02:00
Chandrapal Singh
5033310e8a UI: Add description for Batch rename
Added description for Batch rename which pop-ups when
hovering the mouse over "Batch rename" inside the edit menu.

Fixes T91390

Reviewed By: Blendify

Maniphest Tasks: T91390

Differential Revision: https://developer.blender.org/D12594
2021-09-22 11:35:29 -04:00
ac68b08c5b Fix T91592: Negative Cycles remaining render time
For the default startup was showing -14:-08.-48 as a remaining time.

Was an integer overflow when specifying total number of pixel-samples.
2021-09-22 17:30:00 +02:00
bc1e675bb9 Fix T91603: Cycles crash when volume becomes visible
Making object which uses volume shader invisible will mark the shader
as not having a volume, forcing re-compilation of the shader to bring
it back to a consistent state.

The compilation is happening as part of scene update, which needs to
know kernel features. So there is a feedback loop.

Use more relaxed way of knowing whether there is a volume in the
shader for the kernel features, which doesn't require shader to be
compiled first.

Solves issues from the report, but potentially causes extra memory
allocated if the volume part of graph is fully optimized out. This
downside is solvable, but would need to split scene update into two
steps (the one which requires on kernel, and the one which does not).
It will be an interesting project to tackle, but for a bug fix is
better to use simpler solution.
2021-09-22 17:10:06 +02:00
1eba32c3e9 Fix T91576: Cycles attribute node with name N for smooth normal no longer working
There was an optimization to remove duplicate storage of normals as attributes
when using normal maps. However for named attributes like this we still need to
store the attribute.

Don't request normal attribute from the normal map node now, instead of skipping it
in the geometry code.
2021-09-22 17:05:31 +02:00
4762a9b09f GPencil: Fix unreported missing material panel for new Scene
When a new scene is created, the paint pointers are not available before using them, so the python panel exits because the pointer was None.

Now, the pointer is checked in order to display the materials panel as expected.
2021-09-22 17:05:21 +02:00
794c2828af Initial implementation of local ID re-use when appending.
This commit adds to ID struct a new optional 'weak reference' to a
linked ID (in the form of a blend file library path and full ID name).

This can then be used on next append to try to find a matching local ID
instead of re-making the linked data local again.

Ref. T90545

NOTE: ID re-use will be disabled for regular append for the time being
(3.0 release), and only used for assets. Therefore, this commit should
not change anything user-wise.

Differential Revision: https://developer.blender.org/D12545
2021-09-22 16:55:39 +02:00
707bcd5693 Cleanup: make format 2021-09-22 16:55:09 +02:00
dilithjay
0d350e0193 Geometry Nodes: Curve Fillet Node
This node can be used to fillet splines at control points to
create a circular arc.
The implementation roughly follows T89227's design.

The node works in two main modes: Bezier and Poly
* Bezier: Creates a circular arc at vertices by changing
handle lengths (applicable only for Bezier splines).
* Poly: Creates a circular arc by creating vertices (as
many as defined by the Count fields input) along
the arc (applicable for all spline types).

In both modes, the radius of the created arc is defined
by the Radius fields input.
The Limit Radius attribute can be enabled to prevent
overlapping when the defined radius exceeds the maximum
possible radius for a given point.

Reviewed By: Hans Goudey

Differential Revision: https://developer.blender.org/D12115
2021-09-22 20:11:12 +05:30
204b01a254 Fix T91590: Cycles specular baking not using smooth normal 2021-09-22 16:08:45 +02:00
e57ce464c2 Fix T91600: Cycles viewport not updaing on metaball changes 2021-09-22 16:08:45 +02:00
53e7c64be7 Fix T91597: Cycles volume scatter visibility on lights not working 2021-09-22 16:08:45 +02:00
368b56c9a1 GPencil: Split Weight modifier in two to make more consistent
The old modifier had two modes, but it is better to keep separated as meshes.

The UI has changed to be more consistent, including a new column type of modifiers.

Note: The logic has not changed with the previous version of the modifier, just is a split on two modifiers..

Reviewed By: mendio, pablovazquez

Differential Revision: https://developer.blender.org/D12586
2021-09-22 15:54:34 +02:00
9f6313498a Fix missing samples count pass when using tiles
Samples count pass is normalized to the overall number of samples.
This means that we need to store actual value of the samples in the
tile buffer file.

A bit annoying to pull all those settings to BufferParams and need
to find a more generic solution, but for now this is easiest and a
quickest solution.

Differential Revision: https://developer.blender.org/D12597
2021-09-22 15:07:55 +02:00
Christoph Lendenfeld
f7a492d460 Animation: Pose Slide Operator - Blend to Neighbour
Adds a new operator to the pose slider tools that blends the
current pose with the neighbouring poses in the timeline.
The operator can be called in pose mode with Shift+Alt+E
or from the "pose" menu under "In betweens/Blend to Neighbour"

Reviewed by: Sybren A. Stüvel
Differential Revision: https://developer.blender.org/D9137#inline-105214
Ref: D9137
2021-09-22 14:02:19 +01:00
a6f6c421ef Cleanup: pep8 for the default keymap
Mainly line lengths & indentation.
2021-09-22 22:50:16 +10:00
f7f5024c95 Keymap: support use_key_activate_tools for annotate 2021-09-22 22:38:28 +10:00
9add7c35cc Fix (unreported) crash in outliner after recent changes to ID management core code.
Outliner tree building code abuse the `ID.newid` pointer to store non-ID
data. While this is bad and should be fixed at some point, for the time
being at the very least do not use ID BKE API to deal with this pointer
in that specific case, this needs its own proper code.
2021-09-22 14:37:00 +02:00
2526a355bc Fix bad image drawing during rendering on certain GPUs
Reported by Thomas DInges: the default cube render in Cycles has jagged
edges during rendering. Happens on AMD Radeon RX 5500 XT.

Force linear interpolation at zoom level 1 and less.

Reviewed by @fclem
2021-09-22 14:28:56 +02:00
7633548d60 Revert "Make knife drawing anti aliased (Monkey work based on D11333)"
This reverts commit 96027b2d15.

The patch asserts on different occasions and needs more work.
2021-09-22 13:50:05 +02:00
2884ae971a Custom Properties: fix the tooltip field not initialized in edit dialog.
Initializing the description property was completely forgotten.
It also seems it may be missing sometimes, so use `get`.

Also, clean values when there is no data, and correctly use
the return value of `get_value_eval` in one instance.
2021-09-22 13:22:42 +03:00
90b485845c Keymap: set the default filepath exporting keymaps
Use the key-config name for the file name.
2021-09-22 17:47:52 +10:00
ba313f8a74 Fix crash duplicating sequencer area
Error in 997b5fe45d.
2021-09-22 17:37:10 +10:00
719451f840 Cleanup: use template for hide/reveal keymap items 2021-09-22 17:17:04 +10:00
c0f55400eb Keymap: support use_key_activate_tools for selection tools
Also support sequencer transform tools.
2021-09-22 17:17:04 +10:00
c75e6bcea2 Keymap: add fallback keymap for sequencer tools
This quiets error messages, fall-back tool preference needs to be
further developed.
2021-09-22 17:17:04 +10:00
Jeroen Bakker
0c59386110 Blender Libraries: Add JSON Library.
Several areas within blender can benefit a JSON reader/writer library.
Areas like the asset browser, XR and grease pencil.

After looking at the available options we selected nlohmann's JSON for
modern C++ library. It is actively maintained for over 10 years and
flexible.

This patch only adds the header only implementation of the library so it
can be used by different areas. The asset browser project is planning to
add a small abstraction layer so it will be easier to switch between
several different serialization formats. This is currently in
development in D12544.

In cases the abstraction layer can be an overhead and undesired to be used.
In this case the header file can be directly included.

Reviewed By: Severin

Maniphest Tasks: T91430

Differential Revision: https://developer.blender.org/D12567
2021-09-22 09:07:09 +02:00
Jake
4c156cba21 EEVEE fix gloss low roughness error
Up lower clamp on spec_angle to prevent NaN from being generated on intel GPUs at low roughness.

Fixes T88754

Reviewed By: fclem

Maniphest Tasks: T88754

Differential Revision: https://developer.blender.org/D12508
2021-09-22 08:22:23 +02:00
3fa6426392 Extern: Add TinyGLTF to load XR controller model
The XR_MSFT_controller_model OpenXR extension provides a glTF
controller model that can be displayed to users during a VR session.
There are plans to support this in D10948, which will greatly improve
VR immersion when using a compatible OpenXR runtime.

TinyGLTF (https://github.com/syoyo/tinygltf) was agreed upon as a
simple and sufficient solution for loading this glTF controller model,
which will be performed at the GHOST abstraction layer. Although by
default it has two additional dependencies, stb and json, stb can be
excluded by defining TINYGLTF_NO_STB_IMAGE and
TINYGLTF_NO_STB_IMAGE_WRITE whereas json will be added as a separate
extern lib in D12567.

Reviewed By: Severin

Differential Revision: https://developer.blender.org/D12344
2021-09-21 22:59:10 -07:00
4d66cbd140 Cleanup: spelling in comments 2021-09-22 14:54:01 +10:00
77061a5621 Cleanup: incompatible-pointer-types warning 2021-09-22 14:46:32 +10:00
4d881d9dad Geometry Nodes: Curve Parameter Node
This commit adds a field input node that outputs the fraction of the
total length of the spline on each control point. This is useful for
anything that involves varying a value depending on how far along
the spline it is.

It also works when evaluated on the spline domain, where it outputs
the fraction of the total length of all of the splines at the start.

The operation isn't as well defined for NURB splines for the reasons
noted in the code comment. That can be said explicitly in the docs.

Differential Revision: https://developer.blender.org/D12548
2021-09-21 17:38:37 -05:00
41e3bf8a8e Geometry Nodes: Add legacy warning and "View Legacy" operator
This commit adds warning messages to "legacy" nodes that will be
removed in the future. The warning is shown in the node header, but
it is not printed in the terminal or displayed in the modifier. It is
also not propogated to node groups, but that is a more general task.

If the modifier's node tree has executed a deprecated node, it will
display a warning and a "Search" button that will select the nodes and
pan to them in the node editor. This doesn't open child node trees and
select nodes in there, because I want to keep this operator simple and
avoid wasting a lot of time perfecting this behavior.

Differential Revision: https://developer.blender.org/D12454
2021-09-21 17:17:40 -05:00
8324ac8457 Audaspace: porting upstream pulseaudio fixes.
Fixes T89045 and T91057.
2021-09-21 22:20:34 +02:00
af95542df3 UUIDs: rename UUID to bUUID
Rename the `UUID` struct to `bUUID`. This avoids a symbol clash on
Windows, which also defines `UUID`. This only pops up when a `UUID`
field is used in the DNA code, which is why it wasn't a problem before
(it will be once D12589 lands).

No functional changes.
2021-09-21 21:54:53 +02:00
6d162d35e2 Geometry Nodes: Fill instances separately in the curve fill node
With this commit, each referenced instance data will be converted to
a geometry instances and processed separately. This should result in
a large speedup when the instances component has many insances
referring to the same data.

This change can act as a blueprint for other nodes that need to
implement similar behavior. It adds some helper functions on the
instances component to make that easier.

Thanks to Erik Abrahamsson for a proof of concept patch.

Differential Revision: https://developer.blender.org/D12572
2021-09-21 14:20:54 -05:00
Erik Abrahamsson
29e3545194 Geometry Nodes: String manipulation nodes
This patch adds four new nodes to a new "Text" category:
 - String Length: Outputs length of a string
 - String Substring: Outputs part of a string
 - Value to String: Converts a value to a string
 - String Join: Concatenates multiple strings with a delimiter

The initial use case of these nodes is the upcoming string to curve
node. However, they could also be used to calculate dynamic attribute
names, or with string attributes in the future.

Differential Revision: https://developer.blender.org/D12532
2021-09-21 14:11:32 -05:00
05ce5276db Geometry nodes: Output curve normals from the normal node
The code is basically the same as rB4d51af68adb273.
2021-09-21 13:39:46 -05:00
4d51af68ad Geometry Nodes: Curve tangent node
This node outputs the direction vector, or tangent of a curve at every
control point. For poly splines this is simply the evaluated tangents,
so it all works very simply. For Bezier splines it uses the tangent at
the evaluated point corresponding to each control point, and NURBS
are interpereted as poly splines built from their control points.

Internally the node is called "Input Tangent" to simplify using it for
mesh tangents as well in the future like the "Normal" node.

Differential Revision: https://developer.blender.org/D12581
2021-09-21 13:11:39 -05:00
29b13fa3ca Cleanup: Clang-tidy warnings 2021-09-21 20:02:46 +02:00
499dbb626a UI: Style drag-drop indicators as tooltips
Currently, the drop indicator colors are hardcoded to white text on semi-transparent black background.
This patch makes the drop indicator use the tooltip theme settings, as they serve a similar purpose.

{F10530482, size=full}

All built-in themes seem to work well and got improved readability.

Reviewed By: HooglyBoogly

Differential Revision: https://developer.blender.org/D12588
2021-09-21 19:53:42 +02:00
b37d36a60f Fix: Add versioning for geometry nodes attribute input toggle
rB8e21d528cab98 neglected to add versioning to add the new
"use_attribute" and "attribute_name" properties to the modifier input
list. Though they are added if the modifier's interface is updated, that
doesn't happen when the file is loaded, so patch adds them manually.
Another solution would be calling `MOD_nodes_update_interface`,
but that would require including the modifiers module.

Differential Revision: https://developer.blender.org/D12535
2021-09-21 12:42:47 -05:00
3642e17428 Cleanup: Move curve to mesh node implementation to blenkernel
I plan to use this for curve object data conversion to mesh in D12533,
and possibly for the implicit curve to mesh conversion in the curve
and text object modifier stack in the future.

Differential Revision: https://developer.blender.org/D12585
2021-09-21 11:56:54 -05:00
fde9c3bc74 Fix: Incorrect versioning for float IDProperty default array
The versioning has to have different behavior for when the old default
value had a float type rather than a double type. Also use memcpy
rather than dupalloc, since it's a bit clearer.
2021-09-21 11:20:34 -05:00
66dbe6e55a Cleanup: else-after-return 2021-09-21 17:55:39 +02:00
3c1e75a230 Functions: make asserts more correct
It is valid to e.g. copy construct an integer in the same place,
because it is a trivial type. It does not work for types like std::string.

This fixes a crash reported in D12584 where it would copy a buffer
into itself. We should probably also avoid doing this copy alltogether
but that can be done separately.
2021-09-21 17:51:15 +02:00
2df7d1ebce Cleanup: mention UUID_STRING_LEN in comment
Mention that `UUID_STRING_LEN` exists in the documentation of
`BLI_uuid_format()`.

No functional changes.
2021-09-21 17:50:23 +02:00
49ab38bf54 Fix T91534: GPencil interpolate Sequence fails if stroke has 0 points
In some cases the stroke has 0 points and this must be skipped in the interpolation.
2021-09-21 17:29:27 +02:00
Henrik Dick (weasel)
2e6a735385 GPencil: Curvature support for length modifier
Extend the stroke following an approximated circluar/helical curve.

This can be used as an effect for lineart or on its own as helix generator.

Reviewed By: Sebastian Parborg (zeddb), Hans Goudey (HooglyBoogly), YimingWu (NicksBest), Antonio Vazquez (antoniov), Henrik Dick (weasel)

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

# 请为您的变更输入提交说明。以 '#' 开始的行将被忽略,而一个空的提交
# 说明将会终止提交。
#
# 位于分支 master
# 您的分支与上游分支 'origin/master' 一致。
#
# 要提交的变更:
#	修改:     source/blender/blenkernel/BKE_gpencil_geom.h
#	修改:     source/blender/blenkernel/intern/gpencil_geom.cc
#	修改:     source/blender/gpencil_modifiers/intern/MOD_gpencillength.c
#	修改:     source/blender/makesdna/DNA_gpencil_modifier_defaults.h
#	修改:     source/blender/makesdna/DNA_gpencil_modifier_types.h
#	修改:     source/blender/makesrna/intern/rna_gpencil_modifier.c
#
2021-09-21 23:03:21 +08:00
84f98e28e3 Fix T87801: Eevee ambient occlusion is incorrect on M1 macMini
The issue was caused by `textureSize()` returning the size of the level 0
even when the min texture level is higher than 0.

Using a uniform to pass the correct size fixes the issue.

This issue also affected the downsampling of radiance for reflections and
refractions.

This does not affect anything other than the recusive downsampling shaders.
2021-09-21 16:39:17 +02:00
33955231f3 Fix T91458: Displaying dope-sheet with sequencer keyframes crashes
Error in e6194e7357.
2021-09-22 00:06:17 +10:00
a25cd206c6 Cleanup ClangTidy warning.
Different parameter name in function declaration and implementation.
2021-09-21 15:56:05 +02:00
Urko
96027b2d15 Make knife drawing anti aliased (Monkey work based on D11333)
Knife tool.

Make the drawing anti aliased and consistent by using
3D_POLYLINE/3D_POINT shaders, and making sure alpha
blending is on.

Monkey work based on [[ https://developer.blender.org/D11333 | D11333 ]]
done by  [[ https://developer.blender.org/p/krash/ | Anthony Edlin (krash)]]

Reviewed By: jbakker

Differential Revision: https://developer.blender.org/D12287
2021-09-21 15:40:09 +02:00
0803119725 Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.

Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.

Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles

Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)

For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.

Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-21 14:55:54 +02:00
fa6b1007ba Fix script_load_keymap failure from c9d9bfa84a
Scanning the keymap hierarchy (used in the preferences),
caused the test to fail.

Don't attempt add fallback keymaps for dynamic keymap callbacks.
2021-09-21 22:19:40 +10:00
69928307c5 Cleanup: Silence unused variable warning 2021-09-21 14:18:31 +02:00
Aditya Y Jeppu
997b5fe45d VSE strip thumbnails
Draw thumbnails as strip overlay. This works for movie and image strips.
To draw thumbnails, this overlay has to be enabled and strips must be
tall enough.

The thumbnails are loaded from source file using separate thread and
stored in cache.

Drawing code uses only images stored in cache, and if any is missing,
background rendering job is started. If job can not render thumbnail,
to prevent endless loop of creating job for missing image it sets
`SEQ_FLAG_SKIP_THUMBNAILS` bit of `Sequence` flag.

To prevent visual glitches during timeline panning and zooming, `View2D`
flag `V2D_IS_NAVIGATING` is implemented. If bit is set, drawing code
will look for set of evenly distributed thumbnails that should be
guaranteed to exist and also set of previously displayed thumbnails.
Due to volatile nature of cache these thumbnails can be missing anyway,
in which case no new thumbnails will be drawn for particular strip.

Cache capacity is limited to 5000 thumbnails and performs cleanup of
non visible images when limit is reached.

ref T89143

Reviewed By: ISS

Differential Revision: https://developer.blender.org/D12266
2021-09-21 10:55:04 +02:00
fa2c1698b0 VSE: Image transform tools
Add tools for image manipulation in sequencer preview region.

This includes:
- Translate, rotate and resize operators, tools and gizmos
- Origin for image transformation
- Median point and individual origins pivot modes
- Select and Box select operator works in preview
- Image overlay drawing

ref T90156

Reviewed By: campbellbarton

Differential Revision: https://developer.blender.org/D12105
2021-09-21 10:55:04 +02:00
26f9b1ef49 LibOverride: make view_layer API parameter optional.
This is used to find a valid collection in which to instantiate stray
objects and collections.

In some cases there will be no such active view layer, in which case we
can consider using the Scene's master collections children hierarchy
instead to find a valid instantiated parent collection for those stray
data.
2021-09-21 10:43:34 +02:00
f5c6029cc5 Keymap: preference for keys to set the active tool
With "Keys Activate Tools" preference enabled, keys such as G/R/S
activate the move/rotate/scale tool instead of the modal operator.

Addresses T83692.
2021-09-21 18:24:12 +10:00
8b8a678cdf Keymap: preference for Alt-LMB to use the active tool
With the LMB select key-map some tools required clicking on a gizmo.
With this preference it's possible to hold Alt and click anywhere.

Addresses T83689.
2021-09-21 18:24:07 +10:00
c9d9bfa84a Keymap: preference for fallback-tool with RMB select
Expose a key-map preference "Fallback Tool (RMB)",
disabled by default.

The right mouse button uses the fallback tool
(currently visible selection tool in the toolbar),
instead of always tweaking.

When any selection tool is active, right mouse always tweaks.

To enable fallback selection on RMB, set the "Right Mouse Select Action"
to "Selection Tool".

Internal changes:

- Add fall-back key-maps, separate key-maps needed for when the tool is
  run as a fall-back. This is needed so RMB-select can support fall-back
  tools, so left-mouse can be used when it's the active tool and RMB
  can be used as a fall-back action when another tool is active.
- Add options field to tools so tools without gizmos can enable the
  full-back tool keymap.
- Support multiple key-maps for keymap handlers.
- Fall-back keymaps now co-exist with the tool-keymaps.
  So both keymaps may be active at once - using different mouse buttons.
  When gizmos are in use, a highlighted gizmo prioritizes the
  tool-keymap over the fall-back keymap.

Resolves T83690.

Reviewed By: JulienKaspar

Ref D12493
2021-09-21 18:14:11 +10:00
52bfa750e7 WM: only return PASS_THROUGH on PRESS for selection operators
Some selection operators return (PASS_THROUGH & FINISHED) so the tweak
event isn't suppressed from the PRESS event having been handled.

This is now restricted to events with a PRESS action.
Without this, using CLICK for selection was passing the event through
which could run other actions unintentionally.
2021-09-21 17:26:21 +10:00
5eb505e368 Cleanup: Remove debugging change, add comments 2021-09-20 20:37:49 -05:00
17021adcea Geometry Nodes: Curve Sample Node
This node allows sampling positions, tangents, and normals at any
arbitrary point along a curve. The curve can include multiple splines,
all are taken into account. The node does not yet support transferring
generic attributes like radius, because some more general tooling will
make that much more feasible and useful in different scenarios.

This is a field node, so it is evaluated in the context of a data-flow
node like "Set Position". One nice thing about that is it can easily
be used to move an entire geometry like the follow path constraint.

The point along the curve is chosen either with a factor of the total
length of the curve, or a length into the curve, the same choice used
in the curve trim node.

Differential Revision: https://developer.blender.org/D12565
2021-09-20 20:23:26 -05:00
9e939a614e Functions: Fix incorrect assert for unused output
Since the variable for an output parameter can be null,
it is incorrect to use it later on in a reference.
2021-09-20 20:22:52 -05:00
4472a11017 Fix: Crash with single point bezier spline auto handles
There's no way to calculate auto or vector handles when there is
only one point, and returning early allows avoiding checking for
that case later on.
2021-09-20 20:20:39 -05:00
Victor-Louis De Gusseme
05f3f11d55 Geometry Nodes: Attribute Statistic Node
This nodes evaluates a field on a geometry and outputs various
statistics about the entire data set, like min, max, or even
the standard deviation. It works for float and vector types currently,
though more types could be supported in the future.

 - All statistics are calculated element-wise for vectors.
 - "Product" was not added since the result could very easily overflow.
 - The "Size" output was not added since it isn't specific to an
   attribute and would fit better in another node.

The implementation shares work as much as possible when multiple
statistics are needed.

This node has been in development since the beginning of this year,
with additions from Johnny Matthews and Hans Goudey.

Differential Revision: https://developer.blender.org/D10202
2021-09-20 18:39:39 -05:00
13a4bccdb1 Asset Browser: Redraw sidebars on mode switches
There may be mode specific panels for some assets in the navigation or
the asset metadata sidebar. For example the pose library will likely do
this. So let the regions redraw on mode changes.
2021-09-20 22:10:03 +02:00
15471d9bed Update RNA to user manual url mappings 2021-09-20 13:40:31 -04:00
e43ecca016 Tests: measure time per frame in animation performance benchmark
Instead of a fixed number of frames, so that benchmarking takes about the
same time on any machine.
2021-09-20 19:03:22 +02:00
3b8d702a2f Geometry Nodes: use implicit position input in noise node
This is the same behavior as in shader nodes.
2021-09-20 19:01:08 +02:00
32a4c7f188 Geometry Nodes: implicit position input in Set Position node
This change makes the Set Position node do nothing by default.
Before, the geometry would always disappear, because it all points
would be moved to (0, 0, 0).

Differential Revision: https://developer.blender.org/D12553
2021-09-20 18:56:30 +02:00
a79c33e8f8 UI: Change "Favorites" to "Bookmarks"
Change of File Browser "Favorites" section header in source list
(T panel) to "Bookmarks" to maintain consistency with all the other
bookmark-related text and operations.

See D10262 for more information and alternatives considered.

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

Reviewed by Julian Eisel
2021-09-20 07:42:17 -07:00
7cb65e4581 Cleanup: Refactor VSE overlay settings
Move overlay flags into SequencerPreviewOverlay and
SequencerTimelineOverlay structs.

Reviewed By: campbellbarton

Differential Revision: https://developer.blender.org/D12569
2021-09-20 16:30:15 +02:00
9642447faf GPencil: Fix error in previous commit
By error I commited the previous version.
2021-09-20 15:37:54 +02:00
c5c189a158 GPencil: Change Rotation tooltip
The tooltip was not clear about in what shading modes  works.

Related to T91467
2021-09-20 15:32:27 +02:00
eaad219ee7 Cleanup: spelling (correct c5c8c68eec)
"iff" was intended as "if and only if". while exact use of abbreviations
isn't clear cut, I assumed this was a typo & it's not used anywhere
else in source/, expand to "only if" (suggested by Sybren).
2021-09-20 22:31:13 +10:00
da4796ebf7 Build: change make update to not print errors regarding submodule branches
Instead of trying to checkout non-existent branches and getting confusing fatal
error prints, check if the branch exists first.

Ref D12560
2021-09-20 14:05:56 +02:00
fc4f82d200 Geometry Nodes: support Noise Texture node
This makes the Noise Texture node available in geometry nodes.
It should behave the same as in shader node, with the exception
that it does not have an implicit position input yet. That will
be added separately.

Differential Revision: https://developer.blender.org/D12467
2021-09-20 13:12:25 +02:00
8c7c4549d1 Geometry Nodes: support Set Position node on instances
Previously, the node would always realize instances implicitly.
Now it can change the position of entire instances.
The Realize Instances node can be used before if the old
behavior is required.

Differential Revision: https://developer.blender.org/D12555
2021-09-20 12:49:28 +02:00
11e11c41f2 make_update: Fix case where a sub-module would not have required branch.
Issue revealed by rB546314fc9669 change, also error itself exited before
that commit.

Now we do accept git command to fail when trying to checkout the
specified branch from sub-modules, and only actually error in case the
fall-back branch (aka master) cannot be properly checked out.

Thanks fot Ray molenkamp (@LazyDodo) for report and initial patch
(D12560).
2021-09-20 12:44:01 +02:00
7da9da2b27 Geometry Nodes: new Realize Instances node
This node has a simple geometry input and output.
If the input geometry contains instances, they will be realized
into actual geometry. When there are many instances, this can
be very slow and memory intensive. Generally, instances should
only be made real when necessary, e.g. when every instance
should be deformed independently.

Differential Revision: https://developer.blender.org/D12556
2021-09-20 12:37:52 +02:00
029d042e85 UUID: add nil value for UUIDs
Add `BLI_uuid_nil()` that returns the nil UUID (used to indicate "not
set") and `BLI_uuid_is_nil(uuid)` to do an equality test with the nil
value.
2021-09-20 12:15:37 +02:00
07b482c2ff UUID: fix seeding the RNG clock on macOS
On Apple machines, call `clock_gettime()` instead of `timespec_get()`.

macOS only introduced `timespec_get()` in version 10.15 (introduced
approx two years ago, so in 2019), even though the function is from C11.
2021-09-20 12:10:25 +02:00
1e3c5fdb85 Cleanup: UUID, prevent "missing braces" warning on macOS
Add braces around initialization of sub-objects, as per the warning
suggestion on macOS.

No functional changes.
2021-09-20 12:10:25 +02:00
4eba920d15 UUID: include 'seconds' field of current time in RNG seed
XOR the 'seconds' and 'nanoseconds' fields of the current time to seed the
RNG used for generating random UUIDs. This ensures a better seed just in
case the clock as no sub-second resolution.
2021-09-20 12:10:25 +02:00
1f51672d71 Fix T91511: GPencil weight_get and Vertex Groups not working at expected
The API was checking the number of total weights with the first point of the stroke and this was not valid because each point can have different number of weight elemnts,
2021-09-20 11:10:39 +02:00
738f1dbeff UI: rename "Save Screenshot (Area => Editor)"
The term "area" isn't normally exposed in the UI.
2021-09-20 19:03:07 +10:00
c5c8c68eec Cleanup: spelling 2021-09-20 16:44:28 +10:00
c773443845 Fix: Incorrect default values for the curve trim node
The default end factor should be 1. The proper value for the default end
length is somewhat arbitrary, but it shouldn't be zero.
2021-09-19 22:08:11 -05:00
f973e0b75a Fix: Spline length calculation fails with no evaluated points
The case that checked whether there were evaluated edges was incorrect,
since two points are needed for an edge. Then also avoid running the
accumulation for an empty span.
2021-09-19 19:01:24 -05:00
c9e835fec1 Fix build error after previous commit
Incorrect renaming and use of enum after search and replace.
2021-09-19 18:59:01 -05:00
25aa943e8c Cleanup: Fix/improve variable names and comments 2021-09-19 18:54:03 -05:00
276eebb274 Compositor: Add OIDN prefiltering option to Denoise node
It's equivalent to the OpenImageDenoise prefiltering option in Cycles.
See D12043.

Prefilter modes:
- None: No prefiltering, use when guiding passes are noise-free.
- Fast: Denoise image and guiding passes together. Improves quality when
guiding passes are noisy using least amount of extra processing time.
- Accurate: Prefilter noisy guiding passes before denoising image.
Improves quality when guiding passes are noisy using extra
processing time.

Reviewed By: #compositing, jbakker, sergey

Differential Revision: https://developer.blender.org/D12342
2021-09-19 21:13:51 +02:00
f256bfb3e2 Compositor: Fix crash exporting buffers on debug
ImBuf allocates 4 channels, use copying to support buffers
with 1 and 3 channels.
2021-09-19 21:13:45 +02:00
942c471ce9 Compositor: Fix Alpha Over node ignoring emissive colors
It was an issue on Full Frame mode only.
2021-09-19 21:13:40 +02:00
257c7753e9 Cleanup: Rename curve node enums
The enum called "interpolate" was really a choice of methods for mapping
inputs to positions on the curve, whereas the "sample" enum was used to
define a way to create a whole set of new points from the curve, without
any input parameters. The "re-sample" vs. "sample" naming makes that
distinction better.
2021-09-19 01:20:06 -05:00
69697fcca9 Revert "GPencil: Curvature support for length modifier."
Reason for revert: accidental push of a intermediate change locally.

This reverts commit 25e548c96b.
2021-09-19 13:19:32 +08:00
25e548c96b GPencil: Curvature support for length modifier. 2021-09-19 13:01:24 +08:00
bdbc7e12a0 Audaspace: added audio file streams functionality.
On the blender side this commit fixes importing video files with audio
and video streams that do not share the same start time and duration.

Differential Revision: https://developer.blender.org/D12353
2021-09-18 21:45:33 +02:00
970c928f27 Py API Docs: Fix audio docs example
After new AUD API changes from 2.8x what "buffer" function used to do
has now become "cache" function (it caches a sound into RAM). Therefore,
the basic aud example should call this new "cache" function instead of
"buffer" function.

Thanks to Michael-Z-Freeman for pointing out.
2021-09-18 19:28:55 +02:00
2618df7d03 Cleanup: add missing includes 2021-09-18 13:36:20 +02:00
136e357d8d Cleanup: typo 2021-09-18 13:35:05 +02:00
a229a9dd64 Fix T91461: Pose Library name filter not working
since `AssetHandle` does not have a `name_property`
(`RNA_def_struct_name_property`), and the UIList is just using the
default `uilist_filter_items_default` it simply cannot filter on names
(`RNA_struct_name_get_alloc` wont succeed).

Adding a name_property also wont work since `AssetHandle` inherits
`PropertyGroup` (which already sets name_property).

So this adds a (temporary) hack exception for RNA_AssetHandle in
uilist_filter_items_default until the design of `AssetHandle` progresses
further.

thx @Severin for additional feedback

Maniphest Tasks: T91461

Differential Revision: https://developer.blender.org/D12541
2021-09-18 08:13:24 +02:00
6cf734a2e5 UI: Always Create Asset Previews
This patch allows Asset Browser previews to be made regardless
of the setting of the (unrelated) "File Preview Type" Preference.

See D12484 for more details.

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

Reviewed by Julian Eisel
2021-09-17 08:08:56 -07:00
6b0aa7ae15 Geometry Nodes: hide Attribute Remove node when fields are enabled 2021-09-17 16:21:20 +02:00
9566e3bc9c Fix (harmless) mistake in recent new Append code.
This code path is not yet used so no harm, but that was a fairly nasty
potential crash-generator.
2021-09-17 16:20:39 +02:00
8ee7f62a63 Cleanup: clang-tidy warnings in UUID code
Use C++ version of C headers, and avoid static function call on instance.

No functional changes.
2021-09-17 14:51:43 +02:00
365443412c Cleanup: fix memory leak 2021-09-17 13:31:17 +02:00
Henrik Dick
9a41b44197 Fix T91481: Grease Pencil Layer Double Transformations
Use the inverse of the grease pencil object. This patch fixes the issue for bones and objects.

Maniphest Tasks: T91481

Differential Revision: https://developer.blender.org/D12539
2021-09-17 13:29:48 +02:00
e1d7ce005f Blenlib: introduce a UUID type
Add `BLI_uuid` and `DNA_uuid_types.h` with a UUID implementation
following RFC4122 (https://datatracker.ietf.org/doc/html/rfc4122.html).

The following features are implemented:
- A struct of 128 bits that can be used in DNA definitions.
- Generation of version 4 UUIDs, that is, purely random ones.
- UUID equality function.
- String to UUID and UUID to string conversion functions that are
  compatible with RFC4122.
- C++ stream operator that outputs the UUID as string.

This UUID will be used by the asset system, to uniquely identify asset
catalogs.

Reviewed By: Severin, jacqueslucke

Differential Revision: https://developer.blender.org/D12475
2021-09-17 12:22:00 +02:00
1cd20b0026 Fix T91448: GPencil Fill simplify not working in render
The simplify was hardcode to be disabled in render.
2021-09-17 11:01:01 +02:00
9dee0a10c8 Fix T85564: FCurve modifier zero influence on restrict range borders
When using FModifier `Restrict Frame Range`, the resulting influence was
zero being exactly on `Start` / `End` range borders (so borders were
**exclusive**).
This made it impossible to chain FModifers together (forcing the user to
specify values slightly below the desired border in following
FModifiers).
This is now corrected to be **inclusive** on Start / End range borders.

Before
{F10234864}
After
{F10234865}
Testfile
{F10234866}

In the case of touching open borders (so [frame A frame B] followed by
[frame B frame C]) both modifiers are evaluated (in stack order).
If the later modifier has full influence (and is not additive) this simply
means the result is the same as the later modifier's value.
If influences below 1 are used (or modifiers are additive) both modifier's
values are interpolated/added accordingly.

technical notes:
- this was caused by the introduction of FModifier Influence/BlendIn-Out
in rB185663b52b61.
- for comparison, see other occurrences of
`FMODIFIER_FLAG_RANGERESTRICT`.
- the following conditions in `eval_fmodifier_influence` for blend in/
out have been changed accordingly.

Maniphest Tasks: T85564

Differential Revision: https://developer.blender.org/D10401
2021-09-17 09:13:24 +02:00
06ac655b8d WM: expose the "any" state of KeyMapItem modifiers
Change KeyMapItem.alt/ctrl/shift/oskey to integer types,
where -1 is used to ignore the modifier when matching key-map items.

It was only possible to set all modifiers to -1 at once from RNA
using the 'any' property.
Afterwards individual modifiers could be set back to true/false.
Although these key-map items could not be exported/imported.

Exposing the values directly avoids the need for cumbersome workarounds.
2021-09-17 16:52:33 +10:00
6dca61b91c Cleanup: remove KM_MOD_SECOND & KM_SHIFT2, KM_CTRL2.. etc
These were added in a1c8543f2a (2007)
but never used.
Nor did they have any meaning in practice.

Note that versioning keymap items isn't needed as these values were
never set. The code-paths that set these values also set KM_MOD_FIRST
causing `keymap_event_set` to only ever assign values of 0 or 1.

These flags complicate further exposing KM_ANY (-1)
which is also a valid value for modifiers.
2021-09-17 13:20:50 +10:00
8bc27c508a UI: expose "Lasso Select" & "Extrude to Cursor" in menus
- Show "Lasso Select" in menus (along with Box & Circle select)
- Show "Extrude to Cursor" (along with other extrude actions).
- Rename operators that add/extrude on Ctrl-Click
  since their names were inconsistent.

This is mainly for discoverability.
2021-09-17 12:57:28 +10:00
f8b51f702c UI: enable the depend-on-cursor flag for some operators
- Bend (Transform).
- Extrude to Cursor.
- Lasso Select (related operators such as node-cut links, mask.. etc).
- Rip Mesh / UV's.
- Vertex/Edge Slide.
2021-09-17 12:57:28 +10:00
180bafe225 UI: split screenshot area into a separate operator
While the screenshot operator showed an "Area" option,
it wasn't usable from the main menu (unless accessed via menu search).

Split screenshot area into an operator that depends on cursor.
2021-09-17 12:57:28 +10:00
da2ba40268 UI: wait for input for operators that depend on cursor location
Support waiting for input so operators that depend on the
cursor location are usable from menus / buttons.

Use an operator type flag which the user interface code checks for,
waiting for input when run from a menu item.

This patch only supports this feature, there are no functional changes.

The motivation for this change is discoverability since some actions
were either hidden or broken when accessed from menus
(where the behavior of the operator depended on the menu location).

In general, waiting for input is *not* an efficient way to access tools,
however there are over 50 operators with a "wait_for_input" property
so this isn't introducing a new kind of interaction,
rather exposing this in a way that does not need to be hard-coded into
each operator, or having modal callbacks added for the sole purpose
of waiting for input.

Besides requiring boiler plate code using a "wait_for_input" property
has the added down-side of preventing key shortcuts from showing.
Only the menu items will enable the property,
causing them not to match key-map items.

Reviewed By: Severin

Ref D12255
2021-09-17 12:57:28 +10:00
633c29fb7b Fix: Nodes modifier ignores input value with new property missing
An issue with the previous commit-- the default value of the type was
used instead of the property value when the "use_attribute" property
was missing.
2021-09-16 21:54:14 -05:00
8e21d528ca Geometry Nodes: Add a toggle to use attributes as input values
This adds a toggle to node group inputs exposed in the modifier to use
an attribute instead of a single value. When the toggle is pressed, the
button switches to a text button to choose an attribute name. Attribute
search isn't implemented here yet.

One confusing thing is that some values can't be driven by attributes
at all, like the size of a primitive node. In that case, we should have
a node warning, but that will be separate since it's more general.
We can also have an option to turn off this toggle in node group
input settings.

The two new properties for each input are stored with the same name
as the value, but with `"_use_attribute"` and `"_attribute_name"``
suffixes. The properties are not added for socket types that don't
support attribute input, like object sockets.

Differential Revision: https://developer.blender.org/D12504
2021-09-16 20:49:10 -05:00
4fa0bbb5ac UI: Automatic Blend Thumbnail Selection
Adds an "Auto" option to blend thumbnail types that will automatically
use Screenshot if there is no camera and 3dview, or workbench render
with shading settings from the largest 3dview.

See D12407 for more details.

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

Reviewed by Campbell Barton
2021-09-16 17:40:19 -07:00
a1c65748c4 Cleanup: Pass const mesh argument
Also remove unnecessary parantheses.
2021-09-16 18:23:53 -05:00
8e2e44b58b Cleanup: Move mesh_convert.c to C++
This should allow easier changes when it's helpful to use C++ types.
The diff is for a test on the buildbot.

Differential Revision: https://developer.blender.org/D12528
2021-09-16 15:44:43 -05:00
7a9cfd08a8 UI: Remove Menus & Show Wait Cursor When Saving
When saving blend files close any menus that might be open, show
"waiting" mouse cursor right away, before creating preview.

See D12507 for more details.

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

Reviewed by Campbell Barton
2021-09-16 13:13:15 -07:00
db7fca3588 Cleanup: Remove unnecessary manual of move constructor
Turns out this isn't actually necessary.
2021-09-16 12:32:40 -05:00
f81bacd6f0 Geometry Nodes: Transfer attributes in the curve to mesh node
This patch allows point and spline attributes to be transferred to the
mesh generated by the curve to mesh node. All dynamic named and
anonymous attributes are transferred. So a user-created attribute will
be transferred, but "radius", "tilt" or the handle position attributes
won't be transferred by default and will need to be copied first.
This trade-off is made for performance, since most of the time, users
won't need these attributes copied.

Generally, attributes are transferred to the point/vertex domain.
However, if they have the same name as a built-in mesh attribute that
only exists on a different domain, like "shade_smooth", then they can
be transferred directly to that domain as well. Conversion directly to
the face corner domain is not necessary because there are no builtin
face corner attributes. I see this conversion directly to other domains
as an optimization we could use behind the scenes in the future as well,
when named attributes are less common.

For performance, I haven't tested which of the following is better:
```
for each spline combination:
    for each attribute:

for each attribute:
    for each spline combination:
```
For now I used the existing loop to avoid more threading overhead.

Differential Revision: https://developer.blender.org/D12363
2021-09-16 12:25:26 -05:00
ddb7cb7e4a Geometry Nodes: Simplify using OutputAttribute in a vector
Store the optional temporary span storage as a unique_ptr and move
it in the move constructor, to avoid the need to add a special move
constructor that clears the "show_warning" fields from it. Maybe this
is very slightly slower, but we'll need this class less often in the future
anyway.
2021-09-16 12:03:32 -05:00
31a0708cb1 Cleanup: Add built-in check for an attribute ID 2021-09-16 11:56:31 -05:00
58043c0637 Rename App Menu to Blender Menu
"App" is a name reserved for the application templates at the moment.
It may become its own term in the near future if Templates are separated
from "Apps".

So since this is a name not exposed to the users we should renamed it
sooner than later.

Note that this will require scripts to update since the name of the
class is renamed here.

This also requires an update in the User Manual.

Differential Revision: https://developer.blender.org/D12523
2021-09-16 18:48:59 +02:00
c9daab7936 Assets: Recursive reading of asset libraries
With this, asset libraries can be directory structures and all assets in
sub-directories will show up in an Asset Browser.

With complex directory structures and many .blend files inside, asset
library reading will be quite slow for now. There's initial work being
done to introduce indexing for this (T82979), other optimizations are
being discussed as well.

Addresses T91406.

Differential Revision: https://developer.blender.org/D12139
2021-09-16 16:41:31 +02:00
73ed076489 Hide empty keymap warnings when running a template 2021-09-16 16:11:41 +02:00
867e6ffe88 App Settings: Edge Resize
This prevents both editor resize as well as regions (e.g., the toolbar).

Note: This option is not visible in the UI.

Differential Revision: D12516
2021-09-16 16:02:33 +02:00
f2cfad77f9 App Settings: Regions Visbility Toggle
The toggle that allow users to "show" the region (header, toolbar, ...)
when it is collapsed can now be configured for the apps.

Note: This option is not visibile in the UI.

Differential Revision: D12516
2021-09-16 16:02:33 +02:00
9fee59a484 Rename show_layout_ui > show_corner_split and remove from UI
This breaks API compatibility. However we are now grouping this setting
in the proper section (preferences.apps), so scripts had to update anyways.

So they may as well do it for the final name.

The reason to remove from the UI is that this is intended for app setup,
and as such it should not be exposed to final users until we have apps
better presented (for 3.1 hopefully).

Differential Revision: D12516
2021-09-16 16:02:33 +02:00
c938d9a0e5 Cleanup: Rename USER_APP_LOCK_UI_LAYOUT
There will be other settings that lock other aspects of the
UI layout (e.g., resizing of editors). So better to name
this setting what it actually handles (the corners).

New name: USER_APP_LOCK_CORNER_SPLIT

Differential Revision: D12516
2021-09-16 16:02:33 +02:00
08aa0eb15d Cleanup: WM append code: de-duplicate post-make-local process a bit. 2021-09-16 15:31:03 +02:00
e97653ccf3 Fix: properly implement the 'only append' execption case for WorkSpaces.
Add needed extra flag and utils to IDType to mark and check an ID type
as only appendable.

Note that this is only a loose user-level enforcement currently, in any
case you need to be able to link an ID to append it currently, so for
low-level code this does not really matter.

Currently only WorkSpace and Screen ID types are marked with the new
`IDTYPE_FLAGS_ONLY_APPEND` flag.
2021-09-16 14:30:56 +02:00
3deb56424f Cleanup/Fix outliner 'make local' code.
While likely harmless, this code was doing extremely bad thing,
by-passing the whole lower-level `BKE_lib_id_make_local` call in case it
would fail and deciding by itself to forcefully make the given ID local.
Bad. Very, very, very bad.
2021-09-16 14:30:56 +02:00
e04a10adab Cleanup: no need to clear new flags and pointers from whole Main when making a single ID local. 2021-09-16 14:30:56 +02:00
27b6636c45 Cleanup: Comment about shpaekey being treated as embedded IDs in BKE_id_newptr_and_tag_clear. 2021-09-16 14:30:56 +02:00
4ec2bdbbda Cleanup: Add comment about 'make_local' callback of Brush doing bad thing.
Callbacks in IDTypeInfo should never affect other IDs if they are not
embedded.

We break this rule in some cases, at least each of those should be
clearly commented about and get some security checks to try to avoid
unexpected issues as much as possible.
2021-09-16 14:30:56 +02:00
1d5cc52ef6 Cleanup: Rename BKE_id_clear_newpoin to BKE_id_newptr_and_tag_clear. 2021-09-16 14:30:56 +02:00
1fce66190a Fix/refactor BKE_id_clear_newpoin and BKE_main_id_newptr_and_tag_clear.
Those were not clearing embdeed IDs flags and `newid` pointers at all...
2021-09-16 14:30:56 +02:00
236a9f0814 IDManagement: refactor: Remove 'test' part from BKE_lib_id_make_local.
Mixing testing and actual action in a single function is just not a good
way to do things, and the 'testing' feature is not used anywhere
anymore, time to get rid of it.
2021-09-16 14:30:56 +02:00
4f38624bf5 IDType: Add BKE_idtype_idcode_is_localizable.
This is the same as `BKE_idtype_idcode_is_linkable` currently, used only
in one place in UI code of IDtemplate.
2021-09-16 14:30:55 +02:00
95c2f0bea8 IDType: Cleanup: Remove useless IDTYPE_FLAGS_NO_MAKELOCAL.
This flag became a full duplicate of `IDTYPE_FLAGS_NO_LIBLINKING`, which
is a good thing (don't think we ever want to be able to link some data,
without being able to make it local...).

So we can now remove it and use `IDTYPE_FLAGS_NO_LIBLINKING` instead.
2021-09-16 14:30:55 +02:00
bfe8f29baf Fix ID-property UI versioning skipping nested meta-strips 2021-09-16 21:48:56 +10:00
860a55d8fc Fix security popup re-displaying after undo
Don't reset these flags when loading a file (or undoing)
rely on BPY_python_reset to reset the flags.
2021-09-16 16:56:38 +10:00
0e329a967e Fix memory leak if an error occurred assigning id-property sequence 2021-09-16 16:39:42 +10:00
0530b67909 Fix bisect gizmo offset while dragging 2021-09-16 16:36:53 +10:00
289f68588a GPencil: Fix dash modifier reading error.
The reference for parent modifier in segment data is not assigned. Now fixed.
2021-09-16 08:42:39 +08:00
28bd74c186 Cleanup: Use function to mark mesh normals dirty 2021-09-15 14:44:56 -05:00
8c5d9fa929 Cleanup: Remove duplicate warning from subdivision surface node 2021-09-15 14:19:08 -05:00
525def99bc Geometry Nodes: Hide values for selection inputs
Toggling the selection off in the node is the same as muting it,
so exposing it there doesn't help, and makes it less clear that it's
meant to be used as a field.
2021-09-15 14:16:16 -05:00
acb8909021 Fix: Division by zero in curve spiral primitive node 2021-09-15 14:12:48 -05:00
Johnny Matthews
231948f33f Splines: Add a method for reversing a Spline
This moved the spline reversing logic out of the Curve Reverse geometry
node and into the spline class. This allows a spline to reverse itself
with a call to `my_spline.reverse()`

The base class will reverse position, radii & tilt, while specialized
versions are created for Bezier and Nurbs splines to reverse the
additional data that these classes encapsulate.

Differential Revision: https://developer.blender.org/D12501
2021-09-15 13:57:01 -05:00
a866a32ff2 Tests: Updated test message for Directory Not Found 2021-09-15 23:04:47 +05:30
4a009b54bc Fix broken WorkSpace use after recent refactor of append code.
Essentially, Workspace (and Screen) types were defined as not
localizable.

In previous code it happended to work by mere chance (code path taken in
`BKE_library_make_local` was conviniently skipping the call to
`BKE_lib_id_make_local` in that case, hence not checking for
`IDTYPE_FLAGS_NO_MAKELOCAL` flag of the localized ID type).

This is a total abuse of this IDType flag, for now removing it.

That specific case (IDtype appendable but nor linkable) requires its own
proper flag, this will be tackled in a later commit.

Issue introduced in rB3be5ce4aad5e.
2021-09-15 19:06:36 +02:00
51f7d24a4e Fix missing passes result when rendering multiple views
Caused by the lazily pass pixels allocation which didn't reset
allocation state of the render result.

Demo file: XXX
2021-09-15 18:53:57 +02:00
b6d890672c Fix crash in 'drag asset' case in new append code from yesterday.
Scene and related pointer parameter can be NULL in link/append code, in
which case there is no instantiation of new objects/collections/obdata.

Link code in blendloader was already checking that, new instantiation
code in WM area from yesterday did not.

Issue introduced by rB3be5ce4aad5e.
2021-09-15 18:47:37 +02:00
Johnny Matthews
a6adb7ecae BLI: Add a reverse method to MutableSpan
Add a method that allows a MutableSpan to reverse itself. This reverses
the data in the original span object. This is a first step in extracting
some functionality from nodes and making it more general.

Differential Revision: https://developer.blender.org/D12485
2021-09-15 11:13:10 -05:00
09f14b38f2 Geometry Nodes: Add fields version of material nodes
This commit moves the old material nodes to a "legacy" folder and adds
versions of the nodes that work with fields.

The "Select by Material" node is a field node now, so it doesn't have
a geometry output. This is an improvement because there are fewer links
to connect, and it's more easily usable in different situations.
It's also called "Material Selection", since it's more of an input
than an action now.

It's sometimes necessary to use the attribute capture node to get a
more predictable interpolation to mesh faces. This is because the
selection field input is always evaluated on the face domain, so
attribute inputs are interpolated before they are booleans, so they
cannot use the new interpolations from rB5841f8656d9580d7b9.

Differential Revision: https://developer.blender.org/D12456
2021-09-15 10:51:52 -05:00
5841f8656d Geometry Nodes: Add special domain interpolation for selections
The generic domain interpolation algorithms didn't quite work for
selections. The interpolation would do unexpected things that
were different than the results in edit mode. The new behavior
is supposed to be the same as edit mode, although we also have
to handle face corner selections here.

Currently the code assumes that all boolean attributes should be
handled that way. I'm not sure of why that wouldn't be the case,
but if we ever need non-selection boolean attributes, that could
be supported too.

Differential Revision: https://developer.blender.org/D12488
2021-09-15 10:28:00 -05:00
e456a9de57 Cleanup: avoid passing redundant parameter 2021-09-15 16:35:33 +02:00
46fff97604 Nodes: refactor socket declarations
This commits adds a few common flags to `SocketDeclaration`
so that they are available for all socket types (hide label, hide
value, is multi input). This allows porting over the remaining
geometry nodes to the new declaration system.

Furthermore, this commit separates the concepts of the socket
declaration and corresponding builders. The builders are used
by nodes to declare which sockets they have (e.g. `FloatBuilder`).
The ready build socket declarations can then be consumed by
other systems such as the versioning code. Both use cases
need different APIs and those will change for independent reasons,
so it makes sense to separate the classes.
2021-09-15 16:09:00 +02:00
5c6cc931b2 Gizmo: add flag to hide the gizmo group during interaction
This allows a hack to be removed that temporarily overwrote
the 3D views gizmo display flag.

Also reverse change from fb27a9bb98
that runs poll on modal gizmo groups as there is some risk
that the poll function unlinks the gizmo.
2021-09-15 22:34:21 +10:00
1bd28a5e0c Cleanup: unused variable 2021-09-15 22:34:19 +10:00
c420399f4d Fix T91421: Length modifier bake influence check.
Reviewed By: Antonio Vazquez (antoniov)

Differential Revision: https://developer.blender.org/D12496
2021-09-15 18:19:56 +08:00
429136c89f Fix Asset Browser cannot open containing file anymore
In {rB9cff9f9f5df0} asset_library was renamed → asset_library_ref.

Missed to update this in assets.py.

Differential Revision: https://developer.blender.org/D12497
2021-09-15 12:09:23 +02:00
e6ca054590 Geometry Nodes: multi threaded field evaluation
This adds a new `ParallelMultiFunction` which wraps another multi-function
and evaluates it with multiple threads. The speeds up field evaluation
quite a bit (the effect is most noticeable when the number of evaluations
and the field is large).

There are still other single-threaded performance bottlenecks in field
evaluation that will need to be solved separately. Most notably here
is the process of copying the computed data into the position attribute
in the Set Position node.

Differential Revision: https://developer.blender.org/D12457
2021-09-15 11:02:39 +02:00
fb27a9bb98 Gizmo: show groups flagged with SHOW_MODAL_ALL during interaction
Follow up to fix for T73684,
which allowed some modal gizmos to hide all others.

Also resolve an issue from 917a972b56
where shear the shear gizmo would be visible during interaction.

Internally there are some changes to gizmo behavior

- The gizmo with modal interaction wont draw if it's poll function fails.
- The WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL flag now causes these gizmo
  groups to draw when another group is being interacted with.
2021-09-15 17:54:24 +10:00
785e7ddf10 Cleanup: replace defines with functions 2021-09-15 17:05:56 +10:00
8cbe55c9e9 Cleanup: correct tracker ID in comment 2021-09-15 17:05:56 +10:00
a2c5c2b406 GPencil: Dot dash modifier.
Create dot-dash effect for grease pencil strokes. User can manually edit the length, gap and styles for each segment of dashed lines.

The values in each segment can all be key-framed to make animations.

Reviewed By: Hans Goudey (HooglyBoogly), Antonio Vazquez (antoniov)

Differential Revision: http://developer.blender.org/D11876
2021-09-15 14:38:32 +08:00
c1cf66bff3 LineArt: Automatic crease with flat/smooth faces.
This allows crease lines to be automatically hidden on smooth surfaces, also provided options for:

- Showing crease on marked sharp edges.
- Force crease detection on smooth surfaces.

Reviewed By: Antonio Vazquez (antoniov)

Differential Revision: http://developer.blender.org/D12051
2021-09-15 14:03:39 +08:00
202dc3631e PyDocs: Update theme to latest version 2021-09-14 23:16:38 -04:00
94dd30208e UI: Addition Changes to Freestyle Properties
- Material Properties: Use split column layout
- Remove the redundent term 'Options'
- Remove the redundent term 'Freesttle'
2021-09-14 22:57:57 -04:00
56f8d7c705 Fix T89241: Scale to fit overflows into a second line 2021-09-15 11:15:00 +10:00
e1714ce8c9 Cleanup: spelling 2021-09-15 10:56:35 +10:00
97de4f07a3 Cleanup: doxy sections, parameter syntax 2021-09-15 10:53:12 +10:00
e6fa74ffed Fix: Use after free in spreadsheet attribute column ID
A temporary string was created in the attribute_foreach callback
and used in a map at a higher scope. When the callback finished,
the string went out of scope, was freed, then the elements in the
set pointed to freed memory.
2021-09-14 18:13:52 -05:00
Christoph Lendenfeld
7c7348f78d Fix T89027: "factor" field in pose breakdowner not updated
After applying the pose breakdowner,
the "factor" slider in the redo panel wasn't set to the correct value
This would cause the pose to jump around
once you start dragging the slider

Reviewed by: Sybren A. Stüvel
Differential Revision: https://developer.blender.org/D12187
Ref: D12187
2021-09-14 19:24:36 +01:00
0ed089cebd LibLink: Enable unittest that was previously failing in append case.
Previous commit fixed it.
2021-09-14 17:59:18 +02:00
3be5ce4aad LibLink: New Append code.
This commit fully refactors the way linked IDs are made local when
appended.

Previously, `BKE_library_make_local` was (ab)used for this task, but it
was missing some contextual data and doing complex processing to try to
work around this, with limited sucess. Further more, it was nearly
impossibe to extend (e.g. to get new append behaviors necessary for the
asset project).

The new code is a dedicated append step in WM linking process.

NOTE: BPY API (`libray.load()` context manager) uses its own code here,
which still relies on `BKE_library_make_local` for appending.
Unfortunately, merging those two different code paths is not trivial so
for now this API will remain unchanged.

Fix T55629: Append already linked Data is impossible.
2021-09-14 17:49:57 +02:00
cddb792021 ID management: Add new version of relink_to_newid using proper new remapping code.
Current `BKE_libblock_relink_to_newid` is using its own simplistic,
limited and not really correct version of ID remapping.

While doing a full replacement would have been ideal, this is
risky/time-constrained for Blender 3.0 release, so for now we'll have
both versions co-existing.
2021-09-14 17:49:35 +02:00
2d13c823ee Cleanup: fix inconsistent parameter name
Found by clang-tidy.
2021-09-14 16:41:29 +02:00
edaeec3e72 Nodes: cache node declaration on node
Previously, it was necessary to rebuild the node declaration
every time it was used. Now it is cached per node for easy
and fast access.

For more details on what this is, look at the comment in
`DNA_node_types.h`.

Differential Revision: https://developer.blender.org/D12471
2021-09-14 16:34:31 +02:00
dee0b56b92 Cleanup: simplify resource scope methods
Previously, a debug name had to be passed to all methods
that added a resource to the `ResourceScope`. The idea was
that this would make it easier to find certain bugs. In reality
I never found this to be useful, and it was mostly annoying.
The thing is, something that is in a resource scope never leaks
(unless the resource scope is not destructed of course).

Removing the name parameter makes the structure easier to use.
2021-09-14 16:08:09 +02:00
426e2663a0 Fix: use type name instead of variable name
That was a typo in rBfd60f6713a9d9e6f7d706b53bf1311f2f1cd9031.
2021-09-14 15:18:17 +02:00
fd60f6713a Functions: support optional outputs in multi-function
Sometimes not all outputs of a multi-function are required by the
caller. In those cases it would be a waste of compute resources
to calculate the unused values anyway. Now, the caller of a
multi-function can specify when a specific output is not used.
The called function can check if an output is unused and may
ignore it. Multi-functions can still computed unused outputs as
before if they don't want to check if a specific output is unused.

The multi-function procedure system has been updated to support
ignored outputs in call instructions. An ignored output just has no
variable assigned to it.

The field system has been updated to generate a multi-function
procedure where unused outputs are ignored.
2021-09-14 14:52:44 +02:00
90a48fa064 Geometry Nodes: fix memory leak for multi input sockets 2021-09-14 13:33:34 +02:00
1c1be5bdf4 Fix T90862: Texts in Outliner can have wrong icon
In contrast to the Filebrowser, the Outliner (Blender File view) did not
distinguish icons for text-based formats (if they have a filepath this
can be done though).

Maniphest Tasks: T90862

Differential Revision: https://developer.blender.org/D12347
2021-09-14 09:53:57 +02:00
30845b5c8e Doc: expand on comment for why bound-box access could cause issues 2021-09-14 13:27:15 +10:00
917a972b56 UI: keep navigation gizmos visible during modal operators
Hiding viewport navigation gizmos caused the UI to "flicker"
unnecessarily, the axis could also be useful as a reference.

Resolves T73684
2021-09-14 12:49:36 +10:00
9b0b78d58f Update RNA to User Manual Mappings 2021-09-13 19:08:12 -04:00
3ff60bcad8 Asset Template: Extra UI options
This allow users to show/hide:
* Library name / refresh.
* Assets names.
* Filter.

To set them in Python use:
display_options={'NO_NAMES', 'NO_FILTER', 'NO_LIBRARY'}

With contributions by Julian Eisel.

Differential Revision: https://developer.blender.org/D12476
2021-09-13 19:51:46 +02:00
9fe6854a93 Cleanup: Remove duplicate code
Class SEQUENCER_PT_overlay as defined twice.
2021-09-13 17:48:57 +02:00
Germano Cavalcante
4f73d43adc Fix T90736: Problem applying scale to curves
Curve Points of handle of type `Auto` on curves not uniformly scaled
cause the shape of the curve to be modified after applying the scale.

So change these handles to `Aligned` in these cases.

Reviewed By: campbellbarton

Maniphest Tasks: T90736

Differential Revision: https://developer.blender.org/D12281
2021-09-13 12:43:04 -03:00
a78410386b Cleanup: fix typo in comment 2021-09-13 16:49:32 +02:00
1bcdd1c54e Fix T91320: Support flipping sides in mesh bisect
Changing active side was introduced in {rB7ff6bfd1e0af} but was never
working for tools/operators other than the sculpt line mask tool.

While for most tools/operators this actually does not make sense, the
bisect tool/operator can actually benefit from it.

thx @campbellbarton for additional input!

Maniphest Tasks: T91320

Differential Revision: https://developer.blender.org/D12473
2021-09-13 16:42:27 +02:00
503d79cd77 Fix straightline gesture snapping not working for modal tools
This was implemented in {rB14d56b4217f8} but was never working for
tools/operators other than the sculpt line mask tool.

To be precise, the preview actually snapped but the operations (e.g.
mesh bisect, vertex weight gradient) still happened "unsnapped" in
modal. For the sculpt line mask tool this wasnt a problem, because it
only draws a preview while modal, the actual mask was only applied
later.

This solves part one of T91320 (snapping), sculpting also introduced
flipping in {rB7ff6bfd1e0af} which does not make much sense for all
tools, but in bisect this could actually be supported, will add that in
a separate Diff.

ref T91320

Maniphest Tasks: T91320

Differential Revision: https://developer.blender.org/D12470
2021-09-13 16:42:27 +02:00
Iyad Ahmed
6f52ebba19 UI: Freestyle UI Upgrade
Suggested and funded by [[ https://blendernpr.org/| BNPR ]], this patch aims to update the long not-updated Freestyle UI

**Why do the UI upgrade:**

  - Freestyle UI doesn't match the rest of Blender UI, it was neglected for a long time
  - The current UI makes Freestyle workflows tedious and distracting

**Highlights:**

For before/after screenshots see https://developer.blender.org/D10505

Video:
https://youtu.be/qaXhuJW_c9U

Workflow video (older revision): https://youtu.be/IqbjIq_A800

Doc patch (WIP): https://github.com/bnpr/FreestyleUIUpgrade/blob/main/freestyle-ui-upgrade-docs.diff

Reviewed By: #user_interface, Blendify, HooglyBoogly, Severin

Differential Revision: https://developer.blender.org/D10505
2021-09-13 10:37:50 -04:00
c9c890f196 Templates: Set more user preference settings to be swapped
* Splash Disable
* Show gizmo navigate
* ui scale

It is a bit arbritrary now. So those are the flags I'm
setting up for the Blender 101 project (T90025).

Differential Revision: https://developer.blender.org/D12474
2021-09-13 16:18:59 +02:00
4b06420e65 Cleanup: Packedfile don't repeat yourself.
Introduced `BKE_packedfile_unpack` that is called from the specialized
implementation for Image, Sound, Font, Volume etc. This is in
preparation for T91252.
2021-09-13 14:13:58 +02:00
603ae580ce Build: show better "make update" error message when in detached HEAD state 2021-09-13 13:14:17 +02:00
b777df8080 Fix: fix equality operator for fields
Instead of comparing the referenced field node by pointer,
compare the nodes directly instead. This is important
because different field nodes might be the same semantically.
2021-09-13 13:09:18 +02:00
410dc76177 Various UI messages fixes and updates. 2021-09-13 12:40:37 +02:00
f6ebbfe7de Nodes: move some texture nodes to c++
This is necessary to be able to use them in geometry nodes.
2021-09-13 11:54:05 +02:00
9d6e960e2c Fix make_utils.py recent API breackage.
rB546314fc9669 broke `svn_libraries_base_url` utils API compatibility
for no good reasons, making new `branch` argument explicitely optional.

Reported on chat by  Michael Kowalski (@makowalski), thanks!
2021-09-13 11:41:43 +02:00
25550c210a Fix regression test after recent fix
Was cased by 9b2b32a333.
2021-09-13 11:30:32 +02:00
eaa35b27e0 Fix T91311: incorrect batch generation for instances
This was a mistake in {rB5a9a16334c573c4566dc9b2a314cf0d0ccdcb54f}.
2021-09-13 10:42:54 +02:00
9b2b32a333 Fix T84638: Wrong scale for primitives with radius
Creating some primitives allows for a scale value (via python) that will
scale the object accordingly. For objects with a radius parameter
(like cylinders, spheres, etc.) passing a scale different to (1,1,1)
would result in unexpected behavior.

For example:
`>>> bpy.ops.mesh.primitive_uv_sphere_add(radius=2, scale=(1,1,2))`
We would expect this to create a sphere with a radius of 2
(dimensions 4,4,4) and then be scaled *2 along the z-axis
(dimensions 4,4,8). But this would previously create a scaled sphere
with dimensions (2,2,4).

The scale was simply divided by two. Maybe because the "radius"
parameter for creating the primitives was confusingly named "diameter"
(but used as the radius).

The fix adds a scale parameter to `ED_object_new_primitive_matrix`
and also renames the wrongly named "diameter" parameters to "radius".

Reviewed By: campbellbarton

Maniphest Tasks: T84638

Ref D10093
2021-09-13 18:02:27 +10:00
9d336576b5 Cleanup: clang-format 2021-09-13 17:50:02 +10:00
Jon Denning
e0394761b9 GPUShader: Expose name for debugging & identifying shaders
Added optional `name` argument to `GPUShader` constructor
(defaults to `pyGPUShader`), and added `name` getter to `GPUShader`.

Ref D12393

Reviewed By: campbellbarton, jbakker
2021-09-13 16:16:45 +10:00
b5a1c194c5 Cleanup: early return from smoothview when the view is unchanged 2021-09-12 19:51:17 +10:00
2aa7edbe6b Cleanup: spelling 2021-09-12 19:51:16 +10:00
15405685d9 Cleanup: Remove no-op/unused code 2021-09-11 15:00:36 -05:00
b9febb54a4 Geometry Nodes: Support modifier on curve objects
With this commit, curve objects support the geometry nodes modifier.

Curves objects now evaluate to `CurveEval` unless there was a previous
implicit conversion (tessellating modifiers, mesh modifiers, or the
settings in the curve "Geometry" panel). In the new code, curves are
only considered to be the wire edges-- any generated surface is a mesh
instead, stored in the evaluated geometry set.

The consolidation of concepts mentioned above allows remove a lot of
code that had to do with maintaining the `DispList` type temporarily
for modifiers and rendering. Instead, render engines see a separate
object for the mesh from the mesh geometry component, and when the
curve object evaluates to a curve, the `CurveEval` is always used for
drawing wire edges.

However, currently the `DispList` type is still maintained and used as
an intermediate step in implicit mesh conversion. In the future, more
uses of it could be changed to use `CurveEval` and `Mesh` instead.

This is mostly not changed behavior, it is just a formalization of
existing logic after recent fixes for 2.8 versions last year and two
years ago. Also, in the future more functionality can be converted
to nodes, removing cases of implicit conversions. For more discussion
on that topic, see T89676.

The `use_fill_deform` option is removed. It has not worked properly
since 2.62, and the choice for filling a curve before or after
deformation will work much better and be clearer with a node system.

Applying the geometry nodes modifier to generate a curve is not
implemented with this commit, so applying the modifier won't work
at all. This is a separate technical challenge, and should be solved
in a separate step.

Differential Revision: https://developer.blender.org/D11597
2021-09-11 13:54:40 -05:00
c946fdb2e5 Calm Warning: Unused Variable
Calms warning for unused variable in `constraint_copy_to_selected_poll`
by using UNUSED_VARS.

See D12453 for further details

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

Reviewed by Campbell Barton
2021-09-11 09:07:57 -07:00
863460e5a5 Compositor: Full frame previews
Adds full frame implementation to PreviewOperation.

Part of T88150.
2021-09-11 15:42:29 +02:00
cbe05edde5 Compositor: Fix crash when hashing unconnected operations
It was causing some tests to fail when enabling Full Frame mode.
2021-09-11 15:42:23 +02:00
4e78b89e48 Geometry Nodes: add field support for socket inspection
Since fields were committed to master, socket inspection did
not work correctly for all socket types anymore. Now the same
functionality as before is back. Furthermore, fields that depend
on some input will now show the inputs in the socket inspection.

I added support for evaluating constant fields more immediately.
This has the benefit that the same constant field is not evaluated
more than once. It also helps with making the field independent
of the multi-functions that it uses. We might still want to change
the ownership handling for the multi-functions of nodes a bit,
but that can be done separately.

Differential Revision: https://developer.blender.org/D12444
2021-09-11 13:05:20 +02:00
166c8be7ac Cleanup: use nullptr 2021-09-11 12:41:46 +02:00
aeeffb935e Functions: store cursors to previous instructions
Now an instruction knows the cursors where it is inserted instead
of just the instruction that references it. This has two benefits:
* An instruction knows when it is the entry instruction.
* The cursor can contain more information, e.g. if it is linked to the
  true or false branch of a branch instruction.

  This also simplifies updating the procedure in future optimization
  passes.
2021-09-11 11:43:59 +02:00
6ae8de4742 Cleanup: Rename variables, simplify logic
Mostly renaming the variables to improve line wrapping.
But also the "foreach_attribute" loops look simpler now.
Also use `Spline::copy_base_settings` and don't bother
with an extra call to reallocate the attribute arrays.
2021-09-10 23:21:58 -05:00
d475f99460 Geometry Nodes: Support "Evaluated" mode in Resample Curve node
Just like the curve to points node, this mode outputs point locations
based on the input curve's evaluated points (the points you see in the
viewport). This is expected to be faster, since it doesn't have to
sample equal positions on the result, and it's also consistent with
the existing choices in the curve to points node.
2021-09-10 22:58:30 -05:00
cb83313863 Nodes: Add vector min/max support to new socket builder API
Also use it to fix an incorrect min and max in the cube mesh
primitive node.
2021-09-10 22:48:49 -05:00
Nikhil Shringarpurey
eab26f1334 UI: Quad View Option Names Improved
Improvements to Quad View options' titles and descriptions.

See D12381 for more details.

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

Reviewed by Hans Goudey and Campbell Barton
2021-09-10 14:22:21 -07:00
8745bb9628 Cleanup: Split legacy node type defines 2021-09-10 15:58:18 -05:00
6a00e7a428 Fix: Incorrect file subversion for geometry node versioning
rBe2f99c338bd57 should have used the subversion currently defined
in Blender, instead it used one lower, so some files didn't have the
versioning applied.
2021-09-10 13:26:46 -05:00
5e0684b07d Revert startup.blend changes from commit a00507c482
It appears an old version of this file was committed by accident. The
intended change to remove sculpt layers was done in versioning code and
does not require a modified startup.blend.
2021-09-10 18:59:39 +02:00
Henrik Dick
28f773925a Fix Constraints not updating on move in stack
Flag the changed object and its bones to update after moving a
constraint in the stack up or down. The two operators for move up and
move down seem to be unused, but I notices they had the same problem, so
I added the update there as well.

Reviewed By: sybren

Differential Revision: https://developer.blender.org/D12174
2021-09-10 18:49:18 +02:00
6b7b4f8e57 VFont: Refactor of check_freetypefont()
Refactor of our Vfont check for font validity.

See D12068 for further details.

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

Reviewed by Campbell Barton
2021-09-10 09:30:21 -07:00
e2f99c338b Geometry Nodes: Add versioning to change legacy node ID names
Recently we have decided to avoid fancier versioning for nodes with
string inputs for attribute names when updating the attribute workflow
for 3.0. In that case we would just duplicate any node that will
have an updated version to work with fields.

We want to be able to use the "proper" ID names for the new versions
of the nodes though, so this patch adds "Legacy" to the IDs of all
nodes that will be replaced in 3.0. This commit also removes the nodes
from the add menu when the fields experimental preference is enabled,
in order to make it clear what has been updated and what hasn't.

Nodes in the "Maybe" categories in versioning_300.c can be renamed
later if necessary. For now it's probably better to be conservative,
and to keep the list complete.

Differential Revision: https://developer.blender.org/D12420
2021-09-10 10:34:49 -05:00
Brecht Van Lommel
128eb6cbe9 Modifiers: export motion blur velocity through attribute
Previously fluid simulation and Alembic modifiers had a dedicated function
to query the velocity for motion blur. Now use a more generic system where
those modifiers output a velocity attribute.

Advantages:
* Geometry and particle nodes can output velocity through the same mechanism,
  or read the attribute coming from earlier modifiers.
* The velocity can be preserved through modifiers like subdivision surface or
  auto smooth.
* USD and Alembic previously only output velocity from fluid simulation, now
  they work with velocity from other sources too.
* Simplifies the code for renderers like Cycles and exporters like
  Alembic and USD.

This breaks compatibility:
* External renderers and exporters accessing these velocities through the
  Python API now need to use the attribute instead.
* Existing modifier node setups that create an attribute named "velocity"
  will render differently with motion blur.

Differential Revision: https://developer.blender.org/D12305
2021-09-10 16:48:30 +02:00
42215d7cb8 Tests: more graceful handling of keyboard interrupting benchmarks
Leave current test result unchanged and stop executing immediately,
so it can be continued.
2021-09-10 16:48:26 +02:00
eb96f0cf06 Add missing bit to own previous commit
Amendment to 7a5216497c.
Removed this before committing, because I thought it wasn't needed. Of
course it was...
2021-09-10 15:01:48 +02:00
0467ff4053 Python: extra check on BPY_thread_save() to ensure proper GIL handling
Use `_PyThreadState_UncheckedGet()` to check that the current thread is
tracked by Python before checking whether it has the GIL. The latter
will abort when the former is false.
2021-09-10 14:58:02 +02:00
ca39aff59d Cleanup: Fix comment in recent commit.
A task is created for each item in a list base. It used to say that a
thread was created for each item.
2021-09-10 14:45:03 +02:00
7a5216497c Fix possible crash displaying asset preview from current file
For some reason the asset preview isn't created or loaded correctly in
some instances. This could be addressed with D9974, but hard to tell
since I only have a failing .blend file, no steps to recreate it from
scratch.

Would crash when opening an Asset Browser, selecting an object asset
(that has an invalid preview stored) and opening the Asset Browser
sidebar, so that the preview is visible there.
2021-09-10 14:44:09 +02:00
Jeroen Bakker
7f1fe10595 T78995: Enable keylist threaded drawing.
This enabled multithreaded building of the keys that needs to be drawn
in the timeline (and other action editors).

On an AMD Ryzen 3800 using a mocap data test file (available in patch)
the performance went from 2fps to 8fps. The performance increase depends
on the number of rows of keyframes that is shown in for example the
timeline editor.

Each row will be using a different thread. Currently the bottleneck is
the summary channel that we could split up in the future even more (
although that is a complex refactoring work).

Reviewed By: sybren

Differential Revision: https://developer.blender.org/D12198
2021-09-10 14:31:00 +02:00
a1167e910a BLI: Add Cycles compatible Perlin noise
This patch adds new Perlin noise functions to BLI. The noises are compatible
with the shading texture noises in EEVEE, SVM, and OSL.

The existing Jenkins hash functions couldn't be used because they are not
compatible with the shading implementations and an attempt at adjusting the
implementation will break compatibility in various areas of Blender. So the
simplest approach is to reimplement the relevant hashing functions inside the
noise module itself.

Additionally, this patch also adds a minimal float4 structure to use in the
interface of the noise functions.

Reviewed By: JacquesLucke

Differential Revision: https://developer.blender.org/D12443
2021-09-10 14:25:32 +02:00
Jeroen Bakker
60cfdf0809 Anim: Keylist drawing optimization by using arrays.
Change data structure of keylists. Reducing the balancing overhead and therefore increases performance.

| **Function** | **Master** | **Patch** |
|`draw_summary_channel`| 0.202105s| 0.083874s |

When adding items to the keylist it will store it in a linked list. This linked list is
accompanied with the length (key_len) and a `last_accessed_column`. last_accessed_column is a cursor
that improve the performance when adding new items as they are mostly ordered by frame numbers.
last_accessed_column is reset when a new fcurve/mask/... is added to the keylist.

Before searching or array access. the listbase needs to be converted to an array.
`ED_keylist_prepare_for_direct_access`. After that the caller can use
`ED_keylist_find_*` or `ED_keylist_array*` functions.

The internal array can also be accessed via the `ED_keylist_listbase` function.
The items inside the array link to the previous/next item in the list.

Reviewed By: sybren

Differential Revision: https://developer.blender.org/D12052
2021-09-10 13:28:47 +02:00
a00507c482 Templates: remove masking layers from the default startup file
Remove sculpt mask layer from the default cube, added in
444934632a.
2021-09-10 19:29:45 +10:00
fe4286435c Depsgraph: release GIL when evaluating the depsgraph
Evaluating the dependency graph potentially executes Python code when
evaluating drivers. In specific situations (see T91046) this could
deadlock Blender entirely. Temporarily releasing the GIL when evaluating
the depsgraph resolves this.

This is an improved version of
rBfc460351170478e712740ae1917a2e24803eba3b, thanks @brecht for the diff!

Manifest task: T91046
2021-09-10 11:03:54 +02:00
6d7113c363 Merge branch 'master' into xr-controller-support 2021-09-10 17:57:57 +09:00
33306067da Update based on D10948 2021-09-10 17:23:56 +09:00
93d2940603 Link/Append: Fix unreported obdata being instantiated even when already used by linked/appended data.
Do not instantiate obdata when it is not actually loose.
2021-09-10 09:28:44 +02:00
284c9430f9 Cleanup: Silenced compilation warning in ghost. 2021-09-10 09:21:02 +02:00
Jon Denning
db6b3801b3 Update command line argument description for --addons
Changed doc string for Blender `--addons` command line argument
to explain what it does rather than just describing what it expects.

Reviewed By: Blendify

Ref D12445
2021-09-10 14:36:41 +10:00
82ab2c1678 XR: Re-enable SteamVR OpenGL backend for AMD gpus
Addresses T76082.

Since the DirectX backend does not work for AMD gpus
(wglDXRegisterObjectNV() fails to register the shared OpenGL-DirectX
render buffer, displaying a pink screen to the user), the original
solution was to use SteamVR's OpenGL backend, which, as tested
recently, seems to work without any issues on AMD hardware.

However, the SteamVR OpenGL backend (on Windows) was disabled in
fe492d922d since it resulted in crashes with NVIDIA gpus (and still
crashes, as tested recently), so SteamVR would always use the
AMD-incompatible DirectX backend (on Windows).

This patch restores use of the SteamVR OpenGL backend for non-NVIDIA
(AMD, etc.) gpus while maintaining the DirectX workaround for NVIDIA
gpus. In this way, issues are still resolved on the NVIDIA side but
AMD users can once again use the SteamVR runtime, which may be their
only viable option of using Blender in VR.

Reviewed By: Julian Eisel

Differential Revision: https://developer.blender.org/D12409
2021-09-10 13:19:43 +09:00
ee3b4e8420 Windows: Fix VS2022 detection
VS2019 had a compiler update moving it into the
range that was used to detect VS2022. This patch
updates the detection to the current VS2022
preview compiler version.

Reported by Jesse Y on chat.
2021-09-09 17:19:58 -06:00
c9347b9a7f UI: File Browser Options Fix
With D12436 two File Browser properties were renamed but two references
not changed in space_filebrowser.py

See D12449 for details.

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

Reviewed by Hans Goudey
2021-09-09 14:43:34 -07:00
f13eb69269 Revert "Depsgraph: release GIL when evaluating the depsgraph"
It is causing crashes in rendering, when releasing the GIL in render threads
while the main thread is holding it.

Ref T91046

This reverts commit fc46035117.
2021-09-09 19:19:18 +02:00
efcf46fb6d Fix T90317: Confusing File Browser Preferences
Preferences / File Browser section made less confusing.

See D12436 for details and comparisons.

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

Reviewed by Campbell Barton and Julian Eisel
2021-09-09 09:49:45 -07:00
84d03a1298 Fix T88755: Reuse Temp Windows by Type not Title
Reuse temporary windows when they share the same single area type, not
because they share the same title.

See D12401 for more details.

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

Reviewed by Campbell Barton
2021-09-09 09:26:44 -07:00
45c44a5b5b Fix compiler warnings about virtual functions but non-virtual destructor 2021-09-09 17:11:01 +02:00
ed4ef77f49 DNA: allow initializing defaults for deprecated struct members
This can be useful for better forward compatibility.
2021-09-09 17:11:01 +02:00
b4fd8750f9 Geometry Nodes: Allow exposing color sockets to the modifier
This commit allows connecting color sockets to the group input and
changing the input values in the modifier. Before there was an error
since this was more complicated to support with the previous IDProperty
UI data storage method.

Differential Revision: https://developer.blender.org/D12437
2021-09-09 09:43:00 -05:00
62ec88eb84 Cleanup: use NODE_SOCKET_API_ARRAY for array sockets
This prevents copying the arrays when setting new values in the sockets.

No functional changes.
2021-09-09 16:39:45 +02:00
3eb6569b38 Fix build error on Linux
07c6af4136 was missing include.
2021-09-09 23:22:48 +09:00
Ville Kivistö
07c6af4136 XR: Support for Varjo OpenXR extensions
This adds support for two Varjo specific OpenXR vendor extensions:
1) XR_VARJO_QUAD_VIEWS
2) XR_VARJO_FOVEATED_RENDERING

Together these enable human eye resolution rendering on supported
devices (currently mainly Varjo XR-3 and VR-3).

In addition, there's a detection for Varjo OpenXR runtime.

This has been tested on real Varjo XR-3 hardware and Varjo Simulator
and confirmed to function correctly. Foveation works, and the views are
rendered correctly for all the four views.

Reviewed By: Peter Kim, Julian Eisel

Differential Revision: https://developer.blender.org/D12229
2021-09-09 22:49:48 +09:00
fc46035117 Depsgraph: release GIL when evaluating the depsgraph
Evaluating the dependency graph potentially executes Python code when
evaluating drivers. In specific situations (see T91046) this could deadlock
Blender entirely. Temporarily releasing the GIL when evaluating the depsgraph
resolves this.

Calling the `BPy_BEGIN_ALLOW_THREADS` macro is relatively safe, as it's
a no-op when the current thread does not have the GIL.

Developed in collaboration with @sergey

Manifest task: T91046
2021-09-09 14:27:33 +02:00
da50cd86a7 Cleanup: clarify comment about the use of _PyThreadState_UncheckedGet()
No functional changes.
2021-09-09 14:27:33 +02:00
bf47fb40fd Geometry Nodes: fields and anonymous attributes
This implements the initial core framework for fields and anonymous
attributes (also see T91274).

The new functionality is hidden behind the "Geometry Nodes Fields"
feature flag. When enabled in the user preferences, the following
new nodes become available: `Position`, `Index`, `Normal`,
`Set Position` and `Attribute Capture`.

Socket inspection has not been updated to work with fields yet.

Besides these changes at the user level, this patch contains the
ground work for:
* building and evaluating fields at run-time (`FN_fields.hh`) and
* creating and accessing anonymous attributes on geometry
  (`BKE_anonymous_attribute.h`).

For evaluating fields we use a new so called multi-function procedure
(`FN_multi_function_procedure.hh`). It allows composing multi-functions
in arbitrary ways and supports efficient evaluation as is required by
fields. See `FN_multi_function_procedure.hh` for more details on how
this evaluation mechanism can be used.

A new `AttributeIDRef` has been added which allows handling named
and anonymous attributes in the same way in many places.

Hans and I worked on this patch together.

Differential Revision: https://developer.blender.org/D12414
2021-09-09 12:54:20 +02:00
0f6be4e152 Cleanup: Readfile: cleanup some logic checks. 2021-09-09 10:51:39 +02:00
0c0e5a8420 IDmanagement: makelocal: Fix mistake in recent commit.
rB8cc3d2d6f51f introduced option to force make_local code to either copy
or actually make a linked ID local, but logic of boolean options
handling was broken.

This commit simplifies logic here and fixes the issue.

NOTE: Since those new options were not used yet this was a harmless bug.
2021-09-09 10:51:10 +02:00
f8ead736a0 Fix FONT objects cannot use Object Font anymore
Mistake in {rB459974896228}.

To use Object Fonts, (vertex) instancing needs to be enabled.
So bring back the instancing panel and improve the instancing choice
(similar to rB6c0c766bcaa0) by just giving the 'Vertex' choice (or
'None') and explain this is only used for Object Fonts on characters.

Was reported in D11348 itself.

Differential Revision: https://developer.blender.org/D12438
2021-09-09 09:38:48 +02:00
9bb99532a5 Fix typo in BKE_object_as_kdtree
Seems like an oversight in {rB86635402d516}?

Stumbled over this while investigating another report, but this line in
its current form does not make sense (was taking  derivedFinal - not
derivedDeform - prior so I assume this has to be
BKE_object_get_evaluated_mesh now).

(it is now only used for vertex parenting where this should not be an
issue, but best keep this generic).

Differential Revision: https://developer.blender.org/D12425
2021-09-09 08:38:34 +02:00
b813648378 Fix typo checking empty gizmo keymap 2021-09-09 16:27:52 +10:00
3da09f4e29 Cleanup: remove newlines from logging text
Line endings are already added.
2021-09-09 16:26:15 +10:00
bda9e4238a Fix smooth-view failure to add mouse-move events
View operations that left the cursor over a gizmo were not being updated
because the mouse-move event was added while the view was animated
instead of once the animation had completed.
Mouse-move events were also missing when smooth-view was disabled.

This fixes a glitch with the 3D view navigation gizmo where multiple
clicks on the view aligned axis failed to switch to the opposite side
unless the user moved the cursor between clicks.
2021-09-09 15:33:44 +10:00
c8f80453d5 Modifier: add support for vertex groups
Allow blending the imported cache with the modifiers stack above the
MeshCache modifier.

This is particularly useful for instance when dealing with cloth
simulations performed in another software, where some parts of the cloth
are completely pinned (non-simulated, following the armature). Indeed,
this would allow modifying the animation in some areas without having to
rebake the other parts or the cloth, resulting in a much more flexible
workflow.

Reviewed By: #modeling, campbellbarton, mont29

Ref D9898
2021-09-09 14:05:35 +10:00
f9ebd17b4b Gizmo: warn when 2D projection fails with non-invertable matrices
Add a warning to quickly pinpoint the problem.

This would have simplified tracking down this problem in D12105.
2021-09-09 13:14:57 +10:00
df65103bf0 Fix: Incorrect default for exposed geometry nodes vectors 2021-09-08 18:44:35 -05:00
a131e3bec7 Fix GPU Buffer not allowing uint values greater than one byte
Error in format passed in `PyArg_Parse`
2021-09-08 20:28:00 -03:00
4e91cd5c11 Fix T91255: IDProperty UI as_dict() returns step as default value
Another typo in this section of code.
2021-09-08 15:46:02 -05:00
8f785524ae VSE: Adding a panning angle for multichannel audio.
The panning angle allows a more intuitive panning when the output is
surround sound. It sets the angle on the horizontal plane around the
listener. 0 degrees is to the front, negative values go to the left and
positive ones to the right. +/-180 degrees is directly from the back.

Technical detail: the panning value is linear with the panning angle
with a factor of 90 degrees. For stereo this means that -1 is left and
+1 right, since the speakers are exactly 90 degrees to either side.

Differential Revision: https://developer.blender.org/D12275
2021-09-08 21:18:08 +02:00
5bfc3a3421 Fix error running benchmark script with environment variables for builds
Ref D12434
2021-09-08 19:58:27 +02:00
6fc94d1848 Tests: updates for performance benchmarking
* Make "run" command (re-)run all tests, add "update" command to only
  run queued and outdated tests equivalent to the old "run" command.
* Support specifying environment variables for revisions, to easily
  compare multiple parameter values.
* Better sorting of revisions in graph.
2021-09-08 16:40:58 +02:00
6bc6ffc35c Fix T91241: wrong labels and identifiers for id sockets
`nodeAddSocket` expects the name and identifier in a
different order.
2021-09-08 15:57:22 +02:00
96ef184377 USD import: remove unused files.
Removed unused usd_reader_instance.cc and .h files.
2021-09-08 09:29:16 -04:00
ba5d9fa275 Cleanup: typedef enum for eImageType. 2021-09-08 10:35:16 +02:00
b5f2b81751 Cleanup: typedef enum for eImageSource. 2021-09-08 10:34:21 +02:00
60e9fb9929 Cleanup: consisten naming slot -> resolution.
Makes naming consistent with image_gpu.c
2021-09-08 10:28:45 +02:00
Jeroen Bakker
2b2d427bba Fix T90825: Performance texture painting with limited scale.
Improve texture painting/uv editing performance when limited scale is active.
Cause of the slow down is that the image editor draws the image in maximum resolution,
but the 3d viewport uses the limited scale. The variation reuses the same GPU texture
and needed to be uploaded/scaled twice to the GPU.

This patch will adds texture slots that can hold the scaled down and the maximum
resolution image. This would allow better cache hits and reuse of existing caches.

Maximum resolution textures are reused for limited scale when they fit to reduce memory
and CPU footprint.

Reviewed By: fclem

Differential Revision: https://developer.blender.org/D12388
2021-09-08 09:56:13 +02:00
Jeroen Bakker
54f5c174a8 Asset: Dropping Material assets on material slot under mouse cursor.
This patch allows dropping material assets from material slot under the mouse
cursor. Before this change the material slot had to be hand-picked from the
properties panel.

For consistency it is chosen to do this in any shading mode as the tooltip shows
what is exactly going to happen during release.

The feature also works for other object types than Meshes as it uses the drawn surface on the
GPU to detect the material slots. Performance of this patch has been tested with AMD GCN3.0
cards and are very responsive.

Reviewed By: fclem, Severin

Differential Revision: https://developer.blender.org/D12190
2021-09-08 08:47:26 +02:00
8d40d61af0 Fix T91225: Quick Favorites and shortcuts are broken for some properties
Caused by {rB3e4d720ae483}.

Before above commit, this had a different path handling and
RNA_path_from_ID_to_struct() was always used [which kind of took care of
this]. Now this is only used if ptr represents an ID itself, so we are
"loosing" part of the path.

This patch adds the path back on the member_id in
wm_context_member_from_ptr() for everthing related to space_data, so
WM_context_path_resolve_property_full() can construct a full path even
for these.

Maniphest Tasks: T91225

Differential Revision: https://developer.blender.org/D12418
2021-09-08 08:25:57 +02:00
7beb4a0e0a Fix non-exiting property in keymap
In e6a1d488ab `deselect_all` property was removed from
`sequencer.select` operator but some keymap items were missed, which was
caught by tests by buildbot.
2021-09-08 01:23:07 +02:00
1680c3d510 UI: Remove label of mode in Point Instance node
There isn't enough space for this label at the default node width, and
it was obvious what the drop-down is doing anyway.
2021-09-07 17:05:58 -05:00
e6a1d488ab Cleanup: VSE select operator
Operator combines more features and it wasn't very transparent which
properties are used in which feature and how they are used.

Features linked_time, side_of_frame and linked_handle are
isolated, logic moved into own function.

deselect_all property was removed as it practically equals to
!extend in all cases.

Functional change: Dragging existing selection will not change active
strip. Previously this could happen if click happened on strip that
wasn't active.

Reviewed By: campbellbarton

Differential Revision: https://developer.blender.org/D12320
2021-09-08 00:01:00 +02:00
4abbf6d82b Fix T90967: Snapping not working with single strip
Even if `snap_targets` `SeqCollection` is empty, there can be static
snap points defined, so don't condition snapping on non-zero target
count.

Differential Revision: https://developer.blender.org/D12400
2021-09-07 23:39:50 +02:00
Christoph Lendenfeld
adbafe3b43 Animation: Implement generic slider in graph_slider_ops
This patch implements the generic slider from
`ed_draw.c` to the `GRAPH_OT_decimate` operator
This draws a useful UI and enables precision mode and stepping
Overshoot is disabled
The status message is moved to the workspace footer

Reviewed by: Sybren A. Stüvel
Differential Revision: https://developer.blender.org/D9361
Ref: D9361
2021-09-07 20:10:53 +01:00
a392609ab6 Cleanup: Move function to versioning_common.cc 2021-09-07 13:28:14 -05:00
73ef2fc2f4 Fix T91093: off by one error in when resampling curve
The bug existed in the Curve Resample and Curve to Points node.

Differential Revision: https://developer.blender.org/D12416
2021-09-07 16:07:18 +02:00
08acbdc1ff Fix T91219: Crash canceling scale keyframes in dope sheet grease pencil
Caused by {rBb0d9e6797fb8}

Ideally `td->loc` should always be set and point to a 3d array.
2021-09-07 11:04:20 -03:00
2b4afcbb4c Fix T91236: AssetBrowser crash with certain collections
Caused by {rB5a9a16334c57}

Linking/appending an asset made from a collection containing certain
types of objects lacking bounding boxes (camera, light) would crash.

Add simple bbox check to prevent the crash.

Maniphest Tasks: T91236

Differential Revision: https://developer.blender.org/D12415
2021-09-07 13:22:04 +02:00
c2ce68a018 Fix T91238: crash when instancing geometry group input 2021-09-07 13:18:59 +02:00
8cc3d2d6f5 ID management: add options to force make local or force copy IDs when making them local.
This is to be used when calling code already knows whether the 'made
local' linked ID should be copied, or can directly be converted to a
local one.

Currently unused , this is preparation for rewrite of append code.
2021-09-07 10:18:49 +02:00
d7d8eb7de4 GPencil: Change icons missing in previous commit
It was missing to change the modifier itself, not only RNA enum list.
2021-09-06 18:56:45 +02:00
08593e46a3 Fix T91187: incorrect socket identifier 2021-09-06 18:47:06 +02:00
3b1a16833b UI: Area Split and Join Mouse Cursor Feedback
This patch just changes the mouse cursor to a "stop sign" when dragging
to an unsupported location during Join or Split operations.

See D11396 for details and examples.

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

Reviewed by Campbell Barton
2021-09-06 09:40:59 -07:00
5a9a16334c Geometry Nodes: support for geometry instancing
Previously, the Point Instance node in geometry nodes could only instance
existing objects or collections. The reason was that large parts of Blender
worked under the assumption that objects are the main unit of instancing.
Now we also want to instance geometry within an object, so a slightly larger
refactor was necessary.

This should not affect files that do not use the new kind of instances.

The main change is a redefinition of what "instanced data" is. Now, an
instances is a cow-object + object-data (the geometry). This can be nicely
seen in `struct DupliObject`. This allows the same object to generate
multiple geometries of different types which can be instanced individually.

A nice side effect of this refactor is that having multiple geometry components
is not a special case in the depsgraph object iterator anymore, because those
components are integrated with the `DupliObject` system.

Unfortunately, different systems that work with instances in Blender (e.g.
render engines and exporters) often work under the assumption that objects are
the main unit of instancing. So those have to be updated as well to be able to
handle the new instances. This patch updates Cycles, EEVEE and other viewport
engines. Exporters have not been updated yet. Some minimal (not master-ready)
changes to update the obj and alembic exporters can be found in P2336 and P2335.
Different file formats may want to handle these new instances in different ways.

For users, the only thing that changed is that the Point Instance node now
has a geometry mode.

This also fixes T88454.

Differential Revision: https://developer.blender.org/D11841
2021-09-06 18:31:25 +02:00
d9ad77fa58 GPencil: Replace temp icons for final design
New icons for LIneArt and Length modifier
2021-09-06 18:00:50 +02:00
bd79d6067c make.bat: Fix missing quotes in python detection 2021-09-06 17:58:38 +02:00
ce71357711 Fix T90414: New GPencil icons
Designed by @mendio

The new icons are:

* Dot-Dash modifier
* Length Modifier
* Line Art modifier
2021-09-06 17:35:12 +02:00
Erik Abrahamsson
5a02d0da7a Fluid: Parallelizations for Mantaflow functions (D12002)
This update includes part of a performance boost from D12002.
Contributed by @erik85
2021-09-06 17:30:30 +02:00
3e23af4c49 Fluid: Clang-format cleanups
Just cleanup.
2021-09-06 17:30:30 +02:00
a3ca973dec Nodes: fix incorrect id socket update
The issue was that the entire socket was rebuild, even though
only its `SOCK_HIDE_LABEL` flag changed. This broke e.g.
Object sockets from old files.
2021-09-06 17:21:42 +02:00
861b7071a2 Fix crash drawing hair with older GPUs.
Some GPU's have support for compute shaders, but don't support
GLSL 4.3. This resulted in compiler errors and crashes.

This issue could have been solved by supporting older GLSL languages but
that would have been a hassle to get it right. We already have a
fallback in place for GPU's that don't support compute shaders at all.
2021-09-06 15:47:44 +02:00
William Leeson
5eed7cdc8c Division by zero when there are no lights and only emissive surfaces
When rendering the test scene in T79190 which has only emissive surfaces a division by zero occurs. This is a simple patch to remove this.

Reviewed By: brecht

Maniphest Tasks: T79190

Differential Revision: https://developer.blender.org/D11682
2021-09-06 13:14:46 +02:00
e2bbb5b07e BLI: add default hash for shared_ptr and reference_wrapper
This makes it easier to use these types as keys in Map, Set and VectorSet.
2021-09-06 12:54:51 +02:00
4d0497bea4 Cleanup: format, spelling 2021-09-06 20:34:00 +10:00
4f0ec3cea5 Cleanup: use pre-calculated size variable
Oversight in a0912ff566
2021-09-06 20:32:35 +10:00
687f70ceca ImBuf: add IMB_allocFromBufferOwn that takes ownership of the buffer
Avoids duplicating the image buffer when saving thumbnails.
2021-09-06 20:05:58 +10:00
a0912ff566 Cleanup: support passing in arbitrary buffers to IMB_allocFromBuffer
Also remove IB_metadata flag from the resulting imbuf as this image
has no meta-data.
2021-09-06 20:04:25 +10:00
49f1695ed0 BLI_utildefines: add UNUSED_FUNCTION_WITH_RETURN_TYPE
Unfortunately the UNUSED_FUNCTION macro doesn't work for pointer types.

Add UNUSED_FUNCTION_WITH_RETURN_TYPE to workaround this limitation.
2021-09-06 18:58:46 +10:00
81978594a8 Fix tests broken by rB58632a7f3c0f1be6.
Commits breaking RNA API should always run all tests, and do text search
in python code base to ensure everything is updated as needed.
2021-09-06 10:56:02 +02:00
b4c9f88cbe Fix thumbnail screenshot error in 58632a7f3c
Scaling didn't clamp above zero, see T89868.
2021-09-06 17:03:45 +10:00
3e44592cb9 Cleanup: comment unused functions 2021-09-06 15:51:53 +10:00
58632a7f3c UI: Blend Preview Thumbnails Showing Workspace
This adds an option to use a capture of the entire main window as the
blend file preview thumbnail.

See D10492 for details and examples.

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

Reviewed by Campbell Barton
2021-09-05 21:05:50 -07:00
91bca410c0 Cleanup: clang-format 2021-09-05 23:25:36 -04:00
bf0ac711fd UI: Increase Size of Blend File Thumbnails
Increase effective resolution of blend preview images from 128x128 to
256x256 for versions saved in the file system thumbnail cache.

See D10491 for details and examples.

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

Reviewed by Campbell Barton
2021-09-05 19:55:50 -07:00
Aaron Carlisle
4ddad5a7ee UI: Split Output Properties Dimensions panel
I remember when we originally decided on the Dimensions panel,
one of the reasons we combined time and image size properties in the same panel,
was simply because the 2.49 and previous UIs used fixed-size panels,
so we often put two categories of properties inside a panel, using two columns.

Now that we no longer do this, we could clarify and simplify some panels
by splitting them, such as the Output > Dimensions panel

{F6753690}

Reviewed By: brecht, pablovazquez

Differential Revision: https://developer.blender.org/D4440
2021-09-05 21:27:49 -04:00
Aaron Carlisle
d10ea97053 Compositor: New Posterize Node
The posterize node limits the number of colors per channel.
This is useful to generate masks or to generate stylized images

Both the tiled and full-frame implementation are included in this patch

{F10314012}

Reviewed By: manzanilla, jbakker

Differential Revision: https://developer.blender.org/D12304
2021-09-05 15:24:35 -04:00
b7718bbdf5 Cleanup: improve code clarity
Addresses D12341 review.
2021-09-05 14:25:14 +02:00
079bd11556 Fix T91143: Gpencil Set Vertex Color not using Linear
The color was not converted to Linear from Brush color.
2021-09-04 18:28:54 +02:00
b225a7c470 Compositor: Merge equal operations
Some operations can take a lot of time to execute and
any duplication should be avoided.

This patch implements a compile step that detects
operations with the same type, inputs and parameters that
produce the same result and merge them. Now operations
can generate a hash that represents their output result. They only
need to implement `hash_output_params` and hash any parameter
that affects the output result.

Reviewed By: jbakker

Differential Revision: https://developer.blender.org/D12341
2021-09-04 17:09:59 +02:00
d84c79a218 Compositor: Full frame vector nodes
Adds full frame implementation to Map Range, Map Value, Normal and
Normalize nodes. The other nodes in "Vector" sub-menu are submitted
separately.

Part of T88150.

Reviewed By: jbakker

Differential Revision: https://developer.blender.org/D12233
2021-09-04 17:06:01 +02:00
9d7cb5c4a1 Compositor: Full frame filter nodes
Adds full frame implementation to Anti-Aliasing, Defocus, Denoise,
Despeckle, Dilate/Erode, Directional Blur, Filter, Inpaint and
Vector Blur nodes. The other nodes in "Filter" sub-menu are
submitted separately.

Part of T88150.

Reviewed By: jbakker

Differential Revision: https://developer.blender.org/D12219
2021-09-04 17:05:58 +02:00
9290b41381 Python: Allow Area Close via Scripting
Screen area maintenance "Close" function allowed to be scripted.

See D12307 for usage example.

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

Reviewed by Campbell Barton
2021-09-04 08:00:22 -07:00
Henrik Dick
54b72fe9ff GPencil: Fix Noise Modifier Randomize Panel disabled
Fix regression introduced in rB34b213d60472

Reviewed By: antoniov

Differential Revision: https://developer.blender.org/D12398
2021-09-04 16:03:15 +02:00
Henrik Dick
c23b6596b9 GPencil: Fix subdivision modifier disabled on strokes with 2 points
Fixes the regression introduces in rB29f3af952725 . The subdivision modifier used to work on two point strokes with simple mode but not with catmul clark. Now it will work with simple mode and in case of catmull clark mode it will still use simple mode on these strokes.

Differential Revision: https://developer.blender.org/D12397
2021-09-04 15:41:43 +02:00
Mikkel Gjoel
863d806526 BMesh: optimize edge & face group calculation
This changes the search for unprocessed faces to only search
from the previously found face. Local testing on 1.5 million
triangle meshes gives a 75x speedup
(of the code affected, which is the first half of the work).

The former code would traverse all faces of a mesh until a face was
found that had not been processed. This ended up being slow mainly
because it had to load face-data to determine the state of the flag.
Secondarily, the way it iterated and marked the mesh, it would end up
traversing all previously processed faces to find and unprocessed one.

The same optimization has been made for edge-group calculation.

Reviewed By: campbellbarton

Ref D12379
2021-09-04 23:07:45 +10:00
e6194e7357 RNA: support extracting names from paths without allocating memory
Support extracting identifiers RNA paths into fixed size buffer
since the maximum size of the identifier is known all cases.

- Add BLI_str_unescape_ex to support limiting the destination buffer.
- Add BLI_str_quoted_substr to copy values into a fixed size buffer.
2021-09-04 16:59:54 +10:00
716682365c Fix T91119: Curve to mesh node inverted face normals
Previously I thought I fixed this by reversing the face corner indices
in quads created by the curve to mesh node. But then we fixed a problem
with the transforms used in that node by inverting one of their
components, so the required direction also reversed. This commit
reverts rBcf28398471c84 and reverses the default direction of the
quadrilateral primitive so it's the same as the others.

Tests will be updated.
2021-09-03 16:49:47 -05:00
4fb7217043 UDIM: Show the UV grid even when images are loaded
Allow the UDIM grid to be shown and adjusted when there are images
loaded in UV edit mode. Right now the grid feature disappears once an
image is loaded and many have found this to be confusing.

Based on community and artist feedback, there was support to change this
behavior[1]

This patch does the following:
- Allows the grid to be shown even when images are present
- The max allowable dimensions for the grid has been increased from
10x10 to 10x100 to match the underlying maximum UDIM range that blender
supports

Note: This should not affect other Image editor modes like Paint/Mask or
the Render Result viewer etc. Future work in this area is currently
documented in a dedicated design task[2]

[1] https://devtalk.blender.org/t/the-udim-tile-grid-design-and-feedback-thread/20136
[2] https://developer.blender.org/T90913

Differential Revision: https://developer.blender.org/D11860
2021-09-03 13:03:28 -07:00
235655ee0d Improve message in ob_parbone() about the missing Parent Bone
- lower to warning (might be debatable, but this is not really
malfunctioning and e.g. constraints/modifiers dont spit out errors if
targets are not specified)
- clarify _what_ of the two actualy does not exist

ref. T91101

Maniphest Tasks: T91101

Differential Revision: https://developer.blender.org/D12389
2021-09-03 17:16:42 +02:00
a45dd52cf0 Depsgraph: skip parentbone relation if bone prop is empty
Clearing the Parent Bone field in relations would result in something
like this:

```
add_relation(Bone Parent) - Could not find op_from
(ComponentKey(OBArmature, BONE))
add_relation(Bone Parent) - Failed, but op_to (ComponentKey(OBEmpty,
TRANSFORM)) was ok
ERROR (bke.object): /source/blender/blenkernel/intern\object.c:3330
ob_parbone: Object Empty with Bone parent: bone  doesn't exist
```

Now skip creation of a depsgraph relation if the Parent Bone field is
empty (since this would be invalid anyways).

ref. T91101

Maniphest Tasks: T91101

Differential Revision: https://developer.blender.org/D12389
2021-09-03 17:15:05 +02:00
Leon Leno
ac97893dfc Fix T88411: Draw frame node text when label is empty
This patch fixes the issue described in T88411, that the text in frame nodes is only shown, when the node has a label. This has been caused by rB8f04ddbbc626, because `node_draw_frame_label` not only draws the label, but also all the other text. Therefore skipping it, when the label is empty, also skips drawing the other text.
This is fixed by moving the check for the empty label into `node_frame_draw_label`.

**Patch:** Frame nodes show text despite not having a label.
{F10286204, size = full}

**Same setup in master:**
{F10128099, size = full}

**Test file**
{F10128102}

Reviewed By: #user_interface, pablovazquez

Maniphest Tasks: T88411

Differential Revision: https://developer.blender.org/D11315
2021-09-03 16:18:40 +02:00
ae334532cf GPencil: Smooth thickness when joining strokes
When joining two strokes in paint mode using the auto merge option, the join was very hard if the thickness was too different.

This patch adds a smooth to the join in order to get better transition.

Also fixed the problem to join existing strokes very far from actual stroke.

Some cleanup and rename of old code is included in order to make code more readable.

Reviewed By: pepeland

Differential Revision: https://developer.blender.org/D12362
2021-09-03 15:24:13 +02:00
f9ccd26b03 Fix T87768: .path_resolve fails when requested property is None.
Add a version of RNA_path_resolve_full that returns true
when the path resolves to a NULL RNA pointer.
2021-09-03 21:58:52 +10:00
0950cfd9d5 PyAPI: add read-only 'is_valid' attribute to mathutils types
There was no convenient way to check if the owner
of a mathutils type was valid.

Added to support issue reported in T91111.
2021-09-03 21:21:44 +10:00
f530b43550 Fix T91159: GPencil Smooth brush is using Affect Pressure but not used
The parameter wa sin the UI but was not used because it was replaced by Use Thickness.
2021-09-03 12:42:18 +02:00
d97fd305a0 RNA: minor optimize for token extraction of RNA paths
- Split rna_path_token in two,
  extracting bracket handling into it's own function.

- Only handle escape characters for quoted tokens.
  Numbers were copied using BLI_str_unescape which is unnecessary.

- Extract text without without quotes,
  use a return argument so the caller can tell if the token was quoted.
  This avoids having to strip the tokens quotes afterwards.
2021-09-03 20:35:46 +10:00
671640b4c7 Cleanup: use bool for RNA path token extraction 2021-09-03 19:42:54 +10:00
Rajesh Advani
684500837d Cleanup: convert function nodes socket list to use new API
The new API was introduced in rB1e69a25043120cc8dddc3f58622eb50e1443def1.

Differential Revision: https://developer.blender.org/D12380
2021-09-03 10:45:48 +02:00
4a3243f311 Docs: add note to skip_fcurve_selected_data sequence strip check
Without an explanation the sequencer logic looked wrong since
other selection checks don't skip data that can't be found.
2021-09-03 15:15:45 +10:00
6fc92b296f GPencil: Change default Scale Thickness to True in 2D template
This parameter is more logic as true because is better scale thickness when the size of the stroke changes.

Reviewed by: @mendio @pepeland
2021-09-02 16:26:13 +02:00
8849bed671 Revert "PyAPI: GPU Shader: add 'state' parameter to uniform sampler"
This reverts commit 2aad8fc7bc.

It was a commit without proper review.

A better API needs to be discussed.
2021-09-02 10:19:58 -03:00
546314fc96 Build utils: make_update: Add option to choose SVN branch.
Needed for studio sprite-fright frozen branch.

Also do not overwrite branch for git sub-modules when it is defined, and
fallback to `master` branch in case specified branch is not found in a
specific sub-repository.
2021-09-02 14:56:46 +02:00
799a2b07ad Fix possible missing render result with update_result
Need to ensure render result's pixels are allocated prior to merge.

Differential Revision: https://developer.blender.org/D12371
2021-09-02 09:28:42 +02:00
a8739ae6c2 Fix regression in recent change 0708733c46
Adding a mirror modifier in edit-mode crashed.

Freeing meshes that hold a shallow copy happens in multiple places
while calculating modifiers, making it impractical to clear the
edit-mode pointer before freeing the mesh (as done in
BKE_editmesh_free_derived_caches).

Add a struct member to the edit-mesh struct so evaluated copies
don't free the edit-mesh contents.
2021-09-02 16:12:24 +10:00
a2f3aca647 Cleanup: remove redundant edit-mesh memory allocation
This memory was only duplicated to satisfy mesh_data_free
which was incorrectly freeing the pointer (but nothing else).
2021-09-02 15:30:54 +10:00
19e1b5c1fd Fix T90972: Crash calling Mesh.clear_geometry in edit-mode
No longer free the edit-mesh pointer while in edit-mode since this
isn't reliable to keep the object in edit-mode while freeing it's
edit-mesh data.

Users who want to exit edit-mode should do so explicitly.

Caused by 6d2f9b1dfa.
2021-09-02 15:30:54 +10:00
0708733c46 Fix T91123: Freeing meshes in edit-mode leaks memory
Freeing the edit-mesh pointer wasn't free the edit-mesh data it's self.

Unlinking from the outliner or through the Python API leaked memory.

This didn't often cause leaks in practice since ED_editors_exit
exits edit-mode for all objects.

Now freeing mesh data frees the edit-mode data as well,
this matches the behavior of other object types that support edit-mode.
2021-09-02 15:30:54 +10:00
809b33b69a Docs: improve the error when undo poll fails
Calling undo in from Python background-mode would raise an exception
without any information about how to initialize undo.
2021-09-02 15:30:54 +10:00
ff5733ef2f Merge branch 'master' into xr-controller-support 2021-09-02 13:39:59 +09:00
c996926c05 Remove XrSessionState.reset_navigation() RNA func
Function was unnecessary since XrSessionState.reset_to_base_pose()
will also reset navigation deltas.
2021-09-02 13:27:55 +09:00
Johnny Matthews
0ccbf50694 Cleanup: Convert geometry nodes socket list to use new API
The new API introduced in rB1e69a25043120c provides a shorted, more
flexibly way to declare node socket inputs and outputs. This commit
updates all geometry nodes to use the `NodeSocketBuilder` API, except
the four nodes that need `SOCK_HIDE_VALUE` or `SOCK_MULTI_INPUT`.

Differential Revisions: D12377, D12376, D12374, D12373, D12372
2021-09-01 22:53:52 -05:00
4170668776 Cleanup: Grammar 2021-09-01 22:22:35 -05:00
f77de678d8 EditMesh: recalculate normals after running rip
Failure to calculate normals caused an assertion since face
tessellation was being calculated with invalid normals.

In practice the rip-drag action would recalculate normals anyway,
however mesh tessellation should always be performed with valid normals.
2021-09-02 11:45:55 +10:00
011d3a95e0 Cleanup: de-duplicate logic in bpy keyframing logic 2021-09-02 11:41:01 +10:00
6c177838f3 Cleanup: remove redundant alloc argument to SEQ_editing_get
Callers that require lazy initialization can use SEQ_editing_ensure.
2021-09-02 11:29:32 +10:00
baee000001 Fix T90798: calc_loop_triangles is not updated after joining objects 2021-09-02 11:08:38 +10:00
f8dd0d0dba Cleanup: spelling in comments 2021-09-02 11:08:38 +10:00
42546db490 Fix T91054: Editing group custom property gives error
This commit fixes the custom property edit operator for the the case of
editing group properties. Currently this isn't supported very well, the
data is converted to a string, but the operator shouldn't fail anyway.

This allows editing properties created like this:
C.object['abuse'] = {'parent' : ['child1', 'child2']}

These changes reflect some issues with the design of the operator.
Requiring guessing the type of the data does not work well at all, and
makes code more complicated. In the future this operator can be updated
to use a type drop-down.

Differential Revision: https://developer.blender.org/D12364
2021-09-01 11:47:59 -05:00
99c981fd06 Cleanup: Remove redundant property UI data clear
Since the UI data is now stored in the property, and the property is
deleted on the next line, this doesn't need to be called separately.
2021-09-01 11:46:21 -05:00
083a8921ec Fix strict warning about discarding const qualifier
Solved by using const qualifier for arguments which aren't mutable
in PyC functions.

Differential Revision: https://developer.blender.org/D12369
2021-09-01 17:00:08 +02:00
f62eb8ac16 BPY-Docs: Add missing file context members documentation
Context members of the file space would not be shown in the context API
docs.
2021-09-01 16:28:44 +02:00
2aad8fc7bc PyAPI: GPU Shader: add 'state' parameter to uniform sampler
Now you can choose the state of texture (as a filter and repetition) to
render it.

This is important as the original state is very limited.
2021-09-01 10:39:14 -03:00
7ec839adfa File Browser/BPY: Expose list of selected files in context
Since recently it's possible to query the active file (as object, not
just the name), but it's quite useful for scripting to have access to
all selected files.
This introduces `bpy.context.selected_files`, returning a list of file
objects representing files in the File Browser.
2021-09-01 15:13:18 +02:00
79281336c0 File Browser/BPY: Expose relative path of a file via BPY
There were requests to be able to track the file selection in the File
Browser. Just using the file name for that wouldn't if the file browser
has the recursive display enabled. File names could be duplicated then.
So expose the entire path relative to the currently displayed directory.
2021-09-01 15:12:50 +02:00
8355e3fc77 Unittest: Extend and basic linking tests and add basic append tests.
We could check many more things still, but this should already cover
most basic common cases.
2021-09-01 12:51:07 +02:00
e04631f44a Cleanup: clang-tidy utfconv 2021-09-01 17:13:33 +10:00
93c6b12df5 Cleanup: use doxygen sections in py_capi_rna.c 2021-09-01 17:00:47 +10:00
0c5f6f9fa7 Cleanup: Better names for eDRWColorManagement.
Names describe better what will be applied. Previous names were
extracted from the original code, that weren't accurately named.
2021-09-01 08:58:06 +02:00
18a4e5d561 Cleanup: Use nullptr. 2021-09-01 08:54:18 +02:00
89fa9aada5 Cleanup: use "pyrna_enum_*" prefix for RNA utility functions 2021-09-01 16:50:48 +10:00
1730829592 Cleanup: move RNA utility functions into a generic module
Avoid having to include bpy_rna.h for enum utility functions,
recently added to idprop_py_ui_api.c.
2021-09-01 16:33:42 +10:00
5352b33598 BLI_string: return string length from BLI_string_flip_side_name
Useful for callers that need the string length.
2021-09-01 15:24:01 +10:00
2914ec571e Fix errors pasting flipped names in the action editor
Use BLI_str_quoted_substr_range instead of in-line
quote extraction to resolve:

- Bone names containing quotes caused flip to fail.
- Missing NULL check if a matching quote could not be found.
2021-09-01 15:23:59 +10:00
f1cdd49a4e BLI_string: add BLI_str_quoted_substr_range
This is a similar funciton to BLI_str_quoted_substrN
that extracts the range of the quoted string
instead of allocating a new string un-escaped string.
2021-09-01 15:23:58 +10:00
90dac47717 Cleanup: remove redundant strstr calls
Rely on BLI_str_quoted_substrN to detect if the prefix exists since
this function exists early there is no need to check before calling.
2021-09-01 15:23:56 +10:00
838b6ec48a Fix: Incorrect versioning for float IDProperty UI data
The code put the value from the "min" property into the "max"
value. This would have crashed if min was null and max wasn't.
2021-08-31 12:17:05 -05:00
60fba8202c Fix T91088: Assigning custom property value in python resets UI data
Assigning a new value to an IDProperty with the Python API would free
the entire contents of the existing property, which unfortunately
happened to include the UI data. The fix is to extract the UI data from
the existing property before freeing its contents. An alternative
would be adding another argument to `IDP_FreePropertyContent_ex`, but
this solution is clearer and doesn't increase complexity elsewhere.
2021-08-31 11:49:12 -05:00
cfc674408e Fix T91084: Missing versioning for object pose bone property UI data
Objects also have a list of "bone" pose channels embedded directly.
These properties are user visible, so their UI data should be versioned.
2021-08-31 11:12:07 -05:00
596f1878b6 Cleanup: Reduce variable scope 2021-08-31 10:19:31 -05:00
37943b00f2 Fix: Output int for precision in UI data as_dict method
This is stored internally and used as an integer, so there is no need
to convert it to a float for "as_dict". This was just an oversight.
2021-08-31 09:05:03 -05:00
99b1e8428d Cleanup: pass value by ref in draw_color_management 2021-08-31 15:45:05 +02:00
b18122451f Fix T88433: no greaspencil depsgraph evaluation with certain drivers
When the same stroke was used as a driver variable, this could make this
stroke already tagged as built in the course of building driver
variables (via `build_gpencil`), but then important stuff from
`build_object_data_geometry_datablock` could be missed later on (because
both of these funtions use `checkIsBuiltAndTag`). Most importantly,
setting up operations such as GEOMETRY_EVAL would be skipped entirely.

`build_object_data_geometry_datablock` seems to cover greasepencil just
fine (does the same as `build_gpencil` and more). Proposed solution is to
remove `build_gpencil` entirely. In `build_id` it would then also call
`build_object_data_geometry_datablock` for `ID_GD` IDs. Now the covered
types that _call_ `build_object_data_geometry_datablock` match exactly
to what is covered _inside_ `build_object_data_geometry_datablock`.

Think this "duplication" of functionality was just overseen in
rB66da2f537ae8 [`build_gpencil` existed long before and said commit made
greasepencil a real object with geometry and such].

thx @JacquesLucke for additional input!

Maniphest Tasks: T88433

Differential Revision: https://developer.blender.org/D12324
2021-08-31 15:20:02 +02:00
84f826ff23 Fix T90989: Annotation opacity must not be animatable
All props of annotations are not animatable by design and opacity must be equal.

As the opacity is reused by gpencil objects, a new prop has been created in order to use different props for annotations and GP objects.
2021-08-31 14:59:55 +02:00
1be598ba68 Cleanup: DRW color management seperated in multiple functions. 2021-08-31 14:12:14 +02:00
6931a6f3bd Cleanup: Moved DRW_vieport_colormanagement_set to draw_color_management. 2021-08-31 13:26:13 +02:00
63dc286b01 Cleanup: Added const keywork to GPU_viewport_colorspace_set. 2021-08-31 13:24:42 +02:00
a18d88213f Cleanup: Converted draw_color_management to CPP. 2021-08-31 13:24:42 +02:00
3abf56db27 Cleanup: Draw Manager remove do_color_management from drawing context.
The do_color_management option was set, but never read.
2021-08-31 13:24:42 +02:00
9ab31b53b7 Cleanup: Remove unused DRW_state_do_color_management.
Function wasn't used since we migrated to the new color management
pipeline. It is also not expected it would be needed in the current
design.
2021-08-31 13:24:42 +02:00
a7ee49d065 Fix crash in recent commit.
Crash introduced by {rB8e00db42961297facd521139762fe8c42042fc5c}, fixed
with a null check. Object can be null.
2021-08-31 13:14:26 +02:00
b0cb0a7854 Texture Paint: sync changing active texture in the Node Editor to the
Image Editor

When changing to another texture paint slot, the texture displayed in
the viewport changes accordingly (as well as the image displayed
in the Image Editor).

When changing the active texture in the Node Editor though, only the
texture displayed in the viewport changes.

This was mentioned in T88788 and I am not 100% sure this is desired in
all scenarios (or at all), it should be seen in tandem of D11497. This
change makes it so that the Image Editor changes to the image we changed
to in the Node Editor (keeping them in sync).

If this is not desired in all cases, this could be made an option.

ref T88788
ref D11496
ref D11497

Maniphest Tasks: T88788

Differential Revision: https://developer.blender.org/D11498
2021-08-31 12:45:39 +02:00
3b2a01edf6 Texture Paint: sync changing active texture in the node editor to the
active paint slot

When changing to another texture paint slot, the texture displayed in
the viewport changes accordingly (as well as the image displayed
in the Image Editor).

When changing the active texture in the Node Editor though, only the
texture displayed in the viewport changes.

This _can_ be confusing because you can end up painting on a texture
that you are not looking at in the viewport (so you dont have any
feedback whatsoever). Not 100% sure this is desired in all scenarios,
but this change makes it so that the active paint slot changes to the
one that uses the texture we chaged to in the Node Editor (keeping them
in sync).

If this is not desired in all cases, this could be made an option.

ref T88788
ref D11496

Maniphest Tasks: T88788

Differential Revision: https://developer.blender.org/D11497
2021-08-31 12:29:14 +02:00
d8b445e728 Fix missing render result when using region render
Caused by lazy allocation of passes.
2021-08-31 12:12:34 +02:00
af7233368d Fix T91060: GPencil Time Offset Modifier breaks evaluation time
Caused by {rBf3bf87e5887c}.

When using a GPencil Time Offset Modifier, the bGPDlayer>actframe can be
NULL. This can be determined though, but above optimization commit
skipped getting the active frame in this case entirely (with the
intention to only get it if framenumbers did not match).

Now also call BKE_gpencil_layer_frame_get() if actframe is NULL in order
to fetch a valid one if present.

Maniphest Tasks: T91060

Differential Revision: https://developer.blender.org/D12355
2021-08-31 11:55:16 +02:00
f6d133e2d2 Fix possible wrongly highlighted tiles
Run into it when was re-working tiles in the Cycles X project.
Make sure the storage of highlighted tiles is emptied when the
render is finished or cancelled).

The error is only possible to happen if the engine did not do
something correct, but is still good to deal with such situations
more gracefully.
2021-08-31 11:05:57 +02:00
593621fdfb Merge branch 'master' into xr-controller-support 2021-08-31 18:05:42 +09:00
07a92c616f XR: Add reset navigation operator
Resets XR navigation deltas relative to session base pose. Primarily
useful for undoing elevation/scale changes. Will be added to the
default VR actions.
2021-08-31 17:58:22 +09:00
99ce2f3e4d XR: Replace invoke/modal_3d for XR operators
Special 3D-to-2D handling (as invoke/modal_3d is used for) is not
necessary for regular XR operators, so they can use the normal
invoke/modal callbacks.
2021-08-31 17:48:29 +09:00
c8c782fbf4 Cleanup: remove unused struct member, null checks 2021-08-31 17:42:55 +09:00
f4eacad48f Fix AssetBrowser UI errors
Steps to reproduce:
- enable Extended Asset Browser
- open a regular File Browser

gives:
"rna_uiItemR: property not found: FileSelectParams.asset_category"

Now do proper poll.

Differential Revision: https://developer.blender.org/D12350
2021-08-31 10:41:12 +02:00
1f0d63b9a1 Cleanup: remove unnecessary obedit argument from ED_space_image_set
This was left over from when changing the image set the faces texture.
2021-08-31 18:29:09 +10:00
8e00db4296 Fix: Weightpaint overlay not visible when display type wire/boundbox.
When the object display type was set to wireframe or boundbox the depth
buffer wasn't updated resulting in not visible weightpaint overlay.

Thanks to Demeter Dzadik for mentioning it.
2021-08-31 10:02:45 +02:00
fa4a35d4c4 Measure tool: Add support to restrict dimension to one axis
Support axis constraints for the measure tool.

Press X, Y or Z to restrict the dimension to that axis,
it's also possible to toggle between orientations matching transform.

Reviewed By: campbellbarton

Ref D10872
2021-08-31 17:21:11 +10:00
fa4f9292e1 Transform: avoid passing the context to extended orientation functions
This makes it possible to calculate orientation from functions
that don't have the context.
2021-08-31 17:02:47 +10:00
d718d6b449 Cleanup: Use C style comments for descriptive text 2021-08-31 14:33:57 +10:00
29590eec6e Fix T91054: List of strings custom property cannot be edited
This commit fixes editing the value of a list of strings custom property
with the "Custom Property Edit" operator. This sort of custom property
isn't very well supported in general, but editing the values should
work properly anyway.

Differential Revision: https://developer.blender.org/D12348
2021-08-30 22:21:11 -05:00
c758b87c5e Cleanup: add CTX_data_pointer_set_ptr & CTX_data_list_add_ptr
Many callers expanded a PointerRNA argument,
so add a version of these functions that takes a PointerRNA.
2021-08-31 13:00:31 +10:00
ea575744b8 Fix assigning shortcuts that include array indices
Assigning a shortcut to bone layers for example,
raised a Python exception when used.
2021-08-31 12:30:45 +10:00
63a5f723d6 Fix T90723: User menus & shortcuts fails for sequences, bones & NLA
Use context members instead of not working well or failing due to:

- Missing "path" functions (in the case of edit-bones).

- Paths containing names (in the case of sequence-strips or pose-bones).

  While technically correct it's not useful for shortcuts or
  menu items to lookup data by name.
2021-08-31 12:07:33 +10:00
3e4d720ae4 Fix logical error resolving RNA paths
Only append RNA_path_from_ID_to_struct to context attributes if those
paths resolve to ID types.

Also simplify creating RNA paths by adding utility functions:

- WM_context_path_resolve_property_full
- WM_context_path_resolve_full

Part of fix for T90723.
2021-08-31 12:06:47 +10:00
aabe6e3b45 Context: add "active_nla_track" & "active_nla_strip" context members
Selection was already accessible but not active.

Add utility functions:

- ANIM_nla_context_track to access the active track,
  following the convention of ANIM_nla_context_strip.

- ANIM_nla_context_*_ptr versions of these functions,
  needed to for creating context members to access the ID pointer.

Part of fix for T90723.
2021-08-31 12:06:47 +10:00
65739ded54 Fix 'WM_window_find_under_cursor'
This function was not working if the window is partially out of screen space.
2021-08-30 22:46:10 -03:00
b08ab49cce Fix T90988: Incorrect speed effect strip math
Math implemented in 929d7597b3 was incorrect, but also inconsistent
with previous behavior.

`SEQ_SPEED_STRETCH` should change length only when right handle is
moved. This is now documented in code.
2021-08-31 03:12:00 +02:00
bd67bf4d10 Fix VSE move_to_meta function moving meta strip
API function `move_to_meta` should move strips without changing context
data like `MetaStack` that tells UI which meta strip should be
displayed and operated upon.

`SEQ_time_update_sequence` relied on `MetaStack` to update meta strip
content length. Instead of changing function `SEQ_time_update_sequence`,
use function `SEQ_time_update_meta_strip_range` directly. This is
because caller would have to be aware of parent meta strip that needs
update anyway.
2021-08-31 00:27:19 +02:00
1541fbb4a0 PyDoc: Fix compliation warning 2021-08-30 18:26:07 -04:00
d374ff5b8f PyDoc: Fix compilation after recent contex_member addition
Fixes missing change needed for rB0a8f53a7b847d9c8bdcefc025de70fd2608012b7
2021-08-30 18:17:11 -04:00
fbcb9c5e3f Cleanup: sequencer operators
- Use name 'strip' instead of 's'
- Assign a variable to 'scene' instead of accessing from context.
- Avoid temporary variable for swapping values.
2021-08-31 07:39:03 +10:00
c84d1ad3db Cleanup: use new active_sequence_strip context attribute 2021-08-31 07:27:55 +10:00
0a8f53a7b8 Context: add "active_sequence_strip" context member
This is an alternative to context.scene.sequence_editor.active_strip
which could be verbose, especially with additional None checks.

Part of fix for T90723, extracted from D12297.
2021-08-31 07:13:31 +10:00
b7cb7b78a8 Docs: GPU Shader: improvements
Changes:
- line break
- enum highlighting
- better description
2021-08-30 17:12:31 -03:00
af3f744b41 Fix: add virtual destructor to base class 2021-08-30 18:26:55 +02:00
171c3bd2b0 Cleanup: clang-tidy
readability-named-parameter
2021-08-30 17:30:04 +02:00
1e69a25043 Nodes: add more flexible method to declare sockets of a node
Previously, built-in nodes had to implement "socket templates"
(`bNodeSocketTemplate`) to tell Blender which sockets they have.
It was nice that this was declarative, but this approach was way
too rigid and was cumbersome to use in many cases.

This commit starts to move us away from this rigid structure
by letting nodes implement a function that declares the sockets
the node has. Right now this is used as a direct replacement
of the "socket template" approach to keep the refactor smaller.
It's just a bit easier to read and write.

In the future we want to support more complex features like
dynamic numbers of sockets and type inferencing. Those features
will be easier to build on this new approach.

This new approach can live side by side with `bNodeSocketTemplate`
for a while. That makes it easier to update nodes one by one.

Note: In `bNodeSocketTemplate` socket identifiers were made
unique automatically. In this new approach, one has to specify
unique identifiers manually (unless the name is unique already).

Differential Revision: https://developer.blender.org/D12335
2021-08-30 17:23:05 +02:00
e8684eff30 Fix T91056: GPencil merge layers doesn't preseve Keyframe type.
Now if the frame does not exist in destination layer, the frame type of merge layer is used. 

For existing frames in destination layer, the existing type is not changed.
2021-08-30 17:04:02 +02:00
Henrik Dick
e76f04c870 Fix T90742: Gpencil ghost point on selection
Reviewed By: fclem, filedescriptor

Maniphest Tasks: T90742

Differential Revision: https://developer.blender.org/D12259
2021-08-30 15:17:14 +02:00
9ad56627cf Docs: retitle 'GPU Shader Module' to 'GPU Module'
We already have a module for GPU Shader (`gpu.shader`).

So, remove the name "Shader" from the title to avoid confusion.
2021-08-30 09:21:38 -03:00
Erik Abrahamsson
a71d2b2601 Geometry Nodes: Curve Fill Node
This node takes a curve geometry input and creates a filled mesh at Z=0
using a constrained Delaunay triangulation algorithm. Because of the
choice of algorithm, the results should be higher quality than the
filling for 2D curve objects.

This commit adds an initial fairly simple version of the node, but more
features may be added in the future, like transferring attributes when
necessary, or an index attribute input to break up the calculations
into smaller chunks to improve performance.

Differential Revision: https://developer.blender.org/D11846
2021-08-29 23:27:35 -05:00
41eb33794c Cleanup: Add comment about suspicious O(n^3) loop 2021-08-29 22:12:53 -05:00
Rajesh Advani
b44406f963 Geometry Nodes: Enhance the cube mesh primitive as a cuboid
This mesh primitive enhances the Cube mesh primitive and allows the
creation of a cuboid with a configurable size and number of vertices
in all 3 directions. The Cube primitive is now similar to the Grid
primitive except that it works in 3 dimensions.

Previously it was possible to create a cube and scale it arbitrarily
along each axis. You could also subdivide the mesh, but the number of
subdivisions was equal along all axes. This meant that making the basic
frame for something like modular buildings wasn't trivial.

Inspired by tutorials and files for modular building creation.

The cuboid is created as a `Mesh` so that large meshes with millions of
faces are created quickly. Though edge calculation could be faster if
implemented here, edges are calculated using `BKE_mesh_calc_edges`
to reduce complexity, and in hopes that they may be calculated lazily
for `Mesh` in the future like vertex normals.

See the differential revision for more information.

Differential Revision: https://developer.blender.org/D11810
2021-08-29 22:08:57 -05:00
Mattias Fredriksson
b42354672e Geometry Nodes: Allow for one vertex in grid node
This commit allows setting the number of vertices in either direction
to 1, so that the primitive grid node will create a line instead of a
grid. To avoid confusion the soft limits of the input sockets are not
changed, so this is purely an increase in flexibility for when it is
helpful.

Differential Revision: https://developer.blender.org/D11772
2021-08-29 16:39:42 -05:00
Mattias Fredriksson
084180874c Fix: Circle mesh primitive outer edges do not render
The outer edges created om the circle mesh primitive node
weren't marked with the flags that makes them show in wireframe
mode.

Differential Revision: https://developer.blender.org/D12152
2021-08-29 16:30:17 -05:00
2f7258d618 Fix BLI_strncpy_wchar_from_utf8 result on Windows
This function was documented to return the length but returned an
error value for WIN32. While this doesn't cause any bugs at the moment,
it could cause problems in the future.

Oversight in 5496d8cd36.
2021-08-29 12:11:09 +10:00
4256eeeec4 UI: Timecodes: Rename "No TC in use" to "None"
Differential Revision: https://developer.blender.org/D12296
2021-08-28 16:38:08 -04:00
457302b67b BLI_string_utf8: add buffer size arg to BLI_str_utf8_from_unicode
Besides helping to avoid buffer overflow errors this reduces complexity
of BLI_str_utf32_as_utf8 which needed a special loop for the last 6
characters to avoid writing past the buffer bounds.

Also add BLI_str_utf8_from_unicode_len which only returns the length.
2021-08-28 22:50:52 +10:00
079791dc30 Fix error scaling thumbnails to zero dimensions
Follow up to fix for T89868.
2021-08-28 21:33:06 +10:00
0b6be26126 BLF: remove checks for blend file relative paths
This was added in b24712a9ca
but is no longer needed as of efc129bc82.

Further, this wasn't reliable as it could fail on linked library data
which has a different base directory.

Assert when blend file relative paths are passed to BLF
(matching imbuf file loading).
2021-08-28 19:21:54 +10:00
eae4e22518 Cleanup: Remove redundant null check 2021-08-27 14:33:06 -05:00
276a862ebc Fix failing alembic test after IDProperty UI data refactor
The default float IDProperty min value rB8b9a3b94fc148d19 for when there
is no UI data was FLT_MIN instead of -FLT_MAX, which meant that animated
custom property values couldn't be less than zero unless they had their
UI data values edited previously.

That's a mistake I won't make again! Also change the int minimums from
-INT_MAX to INT_MIN to sanitize the whole situation.
2021-08-27 14:31:19 -05:00
400605c3a6 UI: Reduce Node Contents Jiggling When Moved
This patch just clamps and rounds node contents and socket locations
so they don't appear to jiggle around when you move them. This issue
happens because node sizing and positioning are in floats while text
content must be pixel-aligned.

See D11684 for more details and comparisons.

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

Reviewed by Julian Eisel
2021-08-27 11:25:30 -07:00
071007e0ef UI: Fix summary overlay wrong range and overlap in Dopesheet
The overlay was drawn twice on top of each other making it hard to see,
hard to theme, and making it more prominent in the wrong areas (before
frame 0, not even start frame). The comment in the code was also wrong
since it said "frame one" but it was 0.

Checked with the Animation module team that it's better to use start/end
frame range instead of frame 0.

There is a TODO note to de-duplicate this section eventually so I left it there.
This fix is currently done for Grease Pencil and Mask modes, but it should
also be fixed for the regular Dopesheet mode (in line 244 if anyone wants to do it).
2021-08-27 19:49:08 +02:00
8b9a3b94fc Refactor IDProperty UI data storage
The storage of IDProperty UI data (min, max, default value, etc) is
quite complicated. For every property, retrieving a single one of these
values involves three string lookups. First for the "_RNA_UI" group
property, then another for a group with the property's name, then for
the data value name. Not only is this inefficient, it's hard to reason
about, unintuitive, and not at all self-explanatory.

This commit replaces that system with a UI data struct directly in the
IDProperty. If it's not used, the only cost is of a NULL pointer. Beyond
storing the description, name, and RNA subtype, derived structs are used
to store type specific UI data like min and max.

Note that this means that addons using (abusing) the `_RNA_UI` custom
property will have to be changed. A few places in the addons repository
will be changed after this commit with D9919.

**Before**
Before, first the _RNA_UI subgroup is retrieved the _RNA_UI group,
then the subgroup for the original property, then specific UI data
is accessed like any other IDProperty.
```
prop = rna_idprop_ui_prop_get(idproperties_owner, "prop_name", create=True)
prop["min"] = 1.0
```

**After**
After, the `id_properties_ui` function for RNA structs returns a python
object specifically for managing an IDProperty's UI data.
```
ui_data = idproperties_owner.id_properties_ui("prop_name")
ui_data.update(min=1.0)
```
In addition to `update`, there are now other functions:
 - `as_dict`: Returns a dictionary of the property's UI data.
 - `clear`: Removes the property's UI data.
 - `update_from`: Copy UI data between properties,
   even if they have different owners.

Differential Revision: https://developer.blender.org/D9697
2021-08-27 08:27:24 -05:00
3f5e0f7d91 Fix crash sampling render result before any pixel was rendered
Caused by recent lazy render result passes allocation change.
2021-08-27 15:07:26 +02:00
57e8714b38 Fix shadowing in sequencer iterator
The __LINE__ was not properly expanded.
2021-08-27 14:44:12 +02:00
c88ba461cf Fix "toggle shading" op not updating VR view
Reason was that the notifier did not set the NS_VIEW3D_SHADING
subtype, which the VR view listens for for a shading update.

In the case of "toggle xray", a notifier was absent altogether.
2021-08-27 20:05:34 +09:00
59cd9c6da6 VSE: Transform overwrite mode
Add mode to overwrite strips on overlap instead of resolving overlap.

When overlap is created, 3 things can happen:
 - On partial overlap, handles of overlapped strip are moved
 - On complete overlap with smaller strip, overlapped strip is split
 - On complete overlap with larger strip, overlapped strip is removed

This mode can be enabled in header.

Reviewed By: fsiddi, mano-wii

Differential Revision: https://developer.blender.org/D11805
2021-08-27 12:59:46 +02:00
7f7370fa26 Cleanup: quiet maybe-used-uninitialized warning 2021-08-27 11:58:40 +02:00
6845aad1a2 Fix T90907: RNA pointers for material slots are not unique across IDs
Caused by {rB1a81d268a19f}.

This caused e.g. ALT-clicking the 'Link' button to not propagate to
other selected objects (same as the 'Copy To Selected' context menu
entry).

If these are not unique across IDs, checks in ui_selectcontext_begin()
or copy_to_selected_button() could fail.

Now offset by ID pointer.

thx @JacquesLucke for clarification on the POINTER_* macros (and why
not to use them)!

Maniphest Tasks: T90907

Differential Revision: https://developer.blender.org/D12321
2021-08-27 11:02:58 +02:00
7dba879829 Fix XR action map index initialization
This reverts 151eed752b. Originally thought it was necessary to
initialize selected/active indices to -1 to prevent out-of-bounds
list access, but this is not needed since null checks are already
performed after obtaining list members via BLI_findlink().

In addition, leaving indices zero-initialized facilitates use of the
Python API, for example when displaying action map information in a
UI list.
2021-08-27 17:16:35 +09:00
7652ee43ec Cleanup: clang-tidy 2021-08-27 17:29:05 +10:00
89dae554f9 Cleanup: utf8 stepping functions
Various changes to reduce risk of out of bounds errors in utf8 seeking.

- Remove BLI_str_prev_char_utf8
  This function could potentially scan past the beginning of a string.
  Use BLI_str_find_prev_char_utf8 instead which takes a limiting
  string start argument.

- Swap arguments for BLI_str_find_prev_char_utf8 so the stepping
  argument is first and the limiting argument is last.
  This matches BLI_str_find_next_char_utf8.

- Change behavior of these functions to return it the start or end
  pointers instead of NULL, which complicated use of these functions
  to calculate offsets.

  Callers that need to check if the limits were reached can compare
  the return value with the start/end pointers.

- Return 'const char *' from these functions
  so they don't remove const from the input arguments.
2021-08-27 17:02:53 +10:00
523bc981cf Fix loading packed fonts for sequencer strips 2021-08-27 13:11:36 +10:00
61f9274d07 Cleanup: use early return 2021-08-27 13:05:12 +10:00
efc129bc82 Fix sequencer font loading using an unexpected path
Reuse the existing font loading function which handles this case.
2021-08-27 13:01:19 +10:00
Henrik Dick
20ef771374 Modifier: smooth interpolation support
Add an option to the mask modifier to use the vertex weights to generate
smooth in between geometry, instead of just deleting non complete faces.

This can be used to make all sorts of smooth dissolve animations
directly with geometry, which are usually hacked together with shaders.
It also allows for implicit function plotting using geometry nodes and
boolean like operations on non manifold geometry with the proximity
modifier.

Reviewed By: campbellbarton

Ref D10979
2021-08-27 11:48:18 +10:00
8949eab27e Cleanup: warnings 2021-08-27 11:47:56 +10:00
2b64b4d90d Fix T90973: GPencil - Add buttons to move up and down vertex groups
These buttons were in Meshes but not for Grease Pencil. This patch add them in order to keep consistency.

Reviewed By: HooglyBoogly

Maniphest Tasks: T90973

Differential Revision: https://developer.blender.org/D12328
2021-08-26 22:00:24 +02:00
e5ed9991ea UI: Consistent Area Move Snapping Locations
Change Area Move snapping locations to even 12ths, rather than current
eights and thirds, so snap distances are consistent sizes. Also adds
snapping at minimum and maximum locations.

see D11938 for details and illustrations.

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

Reviewed by Hans Goudey
2021-08-26 10:52:18 -07:00
Germano Cavalcante
8e5b7ac6e2 Fix error in last commmit 2021-08-26 14:21:45 -03:00
583f694826 Fix T90817: Object Picker Doesn't Work on Second window
Solution similar to the one seen in {rBb94ab93dfb82}.

The idea is to find the window and region under the cursor to use in the
operator.

Reviewed By: brecht

Maniphest Tasks: T90817

Differential Revision: https://developer.blender.org/D12310
2021-08-26 14:13:19 -03:00
aadbdb8048 Cleanup: split eyedropper_color_sample_fl into more specific utilities
The window and region find utility can be used in other eyedropper
operators.
2021-08-26 14:12:21 -03:00
Germano Cavalcante
d7b0567f7c Cleanup: return window in 'WM_window_find_under_cursor'
This better matches other functions like `BKE_screen_find_area_xy`.
2021-08-26 13:49:04 -03:00
06a60fe9f7 PyAPI: GPU: expose clip distances
Now you can get a shader that uses Clip Planes and set the number of
Clip Distanes with `gpu.state.clip_distances_set(value)`.
2021-08-26 13:03:07 -03:00
edb95b3fcb Cleanup: Use ID_IS_LINKED instead of direct id.lib pointer check. 2021-08-26 15:01:14 +02:00
1bb2077250 Add locking fallback atomics implementation
Is used for platforms for which we do not have native implementation,
such as MIPS, for example.

It is possible to test locking implementation on local computer by
defining `ATOMIC_FORCE_USE_FALLBACK` in the atomic_ops_unix.h file.

Run full regression suit with the locking implementation on amd64
Linux platform and all tests passed.

Having non-optimal but working implementation for odd-ball platforms
seems to be a better choice than failing the build entirely.

Differential Revision: https://developer.blender.org/D12313
2021-08-26 14:36:59 +02:00
2419ffa183 Fix T90959: crash when hovering over empty data block socket 2021-08-26 14:35:10 +02:00
da17692a3d Cleanup: use BLI_UTF8_MAX define 2021-08-26 20:41:02 +10:00
1434ac3767 Cleanup: add ATTR_WARN_UNUSED_RESULT to BLI_string_utf8.h 2021-08-26 20:41:02 +10:00
0f1ef110a4 Merge branch 'master' into xr-controller-support 2021-08-26 19:29:20 +09:00
5fd158bb87 XR: Refactor motion capture objects
This refactors the feature of binding objects to controllers
and recording auto-keyframes, or "motion capture objects", by
providing a more complete API for managing objects and moving the
implementation out of wm_xr_session.c and into its own file
(wm_xr_mocap.c).

In addition, motion capture objects are now stored as a dynamic array
instead of a fixed array, which was previously hard-coded for
specific devices. Each entry in this dynamic array is uniquely
identified by an Object pointer and is mapped to a VR device via an
OpenXR user path. For example, an object can be bound to the headset
via "/user/head", and the left controller via "/user/hand/left".
2021-08-26 19:23:14 +09:00
c52db4c4cf Decouple highlighted tiles from RenderPart
Should be no visible change on user side.
Preparing for render parts removal as part of Cycles X project.

Differential Revision: https://developer.blender.org/D12317
2021-08-26 12:09:03 +02:00
21a24aa61e Fix view3d.toggle_shading() not updating VR view
Reason was that the WM notifier did not set the NS_VIEW3D_SHADING
subtype, which the VR view listens for for a shading update.

In the case of view3d.toggle_xray(), a notifier was absent
altogether.
2021-08-26 18:55:50 +09:00
c9a4c29589 Cleanup: remove unnecessary #ifdefs 2021-08-26 18:36:29 +09:00
ec66b3ef9b Fix issues with absolute time unit
I think there are the following issues with {rB5fa6cdb77a98}:
- if we introduce a PROP_UNIT_TIME_ABSOLUTE unit, shouldnt it be visible
to RNA as well?
- seems like a double entry sneaked into that commit?

This is in preparation to use this for render time limit in cycles-x.

ref. T90701

Maniphest Tasks: T90701

Differential Revision: https://developer.blender.org/D12315
2021-08-26 11:01:32 +02:00
1f2bf2fd73 Cleanup, quiet compile warnings 2021-08-26 10:36:04 +02:00
fe73778095 Cleanup: unused function from 082ddc9379 2021-08-26 16:10:24 +10:00
d3514cd6a7 ToolSystem: increase the inset tool size
The inset tool requires moving the cursor towards the center of the
selection, making it nearly impossible to use the inset tool
when the view was aligned with the vertical handle.

Use custom settings for VIEW3D_GGT_tool_generic_handle_free
to make it draw hollow, as large as the scale tool.

Resolves T87991.
2021-08-26 16:02:35 +10:00
082ddc9379 ToolSystem: support per-tool gizmo group properties
Also add gizmo group example to the tool-template.
2021-08-26 16:02:31 +10:00
f464cac55a Cleanup: redundant update calls adding objects
These update calls are already performed by
ED_object_add_type_with_obdata.
2021-08-26 13:53:15 +10:00
2fb57685e3 Fix "Text to Object" creating invisible object
Newly created objects would not become visible until
another action forced a depsgraph update.
2021-08-26 12:59:22 +10:00
efcac47155 Cleanup: soft CMake file lists 2021-08-26 12:41:26 +10:00
cec35060f5 Cleanup: sort struct blocks 2021-08-26 12:39:45 +10:00
4e16e8b671 Cleanup: warnings 2021-08-26 12:36:58 +10:00
84f048fda5 Cleanup: use C style comments for descriptive text 2021-08-26 12:36:58 +10:00
42032db1c2 Cleanup: remove deprecated flag use in collada 2021-08-26 12:36:58 +10:00
afcd06e1e1 Cleanup: spelling in comments 2021-08-26 12:36:58 +10:00
ff85ac3009 Cleanup: clang-format 2021-08-26 12:27:13 +10:00
e5a5a251d2 Fix T90915: outliner select behaves as if Ctrl is held
Error in 452cc01932
2021-08-26 11:37:22 +10:00
70fbdcb6bf Cleanup: Refactor proximity node to be more data type agnostic
Before, distances from each component were handled in the same loop,
making it more complicated to add support for more component types
in the future (and probably hurting performance by dealing with two
BVH trees at the same time, though I didn't test that).

Now each component is handled in a separate function, so that adding
support for another component type is much simpler.
2021-08-25 18:03:24 -05:00
5b751c95f4 BLF: Remove ASCII-only Code Paths
Remove redundant code for drawing text strings that contain only ASCII.

See D12293 for much more detail.

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

Reviewed by Campbell Barton
2021-08-25 13:30:00 -07:00
518b97e674 Windows/Ninja: Optimize linker performance
The /Zc:inline flag is by default off in the MSVC
compiler however when you build with msbuild it adds
it to the build flags on its own.

Ninja however does not decide on its own to add
flags you didn't ask for and was building without
this flag.

This change explicitly adds the compiler flag so
msbuild and ninja builds are once more building
with the same build flags leading to smaller .obj
files when building with ninja and lightening the
workload for the linker.

This flag is available starting MSVC 2013 update 2
so does not need to be guarded with version checks.
2021-08-25 10:55:45 -06:00
05564c8ca6 Fix wrong length value in the header of the Move operator
Missed in {rB0d36439f95c0}.
2021-08-25 13:01:41 -03:00
8fb9155598 Fix T90248: missing depsgraph update tag for node group
The code assumed that when a node group is is at the highest
level in the node editor, then it is embedded into another data
block and can't be referenced by other node groups. This is true
for shader and compositor nodes, but not for geometry nodes.
2021-08-25 18:00:29 +02:00
0d36439f95 Fix T90911: Move along axis does not display real distance units
Variable was wrongly set to 0.
Caused by {rB7192e57d63a5}.
2021-08-25 12:44:35 -03:00
f49d438ced Cleanup and remove SEQ_ALL_BEGIN macro
We now use a for_each function with callback to iterate through all sequences in the scene.

This has the benefit that we now only loop over the sequences in the scene once.
Before we would loop over them twice and allocate memory to store temporary data.

The allocation of temporary data lead to unintentional memory leaks if the code used returns to exit out of the iteration loop.
The new for_each callback method doesn't allocate any temporary data and only iterates though all sequences once.

Reviewed By: Richard Antalik, Bastien Montagne

Differential Revision: http://developer.blender.org/D12278
2021-08-25 17:30:39 +02:00
796035ad93 Cleanup: else-after-return 2021-08-25 16:00:48 +02:00
0fd1e6a5f4 T90908: Reduce loading times when extracting thumbnails from Blendfiles.
Previously when loading an thumbnails for an asset the whole file was
read. Reason this was done was perhaps a future idea to load
all thumbnails inside a blendfile in a single go. This was never implemented
and currently unneeded disk and cpu cycles was spend with finding out what
preview to load.

This patch adds an early break when the thumbnail that the caller is
interested in has been found. This improves the thumbnail extraction
when looking into large files.

Reviewed By: mont29

Maniphest Tasks: T90908

Differential Revision: https://developer.blender.org/D12312
2021-08-25 15:59:41 +02:00
5a0ec2302e XR: Enable controller profile extensions
Enables all currently documented OpenXR controller profile
extensions (Reverb G2, Vive Cosmos, Huawei Controller) in order to
support bindings for more VR hardware.

This is necessary because, if these extensions are not enabled, the
OpenXR runtime will return an error when creating a binding with one
of these profiles.

Does not bring about any changes for users at the moment, since
default controller actions have not yet been exposed to users (will
be addressed with D10944, D10948, and D11271).
2021-08-25 21:36:53 +09:00
940ba74024 XR: Improve "Invalid stage ref space" warning
Originally mentioned that absolute tracking was disabled, which is
wrong because absolute tracking (skipping application of eye offsets)
is always available, although it may not give the expected result of
persistent tracking origins across sessions if the stage space is
unavailable (hence the need for a warning).

Now, the warning makes no mention of absolute tracking, instead
informing the user that the local space fallback will be used and
that they should define tracking bounds via the XR runtime if they
wish to use the stage space.
2021-08-25 20:59:53 +09:00
d6ace5a7bb Fix: Crash on file read with active VR session
Add null check for runtime data since it could already have been
freed via wm_xr_exit() (called on file read) prior to the session
exit callback.

Also, fix potential memory leak by freeing session data in
wm_xr_runtime_data_free() instead of session exit callback.
2021-08-25 20:59:37 +09:00
cb9c0aa7d0 Fix: XR action map memory leaks
This fixes two memory leaks related to XR action maps.

1. Freeing of action maps needs to be moved from wm_xr_exit() to
wm_xr_runtime_data_free() since the runtime may have already been
freed when calling wm_xr_exit().

2. Action bindings for action map items were not being freed. This
was mistakenly left out of e844e9e8f3 since the patch needed to be
updated after d3d4be1db3.
2021-08-25 20:57:13 +09:00
a34652d6f8 Fix: Incorrect declaration of XrActionMaps RNA
This fixes a mistake in the XrActionMaps RNA struct declaration.

Originally, the XrActionMaps struct SDNA was set as wmXrData to get
access to wmXrRuntimeData. However, this doesn't give a valid pointer
and the XrSessionState RNA pointer needs to be passed instead.

Since XrSessionState itself does not have SDNA, it is necessary to
pass the XrSessionState pointer to the XrActionMaps struct functions
(new(), new_from_actionmap(), ...) instead of simply using
RNA_def_struct_sdna().
2021-08-25 20:56:52 +09:00
452cc01932 Cleanup: skip saving selection properties set in the keymap
Having settings such as "extend" saved between executions causes
keymaps that don't include this setting to remember the value
between execution.

No longer store this setting for selection operations & remove
redundant values from the key-maps, see: T90275.
2021-08-25 18:10:56 +10:00
8d634c1b27 Cleanup: Mentioning incorrect source file in comment.
Code mentions that ID_* were defined in DNA_ID.h but are actually defined
in DNA_ID_enums.h.
2021-08-25 10:00:55 +02:00
e91fd3b816 Cleanup: separate IMB_thumb_load_blend in multiple functions. 2021-08-25 10:00:55 +02:00
a2597f8b83 Keymap: repeat was disabled for Ctrl-Backspace in the text editor 2021-08-25 17:40:55 +10:00
b98b9354b2 Cleanup: Fixed compile error in debug code. 2021-08-25 09:37:46 +02:00
9df063df19 Fix assert caused by 38630711a0 2021-08-25 17:18:26 +10:00
820d50d3cb Correct error in 38630711a0 2021-08-25 15:36:40 +10:00
38630711a0 BLI_string_utf8: remove unnecessary utf8 decoding functions
Remove BLI_str_utf8_as_unicode_and_size and
BLI_str_utf8_as_unicode_and_size_safe.

Use BLI_str_utf8_as_unicode_step instead since it takes
a buffer bounds argument to prevent buffer over-reading.
2021-08-25 15:28:59 +10:00
be906f44c6 BLI_string_utf8: simplify utf8 stepping logic
There were multiple utf8 functions which treated
errors slightly differently.

Split BLI_str_utf8_as_unicode_step into two functions.

- BLI_str_utf8_as_unicode_step_or_error returns error value
  when decoding fails and doesn't step.

- BLI_str_utf8_as_unicode_step always steps forward at least one
  returning the byte value without decoding
  (needed to display some latin1 file-paths).

Font drawing uses BLI_str_utf8_as_unicode_step and no longer
check for error values.
2021-08-25 15:27:18 +10:00
70f890b510 VSE: Set default sound and video export format
Use video format for export instead of image sequence. Settings are same
as defined in h264_in_MP4 preset.

Sound default is AAC with 256kbit bitrate.

Reviewed By: campbellbarton

Differential Revision: https://developer.blender.org/D7916
2021-08-25 06:58:43 +02:00
f80c39b74e Cleanup: Use shorter enum item names 2021-08-24 23:40:13 -05:00
891e3e98eb LineArt: Fix (Unreported) Crash when loading objects.
Fix mesh freeing call for obi->original_me so the address is correct.
2021-08-25 11:05:48 +08:00
a2e0f714f2 Cleanup: Remove unecessary variables
Instead of passing separate booleans for whether to store the locations
and distances, check if the spans are empty. And instead of passing a
separate boolean for whether there is valid tree data, pass a pointer
to the data.
2021-08-24 21:57:45 -05:00
5ef3afd87c Fix T90900: Crash when rendering geometry nodes created curve
The comment for data_eval mentions that it should contain a mesh for
curve objects, however with geometry nodes, objects can evaluate to
curves as well (though they are only containers for the `CurveEval`.
That is a larger issue, but with the upcoming geometry instancing patch
the situation changes, so this commit does not correct that. I also hope
to remove this code in favor of the new curve to mesh code soon.

Instead, just check the evaluated data type in this case, which prevents
the crash, though it is hacky.
2021-08-24 13:38:53 -05:00
f53cf5141d Cleanup: Make function static, remove unused arguments 2021-08-24 13:27:29 -05:00
19da434e9c Nodes: Improvements to edge panning in the node editor.
- New operator property to toggle edge panning in the keymap:
  This is disabled by default to avoid edge-panning in cases where it
  gets distracting, such as adding a new node. Only the explicit
  translate operator(s) (GKEY or drag) have this enabled now.

- Restore the initial view rect on edge pan cancel:
  The initial view rect is now stored in the edge pan operator data.
  When an operator with edge panning is cancelled it can now call the
  `UI_view2d_edge_pan_cancel` function to restore the original View2D
  rect.

- Less delay in node editor scrolling:
  Delay is useful when scrolling through long lists, such as in the
  outliner, but makes node scrolling feel sluggish and unresponsive.
  The lower scroll speed here makes a faster response the better option.

- Zoom influence feature:
  Somewhat slower scrolling in UI-space when zoomed out. With the 0.5
  zoom influence factor nodes behave as if zoom factor is halved,
  otherwise it gets too fast when zoomed out. Previously scrolling would
  always be constant-speed in UI space, now it's half-way between UI
  space and node (view) space.
2021-08-24 18:00:05 +01:00
Robert Guetzkow
38bdde852f Fix T90715: Remove correct particle modifier through Python API
Before this patch attempting to remove a particle modifier programmatically
through Python would fail, because it deleted the modifier associated with
the currently active particle system instead of the one passed as an argument
to `bpy.types.ObjectModifiers.remove()`.

This fix  adds an additional argument for the particle system to
`object_remove_particle_system`. This allows to specify which particle system
and its associated modifier shall be removed. In case of
`particle_system_remove_exec` it will remain the currently active particle
system, whereas `object_remove_particle_system` passes the particle system
of the modifier. Hence, the correct modifier will be removed.

Reviewed By: mont29

Differential Revision: https://developer.blender.org/D12234
2021-08-24 18:41:22 +02:00
551521cfa4 Cleanup: ID management: Remove useless internal for BKE_lib_id_clear_library_data.
This static internal `_ex` function was not doing anything extra, just
move back whole code to public API `BKE_lib_id_clear_library_data`.
2021-08-24 17:19:41 +02:00
b55c02a206 Cleanup: Remove useless Camera make_local callback.
Not sure why this one was still there, probably just escaped a previous
cleanup somehow.
2021-08-24 17:08:23 +02:00
9327c00f70 Cleanup: Simplify logic 2021-08-24 10:01:08 -05:00
038f9b7f4a Render: Lazily allocate render passes pixels storage
The idea is to only allocate pixel storage only when there is an actual
data to be written to them.

This moves the code forward a better support of high-res rendering when
pixel storage is not allocated until render engine is ready to provide
pixel data.

Is expected to be no functional changes for neither users no external
engines. The only difference is that the motion and depth passes will
be displayed as transparent for until render engine provides any tile
result (at which point the pixels will be allocated and initialized to
infinite depth).

Differential Revision: https://developer.blender.org/D12195
2021-08-24 16:20:57 +02:00
7aff40f410 FFMPEG: Fix building with older versions that need FFMPEG_USE_DURATION_WORKAROUND 2021-08-24 15:15:21 +02:00
3c82725d74 Disable Fade Inactive Geometry overlay by default
This overlay was intended to identify the active objects in modes
like Sculpt Mode, where you don't have any extra visual indication
of what is the current and target object when switching directly
between them.

After having flash on mode transfer on the transfer mode operator,
the visual information this overlays provides is redundant. It is
still available in case some users want to use it like a way of
focusing on the active object.

Reviewed By: JulienKaspar, JacquesLucke

Differential Revision: https://developer.blender.org/D12303
2021-08-24 12:56:36 +02:00
46913bf0a0 Fix T90840: Can't duplicate or copy (Ctrl-C) object from linked file.
We need to separate the flag telling duplicate code to not handle
remapping to new IDs etc., from the one telling the code that we are
currently duplicating a 'root' ID (i.e. not a dependency of another
duplicated ID).

This whole duplicate code/logic is still fairly unsatisfying, think it
will need further refactor, or maybe even re-design, at some point...
2021-08-24 12:23:39 +02:00
4e4ac5a867 Fix invalid mask use for the UV-project modifier
Mistake in a30a817933.
2021-08-24 18:17:54 +10:00
Himanshi Kalra
30d3dd4de1 Added more Geometry Node tests
* Attributes
* Utilities
* Volume

Test folder located in `lib\tests\modeling\geometry_nodes`
It contains around 34 new tests.
* attribute clamp + other attribute nodes
* Curve Primitive nodes
* Mesh Primitive nodes
* delete geometry
* convex hull
* subdivision surface
* boolean intersect
* boolean diff
* volume to mesh

Reviewed By: zazizizou, JacquesLucke

Differential Revision: https://developer.blender.org/D12250
2021-08-24 13:27:36 +05:30
983280b014 PyAPI: remove active area test for script.python_file_run operator
There is no reason running a Python file should require an active area.
2021-08-24 14:53:23 +10:00
de60205f19 Fix buffer size mismatch in SCRIPT_OT_python_file_run
Reading paths over 512 bytes would cause a buffer overrun.
2021-08-24 14:52:02 +10:00
e0a6001a22 Fix reporting Python reference leaks with WITH_PYTHON_SAFETY
Error in f3e26c847b
2021-08-24 14:36:25 +10:00
8b55cda048 Fix BLI_str_utf8_as_unicode_step reading past intended bounds
Add a string length argument to BLI_str_utf8_as_unicode_step to prevent
reading past the buffer bounds or the intended range since some callers
of this function take a string length to operate on part of the string.

Font drawing for example didn't respect the length argument,
potentially causing a buffer over-read with multi-byte characters
that could read past the end of the string.

The following command would read 5 bytes past the end of the input.

`BLF_draw(font_id, (char[]){252}, 1);`

In practice strings are typically null terminated so this didn't crash
reading past buffer bounds.

Nevertheless, this wasn't correct and could cause bugs in the future.

Clamping by the length now has the same behavior as a null byte.

Add test to ensure this is working as intended.
2021-08-24 14:25:15 +10:00
8371df8b1c Cleanup: spelling 2021-08-24 12:49:00 +10:00
a311ab6167 Cleanup: quiet clang-format warnings, unused argument 2021-08-24 12:43:15 +10:00
bffa168157 Fix T90854: Cycles, normal map fails with applied transformations
Prior to rBb8ecdbcd964a normals were stored both in
DeviceScene.tri_vnormal and the float3 attributes buffer. However, the
normals in `DeviceScene.tri_vnormal` might have be transformed to world
space if the object's transformation was applied, while the data in the
float3 attributes buffer were not. This caused shading issues in cases
where the objects did have transformation applied, as the math expects
the normals to be in object space.

To fix this, convert the normals to object space if necessary before
applying the normal map.

Reviewed By: brecht

Maniphest Tasks: T90854

Differential Revision: https://developer.blender.org/D12294
2021-08-24 01:43:57 +02:00
Félix
eec1ea0ccf VSE: Add Sequence.parent_meta() python API function
This function can be used to find metastrip parent of nested strip.

Reviewed By: ISS

Differential Revision: https://developer.blender.org/D11985
2021-08-24 01:21:08 +02:00
929d7597b3 VSE: Cleanup speed effect math
Simplify logic of speed effect frame calculation by using discrete math
where possible. Only `SEQ_SPEED_MULTIPLY` mode with animation requires
frame map to be built. Frame map building was simplified by removing
unused branches.

Functional change: Animating strip in negative range will reverse playback.
I assume this was limitation of previous system, where each frame map item
was limited to be within correct frame range. Now frame map can contain
values that point beyond usable range and they are limited by
`seq_speed_effect_target_frame_get`. This way it is possible to control
playback rate in both directions.

Mostly fixes T89120 apart from offset handling.

Reviewed By: mano-wii

Differential Revision: https://developer.blender.org/D11939
2021-08-24 01:10:12 +02:00
a57ba4147f Fix T88237: Prefetch crash on rendering scene strip
Prefetch needs to avoid rendering scene strips, because

 - Rendering in background needs own dependency graph, which fails to
   initialize from evaluated data.
 - This locks UI and can make it unresponsive for long time periods.

In T88237 prefetch failed to avoid scene strip, because of effect strip
was attached to scene strip.

Ensure, that no effect that is attached to scene strip either directly
or indirectly would be rendered.

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D11247
2021-08-24 00:58:01 +02:00
709ce44617 Fix T90407: Split fails on transition strips
When splitting strips, first they are duplicated and then offsets
adjusted. This can fail on cross transitions, because some strips don't
overlap with split frame.

All strips, that relate to each other must be duplicated to ensure
correct relations after splitting, so solution is to delete non
overlapping strips from left or right side respectively.

Since cross transition don't have to overlap with source strips,
splitting such strips would lead to effect being deleted, which
could cause crash when iterating over strips in python. Therefore
splitting of such strips is now forbidden and will generate error.

Splitting of transition will also generate error solely because such
operation is illogical.

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D12121
2021-08-24 00:52:24 +02:00
24a3446787 Fix T90646: VSE hangs when strips overlap
When all strips are selected and overlap is caused, this causes VSE to
hang in infinite loop, because such situation should never happen.

To prevent infinite loop, ensure, that strip overlap is not tested
against single overlapping strip itself.

Prevent overlap that can not be handled because of issue described above
by moving overlapping strip between channels.

Reviewed By: campbellbarton

Differential Revision: D12209
2021-08-24 00:46:34 +02:00
a0c8ee057a Fix T90467: Initialize CurveMapping on demand
`CurveMapping.evaluate` function expectes `CurveMapping` to be
initialized, while this wasn't documented.

I don't see any reason for not initializing `CurveMapping` on demand.
Initialization was added in rBf16047c2df1e8be56bf76524f9eb1fa5ecde2176

Reviewed By: campbellbarton

Differential Revision: https://developer.blender.org/D12145
2021-08-24 00:37:32 +02:00
Himanshi Kalra
875c2ea5b5 Using relative threshold for floats in mesh comparison
Changes the threshold comparison from absolute to relative.
Removes threshold for MLoopCol comparison.

Adds a compare relative threshold function.

Reviewed By: JacquesLucke

Differential Revision: https://developer.blender.org/D12273
2021-08-24 00:50:03 +05:30
be1891e895 Cleanup: move the buffer list to 'MeshBufferCache'
The cache is used to fill the buffer list.
2021-08-23 13:44:31 -03:00
cbe4036406 Cleanup: Isolate the batch list struct into a struct called MeshBatchList
This allows for a simplification of macros and combines with
`MeshBufferList`.
2021-08-23 13:43:45 -03:00
eb0c50ac78 Cleanup: rename 'MeshBufferExtractionCache' to 'MeshBufferCache'
Matches the existing `MeshBatchCache`.
2021-08-23 13:43:42 -03:00
6e51ef9531 Cleanup: rename 'MeshBufferCache' to 'MeshBufferList'
`MeshBufferList` is more specific and can avoid confusion with
`MeshBufferExtractionCache`.
2021-08-23 13:41:03 -03:00
Germano Cavalcante
ebdae75736 Cleanup: Move 'tris_per_mat' member out of 'MeshBufferCache'
`MeshBufferCache` is a struct representing a list of buffers.

As such, `GPUIndexBuf **tris_per_mat` is out of place as it does not
represent one of the buffers in the list.

In fact this member should be close to `GPUBatch **surface_per_mat` as
they are related.

The code for dependencies between buffer and batch had to be reworked
as it relies on the member's position.

Differential Revision: https://developer.blender.org/D12227
2021-08-23 13:37:32 -03:00
7d17f2addf Fix T89998: Cryptomatte node output values doubled with Multi-View
When using a Cryptomatte node and selecting 2 views in Multi-View,
its output values are doubled. When selecting 3 tripled and so on.
This causes incorrect compositing results for all the views.

The node creates an input operation for each rendered cryptomatte
pass. In Multi-View, passes are rendered for each view but compositor
is executed per view and should only create operations for those
corresponding to the current view being executed. Otherwise duplicated
operations add up later in cryptomatte operation.

Reviewed By: jbakker

Maniphest Tasks: T89998

Differential Revision: https://developer.blender.org/D12216
2021-08-23 17:09:59 +02:00
4c6d207343 Compositor: Fix crash enabling buffer groups on full frame
Full frame doesn't support this option as all operations are already
buffered. UI option will be removed in the future.
2021-08-23 17:09:59 +02:00
42f89b9212 Compositor: Fix incorrect copying of uchar buffers
Row stride and the area x coordinate offset were not taken into
account.
2021-08-23 17:09:59 +02:00
153b45037f Compositor: Full frame matte nodes
Adds full frame implementation to Channel Key, Chroma Key, Color Key,
Color Spill, Cryptomatte, Difference Key, Distance Key, Keying,
Keying Screen and Luminance Key nodes. The other nodes
in "Matte" sub-menu are submitted separately.

No functional changes.

Part of T88150.

Reviewed By: jbakker

Differential Revision: https://developer.blender.org/D12220
2021-08-23 17:09:59 +02:00
daa7c59e38 Compositor: Full frame Bokeh Blur and Blur nodes
Adds full frame implementation to these nodes operations.

When enabling "extend bounds" node option, tiled implementation
result is slightly different because it's using `TranslateOperation`
with bilinear sampling for centering.
Full frame always uses nearest to don't lose image quality.
It has the disadvantage of causing image jiggling on backdrop
when switching size values as it's not pixel perfect.
This is fixed by rounding to even.

No functional changes.

Part of T88150.

Reviewed By: jbakker

Differential Revision: https://developer.blender.org/D12167
2021-08-23 17:08:45 +02:00
344aca3b1b Compositor: Full frame distort nodes
Adds full frame implementation to "Displace", "Crop", "Flip",
"Plane Track Deform", "Corner Pin", "Movie Distortion",
"Lens Distortion" and "Map UV" nodes.

The other nodes in "Distort" sub-menu are implemented
separately in other commits.

No functional changes.

Part of T88150.

Reviewed By: jbakker

Differential Revision: https://developer.blender.org/D12166
2021-08-23 17:07:37 +02:00
064167fce7 Compositor: Full frame transform nodes
Adds full frame implementation to "Rotate", "Transform" and
"Stabilize2D" nodes.
To avoid sampling twice when concatenating scale and rotate
operations, a `TransformOperation` is implemented with all
the functionality.
The nodes have no functional changes.

Part of T88150.

Reviewed By: jbakker

Differential Revision: https://developer.blender.org/D12165
2021-08-23 16:36:09 +02:00
a95e56b741 Compositor: Add sampling methods for full frame
Current sampling methods have off by one issues on full frame:
- Bilinear sampling do not fully sample bottom and left image border,
 creating edges.
- Single elem buffers are not sampled at all when they should be
 at least on the borders to smooth edges.
- EWA filtering is partially implemented on `ReadBufferOperation`, it
 needs to be moved to `MemoryBuffer` on full frame.

In order to not affect tiled implementation, this commit creates
specific sampling methods for full frame needs.

Reviewed By: jbakker

Differential Revision: https://developer.blender.org/D12164
2021-08-23 16:36:09 +02:00
8f4730e66f Compositor: Full frame convert nodes
Adds full frame implementation to all nodes in "Converter" sub-menu
except "ID Mask" which is implemented separately.
No functional changes.

Part of T88150.

Reviewed By: jbakker

Differential Revision: https://developer.blender.org/D12095
2021-08-23 16:36:08 +02:00
James Partsafas
21d4a888b8 Fix T88107: rename Convertor to Converter nodes to correct spelling
Differential Revision: https://developer.blender.org/D11198
2021-08-23 16:27:33 +02:00
Mikhail Matrosov
cd118c5581 Fix T90423: black pixels after shadow terminator geometry offset
Solves an error in the principled diffuse BSDF, where it was not correctly
rejecting directions outside the hemisphere.

Differential Revision: https://developer.blender.org/D12283
2021-08-23 15:47:34 +02:00
27f138f4c8 Cleanup: rename parameter in transform utility
`inv_unit_scale` is not descriptive.
2021-08-23 09:49:01 -03:00
2f0e350ffd Fix T90872: Dopesheet messes up keyframe handles
Y coordinate was not being constrained.

Caused by {rBb0d9e6797fb866e7a58876c7977c98a190070310}
2021-08-23 09:49:01 -03:00
b4b3f518aa GPencil: Fix memory leak in split & trim functions
Authored by Henrik Dick (weasel)

Reviewed By YimingWu (NicksBest), Antonio Vazquez (antoniov)

Differential Revision: https://developer.blender.org/D12284
2021-08-23 20:46:38 +08:00
5aa3167e48 Fix T90772: Image Editor not sampling color from the the currently
selected pass

Caused by {rBebaa3fcedd23}.

Seems this above commit assumed an ImageUser's multi_index is only used
for Multiview/Stereo? This is not the case, multi_index also stores the
index for layer/pass combination.

If we call both BKE_image_multilayer_index and BKE_image_multiview_index
(even though this is not appropriate/needed for multilayer images?), we
might end up overwriting multi_index again.

note: looking at this I was also wondering why we update the ImageUser
in image-buffer-aquiring funnctions [and not from the UI, e.g.
template_image_layers, but that is a whole different story I guess, see
comment in T90772 as well]

note2: this could also use a utility function (this is not the only
place where this is done), this is fo a cleanup commit.

Maniphest Tasks: T90772

Differential Revision: https://developer.blender.org/D12267
2021-08-23 13:54:52 +02:00
8165333de9 Pipeline: Use more explicit cuda versions. 2021-08-23 13:47:40 +02:00
9564b6cf23 Fix T90651: camera reconstruction crash without scene camera
This was working differently in 2.79, tried tracking this down and it
seems this was wrong since the 2.8 beginning in {rB7907dfc40018}.

This would not only crash without an active scene camera, but would also
result in different tracks from different camera's constraints could not
be selected.

So select id depends on corresponding camera, remove the dependency on
scene camera completely.

Maniphest Tasks: T90651

Differential Revision: https://developer.blender.org/D12230
2021-08-23 12:52:23 +02:00
0682af0d63 RNA: add length augmented to RNA_string_get_alloc
This was noted as a TODO as it wraps RNA_property_string_get_alloc
which takes a length return argument.
2021-08-23 15:08:48 +10:00
62f2204d65 Cleanup: rename len to str_len for BLF functions
Make it obvious which variable this is the length of.
2021-08-23 15:08:28 +10:00
aa067bef5e Cleanup: use BLI_str_utf8 prefix
Rename:

- BLI_str_utf8_invalid_byte  (was BLI_utf8_invalid_byte)
- BLI_str_utf8_invalid_strip (was BLI_utf8_invalid_strip)
2021-08-23 15:02:13 +10:00
0de3d4e8c7 Fix T90847: snap to face of Add Primitive tool not working in edit mode
BVHTree was being created but not balanced.
Error introduced in {rBfcc844f8fbd0}.
2021-08-22 23:48:54 -03:00
b477333473 Cleanup: fix comment about compiler support.
Differential Revision: https://developer.blender.org/D12288
2021-08-22 22:15:28 +05:30
a1e91fbef3 BLF: Remove space_userpref.py font_kerning_style
Remove `font_kerning_style` from `space_userpref.py` since this is no
longer valid.

See more details in D12276

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

Reviewed by Campbell Barton
2021-08-22 09:26:06 -07:00
721fad37a1 Fix Windows builds after Zstandard commits 2021-08-21 23:31:51 +02:00
67c29bc5a2 Use Zstandard compression for the sequencer cache
Reviewed By: campbellbarton, brecht, mont29

Differential Revision: https://developer.blender.org/D5799
2021-08-21 21:39:06 +02:00
2ea66af742 Add support for Zstandard compression for .blend files
Compressing blendfiles can help save a lot of disk space, but the slowdown
while loading and saving is a major annoyance.
Currently Blender uses Zlib (aka gzip aka Deflate) for compression, but there
are now several more modern algorithms that outperform it in every way.

In this patch, I decided for Zstandard aka Zstd for several reasons:
- It is widely supported, both in other programs and libraries as well as in
  general-purpose compression utilities on Unix
- It is extremely flexible - spanning several orders of magnitude of
  compression speeds depending on the level setting.
- It is pretty much on the Pareto frontier for all of its configurations
  (meaning that no other algorithm is both faster and more efficient).

One downside of course is that older versions of Blender will not be able to
read these files, but one can always just re-save them without compression or
decompress the file manually with an external tool.

The implementation here saves additional metadata into the compressed file in
order to allow for efficient seeking when loading. This is standard-compliant
and will be ignored by other tools that support Zstd.
If the metadata is not present (e.g. because you manually compressed a .blend
file with another tool), Blender will fall back to sequential reading.

Saving is multithreaded to improve performance. Loading is currently not
multithreaded since it's not easy to predict the access patterns of the
loading code when seeking is supported.
In the future, we might want to look into making this more predictable or
disabling seeking for the main .blend file, which would then allow for
multiple background threads that decompress data ahead of time.

The compression level was chosen to get sizes comparable to previous versions
at much higher speeds. In the future, this could be exposed as an option.

Reviewed By: campbellbarton, brecht, mont29

Differential Revision: https://developer.blender.org/D5799
2021-08-21 21:39:06 +02:00
2b170f16d6 Refactor low-level blendfile reading into separate files
Instead of handling mmap, compression etc. all directly in readfile.c, refactor
the code to use a generic FileReader.
This makes it easier to add new compression methods or similar, and allows to
reuse the logic in other places (e.g. thumbnail reading).

Reviewed By: campbellbarton, brecht, mont29

Differential Revision: https://developer.blender.org/D5799
2021-08-21 21:38:57 +02:00
34a05f39be Clang: warn about C++20 designated initializers
With the ongoing transition to C++ files, Windows build
breaks often because of designated initializers.
Now we have two compilers to catch the MSVC build error on.

Reviewed By: #platform_macos, brecht, campbellbarton
Differential Revision: https://developer.blender.org/D11940
2021-08-21 14:02:50 +05:30
0b7947e855 Cleanup: minor changes to blf_font.c
- Use early return when kerning isn't used.
- Remove early return that prevented matching acquire/release calls.
2021-08-21 17:46:50 +10:00
47e68537f8 Cleanup: organize blf_font.c functions using doxy-sections
Functions in this file were scattered and not well organized.
2021-08-21 17:41:40 +10:00
c671bfe14e Cleanup: spelling in comments & minor cleanup
Also hyphenate 'mouse-move' use doxy sections in render_update.c &
move function comment from the header to the source.
2021-08-21 13:26:54 +10:00
aed5a27755 Correct build error from 0d7aab2375 2021-08-21 13:22:47 +10:00
0d7aab2375 Refactor: BLF Kerning Cache After Use
Optimization of font kerning by only caching kerning values after a
pair is encountered. Also saves unscaled values so they don't have to
be rebuilt between font size changes.

See D12274 for more details and speed comparison.

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

Reviewed by Campbell Barton
2021-08-20 17:48:42 -07:00
b6a1bf757d DocPy: Cleanup missing newline resulting in wrong html generation 2021-08-20 14:54:46 -04:00
86622467c5 DocPy: Update Dependancies
Updates sphinx and the theme to the latest version along with any of their dependencies.

Note that we will be sticking to sphinx 4.1.1 until sphinx 4.2 for the same reasons listed in:
https://developer.blender.org/rBM8334
2021-08-20 13:46:38 -04:00
Alaska
cd8d9383e7 Fix T90804: small grammatical error in noise threshold description
Differential Revision: https://developer.blender.org/D12277
2021-08-20 17:43:24 +02:00
1b5f17b867 Cleanup, use BKE_scene_uses_cycles_experimental_features 2021-08-20 15:00:58 +02:00
6a404bc633 Cleanup, remove extra code from previous commit
This got accidentally introduced while revising dependencies between
patches for this feature, did not notice until it was too late.
2021-08-20 14:48:47 +02:00
9bfc47c933 Alembic Procedural: basic cache control settings
This adds a setting to enable data caching, and another one to set the
maximum cache size in megabytes.

When caching is enabled we load the data for the entire animation in
memory, as we already do, however, if the data exceeds the memory limit,
render is aborted.

When caching is disabled, we simply load the data for the current frame
in memory.

Ref D10197

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D11163
2021-08-20 14:34:43 +02:00
accf3045be Fix memory leak while processing mouse event
Assignment missed.
2021-08-20 09:06:19 -03:00
a063d58080 Merge branch 'master' into xr-controller-support 2021-08-20 20:50:24 +09:00
f58bebf688 XR: Fix controller model world transforms
Fixes incorrect display of Reverb G2 controller model/animated parts.

Thanks to Werner Trunk for help with debugging.
2021-08-20 20:46:15 +09:00
ef502127dd Fix T90795: Moving keys in Grease Pencil Dopesheet crashes Blender
`td->loc` is referenced but not initialized.
2021-08-20 08:40:37 -03:00
0081200812 Functions: remove multi-function network
The multi-function network system was able to compose multiple
multi-functions into a new one and to evaluate that efficiently.
This functionality was heavily used by the particle nodes prototype
a year ago. However, since then we only used multi-functions
without the need to compose them in geometry nodes.

The upcoming "fields" in geometry nodes will need a way to
compose multi-functions again. Unfortunately, the code removed
in this commit was not ideal for this different kind of function
composition. I've been working on an alternative that will be added
separately when it becomes needed.

I've had to update all the function nodes, because their interface
depended on the multi-function network data structure a bit.
The actual multi-function implementations are still the same though.
2021-08-20 13:14:39 +02:00
7d8c71e800 Geometry Nodes: add missing versioning for subdivision surface node
This was missing from rBfecec1644ce54ea386eaeed5ca6748d4a7b2737b.
2021-08-20 12:19:24 +02:00
c1227fd408 Cleanup: remove duplicate line 2021-08-20 12:05:03 +02:00
d217b34214 Functions: add utility methods to parameter builder 2021-08-20 11:48:31 +02:00
fd51b05a02 Functions: add clear method to vector array 2021-08-20 11:48:31 +02:00
2b6f0cc836 BLI: add utility methods to IndexMask 2021-08-20 11:48:31 +02:00
e95b197e98 Cleanup: Add CLOG to wm_files_link.c 2021-08-20 11:27:42 +02:00
cea24b4b4a Cleanup: use "free_data" suffix when the argument isn't freed
Avoid API misuse that caused leaks in T90791 &
2788b0261c.
2021-08-20 16:37:50 +10:00
e05db0c26b Cleanup: rename BKE_mesh_free_data -> BKE_mesh_free_data_for_undo
This function only makes sense for undo which doesn't
initialize the meshes ID. Otherwise BKE_id_free should be used.
2021-08-20 16:21:29 +10:00
40f0783d51 Cleanup: remove BKE_mesh_free_data use for lineart mesh copies
Even though this didn't leak memory, BKE_mesh_free_data doesn't
handle freeing data that is part of the ID making it error prone.
2021-08-20 16:08:35 +10:00
15a46a8b72 Cleanup: accidentally included printf 2021-08-20 16:02:39 +10:00
9e2cd6b077 Fix memory leak with building springs in the cloth simulator
Error in 2788b0261c.
2021-08-20 16:00:12 +10:00
a48df97ada Fix T90791: Knife project leaks memory with curve/text cutter 2021-08-20 15:19:58 +10:00
ce3a6d7989 Cleanup: rename BKE_mesh_free -> BKE_mesh_free_data
It wasn't obvious this didn't free the memory of the mesh it's self
leading to memory leaks.
2021-08-20 15:08:27 +10:00
44b25b0ea5 Cleanup: unused warnings 2021-08-20 15:03:32 +10:00
fca6b2780f Cleanup: clang-format 2021-08-19 19:27:49 -07:00
f8637cd8af Alembic Procedural: only subdivide if subsurf modifier is present
As subdivision objects are first class citizens in Alembic, to
differentiate them with non-subdivided polygon meshes, the Alembic
Procedural automatically sets up subdivision properties on the generated
Cycles Mesh.

However, for real-time playback subdivision is far too slow, so this
modifies the detection of a MeshSeqCache modifier used to activate the
procedural to allow for a Subsurf modifier right after the cache one. If
present, the procedural will tag the object for subdivision, if absent, the
object will be treated as a regular mesh.

This is a temporary measure for until subdivision surface settings are part
of the Mesh datablock (see T68891).

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D11162
2021-08-20 02:40:37 +02:00
5b51df0f33 Cleanup, format 2021-08-20 02:30:11 +02:00
ba79625f9e Merge branch 'master' into xr-controller-support 2021-08-16 18:57:48 +09:00
72381da800 XR: Don't store controller node world transforms
Removes unnecessary storage of world space transforms for controller
model nodes. Now, only local space transforms are stored and the
world transforms are calculated from these local transforms when
needed.
2021-08-16 18:55:36 +09:00
9d68c34a75 Merge branch 'master' into xr-controller-support 2021-08-16 12:04:19 +09:00
e41cc8162a Merge branch 'master' into xr-controller-support 2021-08-15 15:21:01 +09:00
1990bb921f XR: Support dynamic controller model components
Updating the transforms, or "animating", supported controller
model parts (trigger, grip, thumbstick, etc.) provides better visual
feedback for the user and adds little overhead due to caching of node
transforms/indices.
2021-08-15 15:18:34 +09:00
567c22f0d8 Merge branch 'master' into xr-controller-support 2021-08-13 07:28:34 +09:00
be0a272d91 XR: Fix crash/assert on loading controller model
When calculating controller model component transforms from glTF node
data, it was previously wrongly assumed that the glTF nodes would
always contain transform matrix values. However, nodes can instead
store their transforms as separate translation/rotation/scale values,
in which case the transform matrix needs to be explicitly calculated.
This was the case for the Reverb G2 controller models using the
Windows Mixed Reality runtime.

Special thanks to Werner Trunk for help with testing/debugging.
2021-08-13 06:44:50 +09:00
5f5289512c XR: Improve "Invalid stage ref space" warning
Originally mentioned that absolute tracking was disabled, which is
wrong because absolute tracking (skipping application of eye offsets)
is always available, although it may not give the expected result of
persistent tracking origins across sessions if the stage space is
unavailable (hence the need for a warning).

Now, the warning makes no mention of absolute tracking, instead
informing the user that the local space fallback will be used and
that they should define tracking bounds via the XR runtime if they
wish to use the stage space.
2021-08-13 06:23:01 +09:00
05c3e5c433 Cleanup
- Remove unused wmSurface.is_xr member
- Rename "actionmap" to "action_set" in wmXrActionData
- Use BLI_findstring()
- Add modifications note to tinygltf readme
2021-08-08 13:17:18 +09:00
9f6b8bc3a1 Re-update pipeline config
Accidentally updated wrong submodule in previous commit.
2021-08-07 20:55:00 +09:00
d870b85dab Update pipeline config 2021-08-07 20:46:41 +09:00
2f4712841a Merge branch 'master' into xr-controller-support 2021-08-07 18:36:55 +09:00
6dec69daa8 XR: Fix crash on file read with active session
Add null check for runtime data since it could already have been
freed via wm_xr_exit() prior to the session exit callback.
2021-08-07 18:31:12 +09:00
be7653fe52 Cleanup: remove unnecessary double pointer usage 2021-08-07 17:30:27 +09:00
c600251eae XR: Use regular window queues for XR events
Removes special queueing of events to the XR surface, which was
originally done to bypass filtering by mouse region when
invoking/executing XR operators.

Now, finding an appropriate region for XR events will simply be done in
the regular window event handling by checking the event type and
skipping mouse-specific processing.
2021-08-07 17:04:34 +09:00
d2c4094425 Merge branch 'master' into xr-controller-support 2021-08-06 16:20:44 +09:00
14fc1c73e8 Update with changes from D10943 2021-08-06 15:58:41 +09:00
ef07af330a Add missing unused variable 2021-08-02 17:00:57 +09:00
9561a0a0a3 Merge branch 'master' into xr-controller-support 2021-08-02 16:56:42 +09:00
9f5089b67a XR: Simplify action creation API
By passing an XrActionMap struct instead of individual action
parameters, action creation from Python can be reduced to a simple
call to XrSessionState.create_action_set().

This will also set any controller pose actions and optionally the
active action set for the session.
2021-08-02 16:53:04 +09:00
f34cb9f8bf Merge branch 'master' into xr-controller-support 2021-07-29 13:13:12 +09:00
5a640b94b4 Cleanup: use LISTBASE_FOREACH_INDEX macro 2021-07-29 13:12:30 +09:00
9025f2adc6 XR: Fix action map load/save
Forgot to add action bindings list.
2021-07-29 13:10:43 +09:00
d5989308fb Fix build warnings 2021-07-28 13:40:12 +09:00
8a103470c9 Merge branch 'master' into xr-controller-support 2021-07-28 13:08:26 +09:00
be59b7699e XR: Fix crash on close with active session
Fixes an issue introduced in 99beac7b3f due to duplicate call to
wm_xr_session_data_free().
2021-07-28 13:06:41 +09:00
6b67760bd8 XR: Refactor action maps, bindings
This removes the previous limitation of one interaction profile
(device) per action map by moving the profiles to action bindings.
By doing so, there is no longer the need for users to manually select
an action map, as the XR runtime will automatically select the most
appropriate profile.

An additional DNA action map layer, "XrActionMapBinding", was also
added to store profiles and input-specific properties for actions,
allowing for flexible inputs across devices.
2021-07-28 13:02:37 +09:00
fb3154447b Fix build warnings 2021-07-24 19:10:19 +09:00
c56b73277e Merge branch 'master' into xr-controller-support 2021-07-24 18:20:19 +09:00
99beac7b3f XR: Use dynamic arrays for eye, controller data
Makes API/functionality more adaptable to different systems.
2021-07-24 18:08:29 +09:00
c4c4b1a03d XR: Move controller batch creation to draw func
Ensures that a valid GPU context is available during batch creation,
which fixes potential access violation issues.
2021-07-24 15:51:23 +09:00
af90b8aaa3 Update with changes from master
36c0649d32, c41b93bda5
2021-07-24 14:23:07 +09:00
2c5241ad01 Merge branch 'master' into xr-controller-support 2021-07-22 17:36:49 +09:00
6daab062b4 Fix build errors/warnings on some platforms 2021-07-22 17:35:14 +09:00
4b3aaa76bd Merge branch 'master' into xr-controller-support 2021-07-22 15:36:54 +09:00
707bc260d8 XR: Add basic controller model drawing
Uses the OpenXR XR_MSFT_controller_model extension to load a glTF
model provided by the XR runtime. The model's vertex data is then
used to create a GPUBatch in the XR session state. Finally, this
batch is drawn via an XR surface draw callback.

Currently does not use the model's texture data, but this can be
supported in the future.
2021-07-22 15:31:36 +09:00
5b45070024 XR: Refactor controller poses
Separates controller poses into two components, "grip" and "aim",
which are both required to accurately represent the controllers
without manual offsets.

Following their OpenXR definitions, the grip pose represents the
user's hand when holding the controller, and the aim pose represents
the controller's aiming source.
2021-07-22 00:58:17 +09:00
bd8b3f57df Fix build warnings 2021-07-09 13:58:12 +09:00
4040ebd1ff Merge branch 'master' into xr-controller-support 2021-07-09 11:28:47 +09:00
3feb3a4707 XR: Fix grab interp/offsets for parented objects 2021-07-09 11:23:02 +09:00
aa92c23430 Merge branch 'master' into xr-controller-support 2021-07-07 20:04:13 +09:00
7863f2fbe0 XR: Add teleport offset option 2021-07-07 19:22:36 +09:00
872484dfaa XR: Fix action state querying from Python
Credit: Jacob Merrill
2021-07-07 19:22:10 +09:00
1185259db8 Merge branch 'master' into xr-controller-support 2021-07-04 15:48:26 +09:00
1f1589b4df XR: Show selection/controller overlays by default 2021-07-04 15:42:55 +09:00
6ee46d5e83 XR: Fix mirror view not matching navigation
Forgot to update eye poses with viewer pose.
2021-07-04 15:40:38 +09:00
a177eb3dd2 Merge branch 'master' into xr-controller-support 2021-07-03 13:06:04 +09:00
f7d42065eb XR: Fix render artifacts with viewport denoising
Addresses T76003. When using VR with Eevee and viewport denoising,
scene geometry could sometimes be occluded for one eye. Solution was,
as Clement suggested, to use a separate GPUViewport/GPUOffscreen for
each VR view instead of reusing a single one for rendering.
2021-07-03 13:05:32 +09:00
7a7ee11f13 XR: Direction lock, frame based speed fly options 2021-07-03 13:05:10 +09:00
5465112930 Cleanup: RNA text 2021-07-03 13:04:49 +09:00
f89f63eefd Merge branch 'master' into xr-controller-support 2021-07-02 18:17:29 +09:00
714224ee1f XR: Support haptic feedback for actions
Adds haptic settings to float (button) actions that can be used to
apply haptics when an action is active. Users can configure the
duration, frequency, and amplitude of the feedback as well as when
it will be applied (press, release, press/release, or repeat).

The haptic output path/target is specified via the name of an
existing action of type "haptic". This allows float actions to target
the same output paths without the need for multiple haptic actions.
2021-07-02 18:10:34 +09:00
1184da2974 XR: Add cubic interpolation option for fly speed 2021-07-02 18:09:46 +09:00
e8926d40c8 XR: Add option to raycast from viewer pose
Useful when using a gamepad or for systems without motion
controllers.
2021-07-02 18:07:55 +09:00
004034f8c5 XR: Fix grab transform for parented objects 2021-07-02 17:59:14 +09:00
7b867dd00a Merge branch 'master' into xr-controller-support 2021-06-26 19:33:17 +09:00
e022f99e5c XR: Allow multiple modal actions at a time
This was disabled before since modal handlers for action operators
could receive events from other actions and exit prematurely. Now,
the XR operators check for events with the matching operator and
properties to avoid this. In addition, a list of active modal actions
is stored in the session state so that duplicate operators can be
filtered out when dispatching events.
2021-06-26 19:25:52 +09:00
80c80f5e18 XR: Use prior nav data to calculate viewer pose
Fixes an issue where draw callbacks were not drawn correctly if an
operator changed the navigation. Now, the navigation transforms are
saved before dispatching action events and are later used to
calculate the viewer/controller poses.
2021-06-26 19:11:48 +09:00
0d6c6a6787 Merge branch 'master' into xr-controller-support 2021-06-23 20:35:06 +09:00
e3cab5c206 XR: Add fly navigation operator
Navigates the scene by moving/turning relative to navigation space
or the XR viewer/controller. Users can select from a variety of
these modes as well as specify the min/max speed and whether to lock
elevation.

Also: pass float threshold to XR action events.
2021-06-23 20:30:32 +09:00
8ace7897a8 XR: Update controller data again in viewer update
This is needed to draw the controllers with correct transforms in the
event that an operator changed the navigation.
2021-06-23 20:24:31 +09:00
e5089d3924 Merge branch 'master' into xr-controller-support 2021-06-19 18:18:39 +09:00
65804b203e XR: Add location/rotation locks for navigation 2021-06-19 18:12:43 +09:00
2a768ffe43 Merge branch 'master' into xr-controller-support 2021-06-18 21:36:13 +09:00
2585d7f1b8 XR: Add grab navigation operator
Similar to the XR grab transform operator but applies deltas to the
navigation matrix instead of objects. Supports bimanual interaction
for viewer/navigation scaling and locks for rotation and scale.
2021-06-18 21:32:18 +09:00
eed31613e5 XR: Smooth transition between modal actions
Although only one modal action is allowed at a time, if another
modal action is pressed when the current modal action ends, then
transition immediately to that one.
2021-06-18 21:26:38 +09:00
6732d31f18 XR: Fixes/adjustments when viewer scale != 1.0
This corrects some clipping and shading issues when a scale factor
is applied to the XR viewmat. Also fixes the viewer pose calculation
with VR navigation.
2021-06-18 21:22:15 +09:00
1bd403430d Remove duplicate file
Was renamed to "wm_xr_action.c".
2021-06-18 21:14:13 +09:00
9926553255 Merge branch 'master' into xr-controller-support 2021-06-12 19:32:20 +09:00
0c92bf5e37 XR: Fix viewer pose and teleport calculation 2021-06-12 19:28:07 +09:00
9ce38d17ed XR: Add bimanual scale mode for grab operator
Also renamed operator to "Transform Grab".
2021-06-12 19:25:42 +09:00
40741a8942 Merge branch 'master' into xr-controller-support 2021-06-11 21:05:57 +09:00
eeb948f428 XR: Add axis region, bimanual action flags
The axis flags allow binding actions to certain regions of an input
axis (positive or negative). In this way, two different actions can
be bound to the input path "/input/thumbstick/x" without overlapping.

The bimanual flag signifies that the action depends on inputs from
both of its subaction paths, and both states, if available, will then
be passed to the operator. This will be used in the future for
two-handed navigation and transform.
2021-06-11 20:48:41 +09:00
9c3ac44c89 Merge branch 'master' into xr-controller-support 2021-06-08 19:35:24 +09:00
819a7e7900 Update pipeline config 2021-06-08 19:31:24 +09:00
5544ffabd5 Merge branch 'master' into xr-controller-support 2021-06-08 13:52:45 +09:00
2a3b8880e3 Fix build warnings 2021-06-08 13:51:22 +09:00
05f5d2791f Merge branch 'master' into xr-controller-support 2021-06-04 19:18:44 +09:00
29702c6d8b XR: Add teleport navigation operator
Mostly the same as the XR raycast select operator. Users can
optionally constrain the result to specific axes, for example to
achieve "elevation snapping" behavior by constraining to the Z-axis.

Credit to KISKA for the elevation snapping concept.
2021-06-04 19:10:53 +09:00
36463a16bb XR: Add initial navigation support
Adds navigation transforms (pose, scale) to the XR session state
that will be applied to the viewer/controller poses.

Users can access these transforms via Python
(xr_session_state.navigation_location/rotation/scale) to use with
custom operators.
2021-06-04 19:01:50 +09:00
b57cc27ec9 Fix build errors on some platforms 2021-05-26 18:13:35 +09:00
8b53855371 Clang format 2021-05-26 18:12:14 +09:00
af1c2869a6 Merge branch 'master' into xr-controller-support 2021-05-26 17:34:35 +09:00
9df2fae994 XR: Enable controller profile extensions 2021-05-26 17:08:35 +09:00
daf5570c42 Cleanup GHOST_Xr 2021-05-26 17:06:14 +09:00
795ae6433d XR: Change raycast color 2021-05-26 17:05:19 +09:00
1e8b3692b9 XR: Deactivate draw callbacks on session end 2021-05-26 17:04:39 +09:00
544c6fd1b6 Merge branch 'master' into xr-controller-support 2021-05-18 22:14:12 +09:00
963a6c3c12 Update addons submodule 2021-05-18 22:13:22 +09:00
f799fc3033 Merge branch 'master' into temp-xr-actions-D9124 2021-05-18 19:28:04 +09:00
5a786038cb Fix RNA error 2021-05-18 19:14:34 +09:00
7343845d7b Update with changes from D10943 2021-05-18 18:47:17 +09:00
ce5fc090a8 Move customdata wrapper to GHOST_Util.h 2021-05-16 03:13:07 +09:00
2fa8e2686e Rename "threshold" to "float_threshold" 2021-05-16 03:12:56 +09:00
f89460a872 Use RAII customdata wrapper for ctor exceptions 2021-05-16 01:09:39 +09:00
8c8bc114b8 Fix errors/warnings on Linux, gcc 2021-05-15 22:15:06 +09:00
11a63417ea Update with changes from D10942
- GHOST_XrException: Use std::string instead of const char*
- GHOST_XrActionProfile: Move default dtor declaration to header
- GHOST_XrActionSet/Action: Fix mem leak on exception in ctor
2021-05-15 10:58:53 +09:00
ed869a2609 Revert changes to wm_xr_controller_pose_to_mat() 2021-05-15 08:45:16 +09:00
79ed8f21f7 Fix merge-related error 2021-05-14 22:02:58 +09:00
a5d1f3e4c5 Merge branch 'master' into temp-xr-actions-D9124 2021-05-14 21:36:39 +09:00
7c05339597 Update with changes from D10942
Mainly cleanup-related but also adds wmXrPose and wmXrActionState
structs to replace float[7] and void* uses, respectively.
2021-05-14 21:32:23 +09:00
cd3030bb8d Fix RNG_TYPE_LEN value 2021-05-14 21:30:16 +09:00
5677c02954 Pass context to wm_xr_session_actions_update()
Restores motion capture object autokeying functionality.
2021-05-03 11:07:00 +09:00
3e7524b52b Clang format 2021-05-03 11:04:07 +09:00
c34d0fbee2 Update with changes from D10942
Except for motion capture object autokeying (will be added again once
a good way to get the blender context from wm_xr_session is found),
functionality remains the same as before.
2021-04-30 19:54:03 +09:00
63f0dcf6b7 Merge branch 'master' into temp-xr-actions-D9124 2021-04-29 15:36:47 +09:00
517a3cdad1 Adjust CMakeLists, fix typo 2021-04-29 15:32:27 +09:00
585f98784c Merge branch 'master' into xr-actions-D9124 2021-04-10 13:28:17 +09:00
c9c052aae0 Merge branch 'master' into xr-actions-D9124 2021-03-21 20:37:56 +09:00
9cfc8ebcc9 XR: Add op_name property to XrActionMapItem
Improves readability over operator ID string when displaying action
properties.
2021-03-21 20:37:05 +09:00
dfc8860502 Revert edit to blender_default.py
Leftover from keymap->actionmap refactor.
2021-03-21 20:12:32 +09:00
97c8878753 Fix warnings on Linux / gcc 2021-03-14 19:54:43 +09:00
49707f5d83 Merge branch 'master' into xr-actions-D9124 2021-03-14 19:14:50 +09:00
334114d287 XR: Cleanup after actionmap refactoring
Aside from general cleanup, changed that only user actionconfigs and
the builtin user config can be saved to blend files (the builtin
default and addon configs are excluded).
2021-03-14 19:02:34 +09:00
034dd0d702 XR: Move actions from keymaps to actionmaps
Previously, properties for XR actions were stored in keymaps but they
are now stored in a separate XR "actionmaps" system. Although the
actionmap system/API has many similarities to the keymaps, it is
significantly less complex since it does not involve any diff-ing of
default/addon/user configurations (at least at the moment).

Another big distinction between keymaps and actionmaps is that
actionmaps and properties are saved to blend files. This allows users
to set up a VR scene with actions and properties and share working
versions with others, without the need to import/export config files.
However, actionmap import/export is also supported via the addon.

There is still a fair amount of refactoring left to do but at least
this commit removes XR involvement from the keymaps while preserving
most of the existing XR action functionality (i.e. default actions
and user-configurable actions).
2021-03-07 21:40:38 +09:00
d8cf5e7f4d Merge branch 'master' into xr-actions-D9124 2021-03-07 18:54:26 +09:00
854d115d68 XR: "deselect_all" by default for raycast select 2021-03-07 18:33:19 +09:00
886cba7fe8 Fix build error when disabling WITH_XR_OPENXR 2021-03-07 18:29:46 +09:00
f21eb52ecc Merge branch 'master' into xr-actions-D9124 2021-02-16 20:15:34 +09:00
81944920a7 Fix build error on Linux / gcc 2021-02-16 20:12:57 +09:00
cf12206311 Merge branch 'master' into xr-actions-D9124 2021-02-09 00:44:48 +09:00
247267dee4 XR: Use common functions for modal_3d operators
Reduces the amount of similar code for XR invoke_3d/modal_3d
operators that manipulate view3d params.
2021-02-09 00:11:49 +09:00
2370781389 Add TODO for merging into master 2021-02-08 23:57:52 +09:00
1aecb31acc Merge branch 'master' into xr-actions-D9124 2021-01-31 23:53:02 +09:00
2092d39dfd Fix merge-related error 2021-01-31 23:51:36 +09:00
412ea63063 Merge branch 'master' into xr-actions-D9124 2021-01-31 22:31:07 +09:00
0f236af817 XR: Remove remaining use of GHOST types in RNA
It might be good to have a WM equivalent for GHOST_XrPose (e.g.
wmXrPose) since converting from location/rotation or float[7] to
GHOST_XrPose can be pretty awkward.
2021-01-31 22:07:13 +09:00
798c33ab3b XR: Start refactoring internal API
Remove unnecessary data from GHOST types and mostly eliminate use of
GHOST types at RNA level. At the WM level, action creation functions
deal with single actions (instead of multiple actions at once) to
simplify the API.
2021-01-30 12:17:50 +09:00
a87b142e51 Fix build errors after merge
Also fixes incorrect use of RNA_def_struct_name_property().
2021-01-17 19:19:41 +09:00
2ddf55f358 Merge branch 'master' into xr-actions-D9124 2021-01-17 18:45:20 +09:00
84f821f271 Merge branch 'master' into xr-actions-D9124 2020-12-13 13:52:25 +09:00
29ed6a6872 Merge branch 'master' into xr-actions-D9124 2020-11-26 13:32:35 +09:00
78563e9bf1 XR: Add "controller draw style" session setting
Allows users to choose their preferred controller visualization
(controller local axes or -Z axis ray). The enum can be extended in
the future for additional visualizations.
2020-11-25 22:57:33 +09:00
8916a04df8 XR: Restore XR object transforms at session end
If an object was constrained to a headset/controller pose during the
session, then its original transform will be restored at session end
to prevent unwanted changes to the scene. This will also occur when
toggling the constraint or changing the constrained object.
2020-11-25 22:51:58 +09:00
c9f0da5b20 XR: Adjust raycast select property behavior
Combinations of properties (extend/deselect/toggle/deselect on empty)
now match view3d.select behavior.
2020-11-25 22:32:43 +09:00
f7a72a238b Merge branch 'master' into xr-actions-D9124 2020-11-23 16:17:12 +09:00
c8db91fc93 XR: Only allow one active modal action/subaction
Prevents unwanted behavior when a modal operator is bound to multiple
inputs (e.g. when an action has multiple subaction paths). Can be
refactored in the future to support "bimanual" interaction for some
operators.
2020-11-23 16:16:41 +09:00
e089ad2b4b Merge branch 'master' into xr-actions-D9124 2020-11-22 19:40:36 +09:00
6c67d808b7 XR: Add raycast option to ignore non-selectables
Useful when user does not want non-selectable objects to block
selectable objects in raycast result.
2020-11-22 19:35:16 +09:00
d3e352a7ec Keymap I/O: Add "exec" versions of import/export
The new "exec" functions are added for the sake of the VR Scene
Inspection add-on and do not affect the behavior of the existing
keymap I/O functions.

keyconfig_export_as_data_exec() enables exporting a specified keymap
instead of all user-modified keymaps. The VR add-on uses this to
selectively export the "XR Session" add-on keymap.

keyconfig_import_as_data_exec() enables adding keymap data to an
existing keyconfig instead of creating a new keyconfig. The VR add-on
uses this to add the "XR Session" keymap to the add-on keyconfig.
2020-11-22 18:52:17 +09:00
4423ab787b XR: Improve error logs when creating actions
Include action set name in case multiple action sets have an action
with the same name.
2020-11-22 18:29:14 +09:00
57f7e1ff97 Merge branch 'master' into xr-actions-D9124 2020-11-16 18:15:35 +09:00
f8ad9c696e Merge branch 'master' into xr-actions-D9124 2020-11-15 23:52:40 +09:00
79733505bf XR: Enable switching action sets during session
Since xrSuggestInteractionProfileBindings() overwrites any existing
profile bindings, the solution is to suggest bindings from all action
sets at the same time (done just before attaching action sets to the
session).
2020-11-15 23:46:40 +09:00
b4a21355d7 Cleanup: Comments 2020-11-15 23:38:37 +09:00
d685b9ca57 Cleanup: comments, variables 2020-11-14 22:22:46 +09:00
d3b07d5ad5 XR: Support axis (vector2f) input actions 2020-11-14 15:52:41 +09:00
86faaaa934 XR: Improve raycast select in edit mode
Limit raycast test to selected objects.
2020-11-14 15:50:56 +09:00
4d5f104faf Merge branch 'master' into xr-actions-D9124 2020-11-14 01:45:59 +09:00
6fdf493028 XR: Support mesh editing with grab operator
Uses similar mechanics as object mode, but interpolation and offsets
are not yet supported.
2020-11-14 01:26:50 +09:00
43dd6ba330 XR: Ensure mesh object for edit mode raycast 2020-11-14 01:23:09 +09:00
423619fd3d Increase line width for controllers / raycast 2020-11-14 01:10:31 +09:00
6489002982 XR: Remove Z-up conversion for pose actions
Not applying an implicit Z-up conversion for OpenXR coordinates may
be better since poses may have different orientations / tracking
spaces. Users can instead apply custom pose offsets via the UI /
Python API if necessary.
2020-11-14 01:08:28 +09:00
634812e579 Merge branch 'master' into xr-actions-D9124 2020-11-11 23:42:43 +09:00
8ccdd43fc1 XR: Implement XR grab operator
Transforms selected objects' location / rotation relative to a
controller's pose. Very basic compared to the existing transform
operators (which can also be used in VR via modal_3d), but provides
a more natural interaction in VR.
2020-11-11 23:30:24 +09:00
78d7dbbad9 Merge branch 'master' into xr-actions-D9124 2020-11-08 22:55:44 +09:00
4ec85983af XR: Remove controller overlay object
Object was originally meant to visualize the controller and be drawn
by the overlay engine, however it was unused since controllers are
now drawn via draw handlers. It might be added again in the future
for drawing more complex controller geometry.
2020-11-07 21:08:17 +09:00
dc0b81bc99 XR: Add XR region type to View3D space type
Enables add-ons to draw to the XR surface and mirror window by
adding a View3D draw handler of region type 'XR' and draw type
'POST_VIEW'. Also allows individual toggling of controller drawing
and custom overlays.
2020-11-07 19:04:36 +09:00
f6e71179fe XR: Draw controller overlays in mirror view 2020-11-07 17:44:56 +09:00
36bdbe6ce3 XR: Store multiple paths in GHOST_XrActionBinding
Facilitates action binding creation debugging by narrowing
errors down to an interaction profile and action.
2020-11-07 16:46:33 +09:00
5f7285d4af XR: Check for valid stage reference space bounds
Even if the stage reference space is supported by the XR runtime, the
bounds may be invalid (0, 0) if the user did not define a tracking
space via the runtime's UI. In this case, fall back to the local
tracking space.
2020-11-07 15:19:38 +09:00
1625bb3e71 Merge branch 'master' into xr-actions-D9124 2020-11-06 23:58:06 +09:00
a399445b3c XR: Fix projection selection in edit mode
Use window region dimensions instead of XR surface dimensions. Add
winrct offset for box select.
2020-11-06 23:56:31 +09:00
f32d320e90 XR: Fix raycast deselect empty for edit mode 2020-11-06 23:42:28 +09:00
78cd4e8cee Merge branch 'master' into xr-actions-D9124 2020-11-06 21:48:15 +09:00
848c87c6d9 Fix errors after merge 2020-11-06 21:46:56 +09:00
f5ff515085 Merge branch 'master' into xr-actions-D9124 2020-11-06 21:40:58 +09:00
07a7c88918 XR: Use stage ref space for absolute tracking 2020-11-06 21:31:43 +09:00
48ec546911 XR: Add axis property to raycast select operator
Allows users to adjust the raycast axis to fit different poses and
controllers.
2020-11-06 17:13:17 +09:00
8335da48f9 Cleanup: Comments 2020-11-06 17:08:42 +09:00
8fae3debf3 Merge branch 'master' into xr-actions-D9124 2020-11-05 22:33:39 +09:00
2ed0965e97 XR: Add "absolute tracking" session setting
Enables users to define the tracking origin in a way that is not
linked to the headset position. Instead, the tracking values given by
the XR runtime are left unadjusted and a user can manually calibrate
an "origin" landmark object to adjust to their real world space.

Can be useful for applications that use external tracking systems
and those that primarily only need to use controllers (e.g. for
motion capture).
2020-11-05 22:31:34 +09:00
2b338373d7 XR: Ensure valid region for invoking operators
Check for a valid v3d, even if the area / region uses a viewport.
2020-11-04 21:33:14 +09:00
c565bb8985 XR: Use TransInfo viewmat for transform modal_3d
Fixes static variable TODO.
2020-11-04 21:30:03 +09:00
03bb02337f XR: Compare absolute input value with threshold
Trackpad / thumbstick input values range from -1 to 1, so the
absolute value must be compared against the input threshold.
2020-11-04 21:24:43 +09:00
618df6b0b7 Fix build warnings on Linux / gcc 2020-11-04 21:13:42 +09:00
0c246b2b52 Merge branch 'master' into xr-actions-D9124 2020-11-03 18:50:07 +09:00
ff2dcdb447 XR: Implement XR constraints toggle operator
Useful for quickly playing back recorded animations without
overwriting existing data.
2020-11-03 18:47:11 +09:00
73daf1f721 XR: Support auto keying XR constraint objects
If specified, headset / controller objects will auto key on animation
playback. This can be useful for virtual camera applications.
2020-11-03 17:37:41 +09:00
9c28e6e62f XR: Fix crash when reading "constraint" objects
Pointers were not being relinked from file.
2020-11-03 10:46:42 +09:00
9c288d3e20 Merge branch 'master' into xr-actions-D9124 2020-11-02 00:09:10 +09:00
86f76f46f9 XR: Remove view space limitation for transform op
Not needed now that XR supports calling operators with properties.
2020-11-02 00:04:53 +09:00
498804edc8 XR: Implement raycast select operator
Uses the same raycast method as Scene.ray_cast() and works in object
and edit mode. Although it gives users an alternative to the existing
projection-based VR selection method, it is limited to objects with
real geometry (i.e. meshes).
2020-11-01 23:50:46 +09:00
3d24ef827c Merge branch 'master' into xr-actions-D9124 2020-10-31 23:38:14 +09:00
c8be04b7f8 Cleanup: Rename controller pose properties
Makes naming consistent with controller#_object session settings.
2020-10-31 23:31:33 +09:00
58ecc0d1bf XR: Add "constraint" objects to session settings
These objects (3 in total, corresponding to headset and left/right
controllers) will have their location and rotation determined by the
associated XR pose. This provides a way for add-ons to achieve
this "VR constraint" behavior without the need to constantly query
pose information.
2020-10-31 23:00:43 +09:00
1a6d76c5c7 Remove unused parameter 2020-10-31 22:27:00 +09:00
a1333cf2c3 Merge branch 'master' into xr-actions-D9124 2020-10-29 23:51:32 +09:00
9be27de831 XR: Improve error handling / messages
Originally thought that not terminating the session for certain "non-
fatal" errors (e.g. an incorrect action path) would make sense.
However, realized that error messages can pile up this way and it
is better for user feedback and debugging to always exit the session
when encountering an OpenXR-level error.
2020-10-29 23:49:59 +09:00
a90bfa17a9 XR: Include action set name in XR event data
Needed to match keymap items with XR events.
2020-10-29 21:01:49 +09:00
d72fafd62a Merge branch 'master' into xr-actions-D9124 2020-10-28 01:05:45 +09:00
62c5f71da1 XR: Add XR identifiers to key config I/O
Allows XR action properties to be shared with others.
2020-10-28 01:04:01 +09:00
09377b4c9c Merge branch 'master' into xr-actions-D9124 2020-10-27 02:17:20 +09:00
b596d70a1f Apply formatting 2020-10-27 02:05:24 +09:00
1d86e1ff46 XR: Support operator properties for actions
Pointers to op properties are stored in the XR session state as
IDProperty* and applied upon op execution. The actual properties
themselves are stored as key map items (new "XR" and "XR Session"
key maps were added to the blender default key maps).

The "XR" key map is intended to store op properties for action sets
that are saved in add-on (e.g. the VR Scene Inspection add-on) prefs.
The "XR Session" key map is intended to store op properties for scene
action sets, with these properties used for the XR session.

In this way, scene action sets can configure properties without
worrying about overwriting properties for action sets saved in prefs.
2020-10-27 01:54:03 +09:00
3e0acdfe94 Fix build error when disabling WITH_XR_OPENXR 2020-10-27 01:30:47 +09:00
a6c5a1a2dc Merge branch 'master' into xr-actions-D9124 2020-10-21 23:59:08 +09:00
ceab20d5e5 Cleanup: Comment style 2020-10-21 23:57:09 +09:00
cb75a83df0 XR: Draw controllers via draw handler
Callbacks for controllers and other custom drawing will be registered
with the XR surface's region type (RGN_TYPE_XR_DISPLAY) and called
post-view.
2020-10-21 23:47:29 +09:00
db1cdcdafe Merge branch 'master' into xr-actions-D9124 2020-10-20 00:59:21 +09:00
297decbe1f XR: Add input threshold for float actions
Fixes button release events not being sent due to non-zero state.
2020-10-20 00:52:49 +09:00
8af91a18e0 XR: Support basic transform operators
Uses same invoke_3d / modal_3d approach as select operators.
2020-10-20 00:48:29 +09:00
9ec8ca2d55 Merge branch 'master' into xr-actions-D9124 2020-10-19 01:06:04 +09:00
5561fbf1f8 XR: Apply VR clip settings when selecting
Fixes projection matrix calculation for GPU select.
2020-10-19 01:04:04 +09:00
de026d1395 Remove unused function
Was meant to be removed in 2eb44677.
2020-10-18 15:31:15 +09:00
07e5488c61 Merge branch 'master' into xr-actions-D9124 2020-10-18 15:18:51 +09:00
2eb44677dd Fix build error when disabling WITH_XR_OPENXR 2020-10-18 15:11:12 +09:00
3e33c89828 Fix build error on Linux / gcc 2020-10-18 15:06:12 +09:00
f2385a3f05 Merge branch 'master' into xr-actions-D9124
# Conflicts:
#	source/blender/windowmanager/intern/wm_event_system.c
2020-10-17 23:42:47 +09:00
f6a7d5336b XR: Add "selection eye" session setting
The "selection eye" is the XR eye (view) used for 3D-to-2D projection.
Its parameters are used to override the window view when selecting
with VR controllers.
2020-10-17 11:59:50 +09:00
336c8a628a Merge branch 'master' into xr-actions-D9124 2020-10-15 00:43:31 +09:00
66e22a2ed7 Operators: Add modal_3d() and implement for box select
This follows the same logic as invoke_3d(). That is, we wrap an
operator's modal() with modal_3d() and project 3D controller coords to
2D mouse coords.
2020-10-15 00:41:34 +09:00
6920906f75 XR: Remove "replace existing" param from action bindings creation
Since action bindings are only created once at the beginning of an XR
session, overwriting all existing bindings will not be needed.
2020-10-15 00:23:48 +09:00
ae1d8f4c35 Fix: Use correct add-on branch for 'make update'
Credit to Julian Eisel for the fix.
2020-10-14 08:47:14 +09:00
e0eafd2757 XR: Add selection outline offscreen draw flag 2020-10-13 21:39:03 +09:00
5e8d3f6d28 Operators: Add invoke_3d() and implement for VIEW3D_OT_select 2020-10-13 21:39:03 +09:00
090c1b7dda Disable XR object saving and (for now) creation 2020-10-13 21:39:03 +09:00
f126ce2d5b Add safety checks when accessing XR window and controller objects. 2020-10-13 21:39:03 +09:00
3b3955d9e2 Update comment. 2020-10-13 21:39:03 +09:00
9c9081bf83 Fix annotations not being shown in XR view. 2020-10-13 21:39:03 +09:00
cfc5c1b46d Improve error logging and controller data management. 2020-10-13 21:39:03 +09:00
45194962c1 Add wm_xr_operators.c. 2020-10-13 21:39:03 +09:00
921510f34f Add xr overlay and controller object. 2020-10-13 21:39:02 +09:00
d7083de46d Update controller data when setting controller pose action. 2020-10-13 21:39:02 +09:00
b44173754f Fix condition for processing xr actions. 2020-10-13 21:39:02 +09:00
e0da725075 Add basic controller visualization.
Differential Revision: https://developer.blender.org/D9124
2020-10-13 21:39:02 +09:00
2161 changed files with 152498 additions and 69310 deletions

View File

@@ -403,7 +403,7 @@ option(WITH_CYCLES_CUDA_BINARIES "Build Cycles CUDA binaries" OFF)
option(WITH_CYCLES_CUBIN_COMPILER "Build cubins with nvrtc based compiler instead of nvcc" OFF)
option(WITH_CYCLES_CUDA_BUILD_SERIAL "Build cubins one after another (useful on machines with limited RAM)" OFF)
mark_as_advanced(WITH_CYCLES_CUDA_BUILD_SERIAL)
set(CYCLES_TEST_DEVICES CPU CACHE STRING "Run regression tests on the specified device types (CPU CUDA OPTIX OPENCL)" )
set(CYCLES_TEST_DEVICES CPU CACHE STRING "Run regression tests on the specified device types (CPU CUDA OPTIX)" )
set(CYCLES_CUDA_BINARIES_ARCH sm_30 sm_35 sm_37 sm_50 sm_52 sm_60 sm_61 sm_70 sm_75 sm_86 compute_75 CACHE STRING "CUDA architectures to build binaries for")
mark_as_advanced(CYCLES_CUDA_BINARIES_ARCH)
unset(PLATFORM_DEFAULT)
@@ -418,12 +418,10 @@ mark_as_advanced(WITH_CYCLES_DEBUG_NAN)
mark_as_advanced(WITH_CYCLES_NATIVE_ONLY)
option(WITH_CYCLES_DEVICE_CUDA "Enable Cycles CUDA compute support" ON)
option(WITH_CYCLES_DEVICE_OPTIX "Enable Cycles OptiX support" OFF)
option(WITH_CYCLES_DEVICE_OPENCL "Enable Cycles OpenCL compute support" ON)
option(WITH_CYCLES_NETWORK "Enable Cycles compute over network support (EXPERIMENTAL and unfinished)" OFF)
option(WITH_CYCLES_DEVICE_OPTIX "Enable Cycles OptiX support" ON)
option(WITH_CYCLES_DEVICE_HIP "Enable Cycles HIP support" OFF)
mark_as_advanced(WITH_CYCLES_DEVICE_HIP)
mark_as_advanced(WITH_CYCLES_DEVICE_CUDA)
mark_as_advanced(WITH_CYCLES_DEVICE_OPENCL)
mark_as_advanced(WITH_CYCLES_NETWORK)
option(WITH_CUDA_DYNLOAD "Dynamically load CUDA libraries at runtime" ON)
mark_as_advanced(WITH_CUDA_DYNLOAD)
@@ -825,6 +823,11 @@ if(NOT WITH_CUDA_DYNLOAD)
endif()
endif()
if(WITH_CYCLES_DEVICE_HIP)
# Currently HIP must be dynamically loaded, this may change in future toolkits
set(WITH_HIP_DYNLOAD ON)
endif()
#-----------------------------------------------------------------------------
# Check check if submodules are cloned
@@ -1598,6 +1601,9 @@ elseif(CMAKE_C_COMPILER_ID MATCHES "Clang")
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNUSED_PARAMETER -Wunused-parameter)
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_ALL -Wall)
# Using C++20 features while having C++17 as the project language isn't allowed by MSVC.
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_CXX20_DESIGNATOR -Wc++20-designator)
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_AUTOLOGICAL_COMPARE -Wno-tautological-compare)
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts)
@@ -1851,6 +1857,9 @@ elseif(WITH_CYCLES_STANDALONE)
if(WITH_CUDA_DYNLOAD)
add_subdirectory(extern/cuew)
endif()
if(WITH_HIP_DYNLOAD)
add_subdirectory(extern/hipew)
endif()
if(NOT WITH_SYSTEM_GLEW)
add_subdirectory(extern/glew)
endif()

View File

@@ -70,16 +70,18 @@
}
--- a/libavcodec/rl.c
+++ b/libavcodec/rl.c
@@ -71,7 +71,7 @@ av_cold void ff_rl_init(RLTable *rl,
@@ -71,17 +71,19 @@
av_cold void ff_rl_init_vlc(RLTable *rl, unsigned static_size)
{
int i, q;
- VLC_TYPE table[1500][2] = {{0}};
+ VLC_TYPE (*table)[2] = av_calloc(sizeof(VLC_TYPE), 1500 * 2);
VLC vlc = { .table = table, .table_allocated = static_size };
av_assert0(static_size <= FF_ARRAY_ELEMS(table));
- av_assert0(static_size <= FF_ARRAY_ELEMS(table));
+ av_assert0(static_size < 1500);
init_vlc(&vlc, 9, rl->n + 1, &rl->table_vlc[0][1], 4, 2, &rl->table_vlc[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC);
@@ -80,8 +80,10 @@ av_cold void ff_rl_init_vlc(RLTable *rl, unsigned static_size)
for (q = 0; q < 32; q++) {
int qmul = q * 2;
int qadd = (q - 1) | 1;
@@ -91,7 +93,7 @@
if (q == 0) {
qmul = 1;
@@ -113,4 +115,5 @@ av_cold void ff_rl_init_vlc(RLTable *rl, unsigned static_size)
@@ -113,4 +115,5 @@
rl->rl_vlc[q][i].run = run;
}
}

View File

@@ -33,11 +33,23 @@ FIND_PATH(OPTIX_INCLUDE_DIR
include
)
IF(EXISTS "${OPTIX_INCLUDE_DIR}/optix.h")
FILE(STRINGS "${OPTIX_INCLUDE_DIR}/optix.h" _optix_version REGEX "^#define OPTIX_VERSION[ \t].*$")
STRING(REGEX MATCHALL "[0-9]+" _optix_version ${_optix_version})
MATH(EXPR _optix_version_major "${_optix_version} / 10000")
MATH(EXPR _optix_version_minor "(${_optix_version} % 10000) / 100")
MATH(EXPR _optix_version_patch "${_optix_version} % 100")
SET(OPTIX_VERSION "${_optix_version_major}.${_optix_version_minor}.${_optix_version_patch}")
ENDIF()
# handle the QUIETLY and REQUIRED arguments and set OPTIX_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OptiX DEFAULT_MSG
OPTIX_INCLUDE_DIR)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OptiX
REQUIRED_VARS OPTIX_INCLUDE_DIR
VERSION_VAR OPTIX_VERSION)
IF(OPTIX_FOUND)
SET(OPTIX_INCLUDE_DIRS ${OPTIX_INCLUDE_DIR})
@@ -45,6 +57,7 @@ ENDIF()
MARK_AS_ADVANCED(
OPTIX_INCLUDE_DIR
OPTIX_VERSION
)
UNSET(_optix_SEARCH_DIRS)

View File

@@ -0,0 +1,66 @@
# - Find Zstd library
# Find the native Zstd includes and library
# This module defines
# ZSTD_INCLUDE_DIRS, where to find zstd.h, Set when
# ZSTD_INCLUDE_DIR is found.
# ZSTD_LIBRARIES, libraries to link against to use Zstd.
# ZSTD_ROOT_DIR, The base directory to search for Zstd.
# This can also be an environment variable.
# ZSTD_FOUND, If false, do not try to use Zstd.
#
# also defined, but not for general use are
# ZSTD_LIBRARY, where to find the Zstd library.
#=============================================================================
# Copyright 2019 Blender Foundation.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# If ZSTD_ROOT_DIR was defined in the environment, use it.
IF(NOT ZSTD_ROOT_DIR AND NOT $ENV{ZSTD_ROOT_DIR} STREQUAL "")
SET(ZSTD_ROOT_DIR $ENV{ZSTD_ROOT_DIR})
ENDIF()
SET(_zstd_SEARCH_DIRS
${ZSTD_ROOT_DIR}
)
FIND_PATH(ZSTD_INCLUDE_DIR
NAMES
zstd.h
HINTS
${_zstd_SEARCH_DIRS}
PATH_SUFFIXES
include
)
FIND_LIBRARY(ZSTD_LIBRARY
NAMES
zstd
HINTS
${_zstd_SEARCH_DIRS}
PATH_SUFFIXES
lib64 lib
)
# handle the QUIETLY and REQUIRED arguments and set ZSTD_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Zstd DEFAULT_MSG
ZSTD_LIBRARY ZSTD_INCLUDE_DIR)
IF(ZSTD_FOUND)
SET(ZSTD_LIBRARIES ${ZSTD_LIBRARY})
SET(ZSTD_INCLUDE_DIRS ${ZSTD_INCLUDE_DIR})
ENDIF()
MARK_AS_ADVANCED(
ZSTD_INCLUDE_DIR
ZSTD_LIBRARY
)

View File

@@ -441,6 +441,9 @@ if(WITH_HARU)
endif()
endif()
set(ZSTD_ROOT_DIR ${LIBDIR}/zstd)
find_package(Zstd REQUIRED)
if(EXISTS ${LIBDIR})
without_system_libs_end()
endif()

View File

@@ -99,6 +99,7 @@ endif()
find_package_wrapper(JPEG REQUIRED)
find_package_wrapper(PNG REQUIRED)
find_package_wrapper(ZLIB REQUIRED)
find_package_wrapper(Zstd REQUIRED)
find_package_wrapper(Freetype REQUIRED)
if(WITH_PYTHON)

View File

@@ -151,8 +151,8 @@ if(MSVC_CLANG) # Clangs version of cl doesn't support all flags
string(APPEND CMAKE_CXX_FLAGS " ${CXX_WARN_FLAGS} /nologo /J /Gd /EHsc -Wno-unused-command-line-argument -Wno-microsoft-enum-forward-reference ")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /nologo /J /Gd -Wno-unused-command-line-argument -Wno-microsoft-enum-forward-reference")
else()
string(APPEND CMAKE_CXX_FLAGS " /nologo /J /Gd /MP /EHsc /bigobj")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /nologo /J /Gd /MP /bigobj")
string(APPEND CMAKE_CXX_FLAGS " /nologo /J /Gd /MP /EHsc /bigobj /Zc:inline")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /nologo /J /Gd /MP /bigobj /Zc:inline")
endif()
# X64 ASAN is available and usable on MSVC 16.9 preview 4 and up)
@@ -259,7 +259,7 @@ if(NOT DEFINED LIBDIR)
else()
message(FATAL_ERROR "32 bit compiler detected, blender no longer provides pre-build libraries for 32 bit windows, please set the LIBDIR cmake variable to your own library folder")
endif()
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.29.30130)
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.30.30423)
message(STATUS "Visual Studio 2022 detected.")
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/${LIBDIR_BASE}_vc15)
elseif(MSVC_VERSION GREATER 1919)
@@ -873,3 +873,6 @@ if(WITH_HARU)
set(WITH_HARU OFF)
endif()
endif()
set(ZSTD_INCLUDE_DIRS ${LIBDIR}/zstd/include)
set(ZSTD_LIBRARIES ${LIBDIR}/zstd/lib/zstd_static.lib)

View File

@@ -5,7 +5,7 @@
update-code:
git:
submodules:
- branch: master
- branch: xr-controller-support
commit_id: HEAD
path: release/scripts/addons
- branch: master
@@ -51,11 +51,11 @@ buildbot:
gcc:
version: '9.0.0'
cuda10:
version: '10.1.0'
version: '10.1.243'
cuda11:
version: '11.4.0'
version: '11.4.1'
optix:
version: '7.1.0'
version: '7.3.0'
cmake:
default:
version: any

View File

@@ -31,6 +31,7 @@ def parse_arguments():
parser.add_argument("--no-submodules", action="store_true")
parser.add_argument("--use-tests", action="store_true")
parser.add_argument("--svn-command", default="svn")
parser.add_argument("--svn-branch", default=None)
parser.add_argument("--git-command", default="git")
parser.add_argument("--use-centos-libraries", action="store_true")
return parser.parse_args()
@@ -46,7 +47,7 @@ def svn_update(args, release_version):
svn_non_interactive = [args.svn_command, '--non-interactive']
lib_dirpath = os.path.join(get_blender_git_root(), '..', 'lib')
svn_url = make_utils.svn_libraries_base_url(release_version)
svn_url = make_utils.svn_libraries_base_url(release_version, args.svn_branch)
# Checkout precompiled libraries
if sys.platform == 'darwin':
@@ -170,26 +171,28 @@ def submodules_update(args, release_version, branch):
sys.stderr.write("git not found, can't update code\n")
sys.exit(1)
# Update submodules to latest master or appropriate release branch.
if not release_version:
branch = "master"
# Update submodules to appropriate given branch,
# falling back to master if none is given and/or found in a sub-repository.
branch_fallback = "master"
if not branch:
branch = branch_fallback
submodules = [
("release/scripts/addons", branch),
("release/scripts/addons_contrib", branch),
("release/datafiles/locale", branch),
("source/tools", branch),
("release/scripts/addons", "xr-controller-support", branch_fallback),
("release/scripts/addons_contrib", branch, branch_fallback),
("release/datafiles/locale", branch, branch_fallback),
("source/tools", branch, branch_fallback),
]
# Initialize submodules only if needed.
for submodule_path, submodule_branch in submodules:
for submodule_path, submodule_branch, submodule_branch_fallback in submodules:
if not os.path.exists(os.path.join(submodule_path, ".git")):
call([args.git_command, "submodule", "update", "--init", "--recursive"])
break
# Checkout appropriate branch and pull changes.
skip_msg = ""
for submodule_path, submodule_branch in submodules:
for submodule_path, submodule_branch, submodule_branch_fallback in submodules:
cwd = os.getcwd()
try:
os.chdir(submodule_path)
@@ -197,10 +200,20 @@ def submodules_update(args, release_version, branch):
if msg:
skip_msg += submodule_path + " skipped: " + msg + "\n"
else:
if make_utils.git_branch(args.git_command) != submodule_branch:
call([args.git_command, "fetch", "origin"])
call([args.git_command, "checkout", submodule_branch])
call([args.git_command, "pull", "--rebase", "origin", submodule_branch])
# Find a matching branch that exists.
call([args.git_command, "fetch", "origin"])
if make_utils.git_branch_exists(args.git_command, submodule_branch):
pass
elif make_utils.git_branch_exists(args.git_command, submodule_branch_fallback):
submodule_branch = submodule_branch_fallback
else:
submodule_branch = None
# Switch to branch and pull.
if submodule_branch:
if make_utils.git_branch(args.git_command) != submodule_branch:
call([args.git_command, "checkout", submodule_branch])
call([args.git_command, "pull", "--rebase", "origin", submodule_branch])
finally:
os.chdir(cwd)
@@ -214,6 +227,10 @@ if __name__ == "__main__":
# Test if we are building a specific release version.
branch = make_utils.git_branch(args.git_command)
if branch == 'HEAD':
sys.stderr.write('Blender git repository is in detached HEAD state, must be in a branch\n')
sys.exit(1)
tag = make_utils.git_tag(args.git_command)
release_version = make_utils.git_branch_release_version(branch, tag)

View File

@@ -8,14 +8,19 @@ import subprocess
import sys
def call(cmd, exit_on_error=True):
print(" ".join(cmd))
def call(cmd, exit_on_error=True, silent=False):
if not silent:
print(" ".join(cmd))
# Flush to ensure correct order output on Windows.
sys.stdout.flush()
sys.stderr.flush()
retcode = subprocess.call(cmd)
if silent:
retcode = subprocess.call(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
else:
retcode = subprocess.call(cmd)
if exit_on_error and retcode != 0:
sys.exit(retcode)
return retcode
@@ -38,6 +43,11 @@ def check_output(cmd, exit_on_error=True):
return output.strip()
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
def git_branch(git_command):
# Get current branch name.
try:
@@ -70,9 +80,11 @@ def git_branch_release_version(branch, tag):
return release_version
def svn_libraries_base_url(release_version):
def svn_libraries_base_url(release_version, branch=None):
if release_version:
svn_branch = "tags/blender-" + release_version + "-release"
elif branch:
svn_branch = "branches/" + branch
else:
svn_branch = "trunk"
return "https://svn.blender.org/svnroot/bf-blender/" + svn_branch + "/lib/"

View File

@@ -1,4 +1,4 @@
if EXIST %PYTHON% (
if EXIST "%PYTHON%" (
goto detect_python_done
)

View File

@@ -14,7 +14,7 @@ sound = aud.Sound('music.ogg')
# play the audio, this return a handle to control play/pause
handle = device.play(sound)
# if the audio is not too big and will be used often you can buffer it
sound_buffered = aud.Sound.buffer(sound)
sound_buffered = aud.Sound.cache(sound)
handle_buffered = device.play(sound_buffered)
# stop the sounds (otherwise they play until their ends)

View File

@@ -0,0 +1,40 @@
"""
This method enables conversions between Local and Pose space for bones in
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."
def rec(pbone, parent_matrix):
matrix = matrix_map[pbone.name]
## Instead of:
# pbone.matrix = matrix
# bpy.context.view_layer.update()
# Compute and assign local matrix, using the new parent matrix
if pbone.parent:
pbone.matrix_basis = pbone.bone.convert_local_to_pose(
matrix,
pbone.bone.matrix_local,
parent_matrix=parent_matrix,
parent_matrix_local=pbone.parent.bone.matrix_local,
invert=True
)
else:
pbone.matrix_basis = pbone.bone.convert_local_to_pose(
matrix,
pbone.bone.matrix_local,
invert=True
)
# Recursively process children, passing the new matrix through
for child in pbone.children:
rec(child, matrix)
# Scan all bone trees from their roots
for pbone in obj.pose.bones:
if not pbone.parent:
rec(pbone, None)

View File

@@ -1,13 +1,13 @@
sphinx==3.5.4
sphinx==4.1.1
# Sphinx dependencies that are important
Jinja2==2.11.3
Pygments==2.9.0
docutils==0.16
Jinja2==3.0.1
Pygments==2.10.0
docutils==0.17.1
snowballstemmer==2.1.0
babel==2.9.1
requests==2.25.1
requests==2.26.0
# Only needed to match the theme used for the official documentation.
# Without this theme, the default theme will be used.
sphinx_rtd_theme==0.5.2
sphinx_rtd_theme==1.0.0

View File

@@ -1039,13 +1039,17 @@ context_type_map = {
# context_member: (RNA type, is_collection)
"active_annotation_layer": ("GPencilLayer", False),
"active_bone": ("EditBone", False),
"active_file": ("FileSelectEntry", False),
"active_gpencil_frame": ("GreasePencilLayer", True),
"active_gpencil_layer": ("GPencilLayer", True),
"active_node": ("Node", False),
"active_object": ("Object", False),
"active_operator": ("Operator", False),
"active_pose_bone": ("PoseBone", False),
"active_sequence_strip": ("Sequence", False),
"active_editable_fcurve": ("FCurve", False),
"active_nla_strip": ("NlaStrip", False),
"active_nla_track": ("NlaTrack", False),
"annotation_data": ("GreasePencil", False),
"annotation_data_owner": ("ID", False),
"armature": ("Armature", False),
@@ -1074,6 +1078,7 @@ context_type_map = {
"gpencil_data": ("GreasePencil", False),
"gpencil_data_owner": ("ID", False),
"hair": ("Hair", False),
"id": ("ID", False),
"image_paint_object": ("Object", False),
"lattice": ("Lattice", False),
"light": ("Light", False),
@@ -1102,6 +1107,7 @@ context_type_map = {
"selected_editable_keyframes": ("Keyframe", True),
"selected_editable_objects": ("Object", True),
"selected_editable_sequences": ("Sequence", True),
"selected_files": ("FileSelectEntry", True),
"selected_nla_strips": ("NlaStrip", True),
"selected_nodes": ("Node", True),
"selected_objects": ("Object", True),
@@ -1198,6 +1204,7 @@ def pycontext2sphinx(basepath):
"text_context_dir",
"clip_context_dir",
"sequencer_context_dir",
"file_context_dir",
)
unique = set()
@@ -1995,7 +2002,7 @@ def write_rst_importable_modules(basepath):
"blf": "Font Drawing",
"imbuf": "Image Buffer",
"imbuf.types": "Image Buffer Types",
"gpu": "GPU Shader Module",
"gpu": "GPU Module",
"gpu.types": "GPU Types",
"gpu.matrix": "GPU Matrix Utilities",
"gpu.select": "GPU Select Utilities",

View File

@@ -67,9 +67,12 @@ endif()
if(WITH_CYCLES OR WITH_COMPOSITOR OR WITH_OPENSUBDIV)
add_subdirectory(clew)
if(WITH_CUDA_DYNLOAD)
if((WITH_CYCLES_DEVICE_CUDA OR WITH_CYCLES_DEVICE_OPTIX) AND WITH_CUDA_DYNLOAD)
add_subdirectory(cuew)
endif()
if(WITH_CYCLES_DEVICE_HIP AND WITH_HIP_DYNLOAD)
add_subdirectory(hipew)
endif()
endif()
if(WITH_GHOST_X11 AND WITH_GHOST_XDND)

View File

@@ -129,6 +129,7 @@ set(SRC
src/util/Barrier.cpp
src/util/Buffer.cpp
src/util/BufferReader.cpp
src/util/RingBuffer.cpp
src/util/StreamBuffer.cpp
src/util/ThreadPool.cpp
)
@@ -152,6 +153,7 @@ set(PUBLIC_HDR
include/devices/ThreadedDevice.h
include/Exception.h
include/file/File.h
include/file/FileInfo.h
include/file/FileManager.h
include/file/FileWriter.h
include/file/IFileInput.h
@@ -244,6 +246,7 @@ set(PUBLIC_HDR
include/util/BufferReader.h
include/util/ILockable.h
include/util/Math3D.h
include/util/RingBuffer.h
include/util/StreamBuffer.h
include/util/ThreadPool.h
)
@@ -960,7 +963,10 @@ endif()
if(BUILD_DEMOS)
include_directories(${INCLUDE})
set(DEMOS audaplay audaconvert audaremap signalgen randsounds dynamicmusic playbackmanager)
set(DEMOS audainfo audaplay audaconvert audaremap signalgen randsounds dynamicmusic playbackmanager)
add_executable(audainfo demos/audainfo.cpp)
target_link_libraries(audainfo audaspace)
add_executable(audaplay demos/audaplay.cpp)
target_link_libraries(audaplay audaspace)

View File

@@ -39,7 +39,7 @@ extern AUD_API void AUD_PlaybackManager_free(AUD_PlaybackManager* manager);
* Plays a sound through the playback manager, adding it into a category.
* \param manager The PlaybackManager object.
* \param sound The sound to be played.
* \param catKey The key of the category into which the sound will be added. If it doesn't exist a new one will be creatd.
* \param catKey The key of the category into which the sound will be added. If it doesn't exist a new one will be created.
*/
extern AUD_API void AUD_PlaybackManager_play(AUD_PlaybackManager* manager, AUD_Sound* sound, unsigned int catKey);

View File

@@ -94,6 +94,40 @@ AUD_API int AUD_Sound_getLength(AUD_Sound* sound)
return (*sound)->createReader()->getLength();
}
AUD_API int AUD_Sound_getFileStreams(AUD_Sound* sound, AUD_StreamInfo **stream_infos)
{
assert(sound);
std::shared_ptr<File> file = std::dynamic_pointer_cast<File>(*sound);
if(file)
{
try
{
auto streams = file->queryStreams();
size_t size = sizeof(AUD_StreamInfo) * streams.size();
if(!size)
{
*stream_infos = nullptr;
return 0;
}
*stream_infos = reinterpret_cast<AUD_StreamInfo*>(std::malloc(size));
std::memcpy(*stream_infos, streams.data(), size);
return streams.size();
}
catch(Exception&)
{
}
}
*stream_infos = nullptr;
return 0;
}
AUD_API sample_t* AUD_Sound_data(AUD_Sound* sound, int* length, AUD_Specs* specs)
{
assert(sound);
@@ -252,6 +286,12 @@ AUD_API AUD_Sound* AUD_Sound_bufferFile(unsigned char* buffer, int size)
return new AUD_Sound(new File(buffer, size));
}
AUD_API AUD_Sound* AUD_Sound_bufferFileStream(unsigned char* buffer, int size, int stream)
{
assert(buffer);
return new AUD_Sound(new File(buffer, size, stream));
}
AUD_API AUD_Sound* AUD_Sound_cache(AUD_Sound* sound)
{
assert(sound);
@@ -272,6 +312,12 @@ AUD_API AUD_Sound* AUD_Sound_file(const char* filename)
return new AUD_Sound(new File(filename));
}
AUD_API AUD_Sound* AUD_Sound_fileStream(const char* filename, int stream)
{
assert(filename);
return new AUD_Sound(new File(filename, stream));
}
AUD_API AUD_Sound* AUD_Sound_sawtooth(float frequency, AUD_SampleRate rate)
{
return new AUD_Sound(new Sawtooth(frequency, rate));

View File

@@ -36,7 +36,15 @@ extern AUD_API AUD_Specs AUD_Sound_getSpecs(AUD_Sound* sound);
* \return The length of the sound in samples.
* \note This function creates a reader from the sound and deletes it again.
*/
extern AUD_API int AUD_getLength(AUD_Sound* sound);
extern AUD_API int AUD_Sound_getLength(AUD_Sound* sound);
/**
* Retrieves the stream infos of a sound file.
* \param sound The sound to retrieve from which must be a file sound.
* \param infos A pointer to a AUD_StreamInfo array that will be allocated and must afterwards be freed by the caller.
* \return The number of items in the infos array.
*/
extern AUD_API int AUD_Sound_getFileStreams(AUD_Sound* sound, AUD_StreamInfo** stream_infos);
/**
* Reads a sound's samples into memory.
@@ -89,6 +97,15 @@ extern AUD_API AUD_Sound* AUD_Sound_buffer(sample_t* data, int length, AUD_Specs
*/
extern AUD_API AUD_Sound* AUD_Sound_bufferFile(unsigned char* buffer, int size);
/**
* Loads a sound file from a memory buffer.
* \param buffer The buffer which contains the sound file.
* \param size The size of the buffer.
* \param stream The index of the audio stream within the file if it contains multiple audio streams.
* \return A handle of the sound file.
*/
extern AUD_API AUD_Sound* AUD_Sound_bufferFileStream(unsigned char* buffer, int size, int stream);
/**
* Caches a sound into a memory buffer.
* \param sound The sound to cache.
@@ -103,6 +120,14 @@ extern AUD_API AUD_Sound* AUD_Sound_cache(AUD_Sound* sound);
*/
extern AUD_API AUD_Sound* AUD_Sound_file(const char* filename);
/**
* Loads a sound file.
* \param filename The filename of the sound file.
* \param stream The index of the audio stream within the file if it contains multiple audio streams.
* \return A handle of the sound file.
*/
extern AUD_API AUD_Sound* AUD_Sound_fileStream(const char* filename, int stream);
/**
* Creates a sawtooth sound.
* \param frequency The frequency of the generated sawtooth sound.

View File

@@ -86,7 +86,6 @@ AUD_API AUD_SoundInfo AUD_getInfo(AUD_Sound* sound)
info.specs.channels = AUD_CHANNELS_INVALID;
info.specs.rate = AUD_RATE_INVALID;
info.length = 0.0f;
info.start_offset = 0.0f;
try
{
@@ -96,7 +95,6 @@ AUD_API AUD_SoundInfo AUD_getInfo(AUD_Sound* sound)
{
info.specs = convSpecToC(reader->getSpecs());
info.length = reader->getLength() / (float) info.specs.rate;
info.start_offset = reader->getStartOffset();
}
}
catch(Exception&)
@@ -109,7 +107,7 @@ AUD_API AUD_SoundInfo AUD_getInfo(AUD_Sound* sound)
AUD_API float* AUD_readSoundBuffer(const char* filename, float low, float high,
float attack, float release, float threshold,
int accumulate, int additive, int square,
float sthreshold, double samplerate, int* length)
float sthreshold, double samplerate, int* length, int stream)
{
Buffer buffer;
DeviceSpecs specs;
@@ -117,7 +115,7 @@ AUD_API float* AUD_readSoundBuffer(const char* filename, float low, float high,
specs.rate = (SampleRate)samplerate;
std::shared_ptr<ISound> sound;
std::shared_ptr<ISound> file = std::shared_ptr<ISound>(new File(filename));
std::shared_ptr<ISound> file = std::shared_ptr<ISound>(new File(filename, stream));
int position = 0;
@@ -247,7 +245,7 @@ AUD_API int AUD_readSound(AUD_Sound* sound, float* buffer, int length, int sampl
buffer[i * 3] = min;
buffer[i * 3 + 1] = max;
buffer[i * 3 + 2] = sqrt(power / len); // RMS
buffer[i * 3 + 2] = std::sqrt(power / len);
if(overallmax < max)
overallmax = max;

View File

@@ -37,7 +37,7 @@ extern AUD_API float* AUD_readSoundBuffer(const char* filename, float low, float
float attack, float release, float threshold,
int accumulate, int additive, int square,
float sthreshold, double samplerate,
int* length);
int* length, int stream);
/**
* Pauses a playing sound after a specific amount of time.

View File

@@ -176,5 +176,17 @@ typedef struct
{
AUD_Specs specs;
float length;
double start_offset;
} AUD_SoundInfo;
/// Specification of a sound source.
typedef struct
{
/// Start time in seconds.
double start;
/// Duration in seconds. May be estimated or 0 if unknown.
double duration;
/// Audio data parameters.
AUD_DeviceSpecs specs;
} AUD_StreamInfo;

View File

@@ -89,10 +89,11 @@ Sound_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
self = (Sound*)type->tp_alloc(type, 0);
if(self != nullptr)
{
static const char* kwlist[] = {"filename", nullptr};
static const char* kwlist[] = {"filename", "stream", nullptr};
const char* filename = nullptr;
int stream = 0;
if(!PyArg_ParseTupleAndKeywords(args, kwds, "s:Sound", const_cast<char**>(kwlist), &filename))
if(!PyArg_ParseTupleAndKeywords(args, kwds, "s|i:Sound", const_cast<char**>(kwlist), &filename, &stream))
{
Py_DECREF(self);
return nullptr;
@@ -100,7 +101,7 @@ Sound_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
try
{
self->sound = new std::shared_ptr<ISound>(new File(filename));
self->sound = new std::shared_ptr<ISound>(new File(filename, stream));
}
catch(Exception& e)
{
@@ -407,8 +408,9 @@ static PyObject *
Sound_file(PyTypeObject* type, PyObject* args)
{
const char* filename = nullptr;
int stream = 0;
if(!PyArg_ParseTuple(args, "s:file", &filename))
if(!PyArg_ParseTuple(args, "s|i:file", &filename, &stream))
return nullptr;
Sound* self;
@@ -418,7 +420,7 @@ Sound_file(PyTypeObject* type, PyObject* args)
{
try
{
self->sound = new std::shared_ptr<ISound>(new File(filename));
self->sound = new std::shared_ptr<ISound>(new File(filename, stream));
}
catch(Exception& e)
{

View File

@@ -70,12 +70,6 @@ public:
*/
virtual int getPosition() const=0;
/**
* Returns the start offset the sound should have to line up with related sources.
* \return The required start offset in seconds.
*/
virtual double getStartOffset() const { return 0.0;}
/**
* Returns the specification of the reader.
* \return The Specs structure.

View File

@@ -23,9 +23,11 @@
*/
#include "ISound.h"
#include "FileInfo.h"
#include <string>
#include <memory>
#include <vector>
AUD_NAMESPACE_BEGIN
@@ -48,6 +50,14 @@ private:
*/
std::shared_ptr<Buffer> m_buffer;
/**
* The index of the stream within the file if it contains multiple.
* The first audio stream in the file has index 0 and the index increments by one
* for every other audio stream in the file. Other types of streams in the file
* do not count.
*/
int m_stream;
// delete copy constructor and operator=
File(const File&) = delete;
File& operator=(const File&) = delete;
@@ -57,16 +67,25 @@ public:
* Creates a new sound.
* The file is read from the file system using the given path.
* \param filename The sound file path.
* \param stream The index of the audio stream within the file if it contains multiple audio streams.
*/
File(std::string filename);
File(std::string filename, int stream = 0);
/**
* Creates a new sound.
* The file is read from memory using the supplied buffer.
* \param buffer The buffer to read from.
* \param size The size of the buffer.
* \param stream The index of the audio stream within the file if it contains multiple audio streams.
*/
File(const data_t* buffer, int size);
File(const data_t* buffer, int size, int stream = 0);
/**
* Queries the streams of the file.
* \return A vector with as many streams as there are in the file.
* \exception Exception Thrown if the file specified cannot be read.
*/
std::vector<StreamInfo> queryStreams();
virtual std::shared_ptr<IReader> createReader();
};

View File

@@ -0,0 +1,42 @@
/*******************************************************************************
* Copyright 2009-2016 Jörg Müller
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
#pragma once
/**
* @file FileInfo.h
* @ingroup file
* The FileInfo data structures.
*/
#include "respec/Specification.h"
AUD_NAMESPACE_BEGIN
/// Specification of a sound source.
struct StreamInfo
{
/// Start time in seconds.
double start;
/// Duration in seconds. May be estimated or 0 if unknown.
double duration;
/// Audio data parameters.
DeviceSpecs specs;
};
AUD_NAMESPACE_END

View File

@@ -22,12 +22,14 @@
* The FileManager class.
*/
#include "FileInfo.h"
#include "respec/Specification.h"
#include "IWriter.h"
#include <list>
#include <memory>
#include <string>
#include <vector>
AUD_NAMESPACE_BEGIN
@@ -66,18 +68,36 @@ public:
/**
* Creates a file reader for the given filename if a registed IFileInput is able to read it.
* @param filename The path to the file.
* @param stream The index of the audio stream within the file if it contains multiple audio streams.
* @return The reader created.
* @exception Exception If no file input can read the file an exception is thrown.
*/
static std::shared_ptr<IReader> createReader(std::string filename);
static std::shared_ptr<IReader> createReader(std::string filename, int stream = 0);
/**
* Creates a file reader for the given buffer if a registed IFileInput is able to read it.
* @param buffer The buffer to read the file from.
* @param stream The index of the audio stream within the file if it contains multiple audio streams.
* @return The reader created.
* @exception Exception If no file input can read the file an exception is thrown.
*/
static std::shared_ptr<IReader> createReader(std::shared_ptr<Buffer> buffer);
static std::shared_ptr<IReader> createReader(std::shared_ptr<Buffer> buffer, int stream = 0);
/**
* Queries the streams of a sound file.
* \param filename Path to the file to be read.
* \return A vector with as many streams as there are in the file.
* \exception Exception Thrown if the file specified cannot be read.
*/
static std::vector<StreamInfo> queryStreams(std::string filename);
/**
* Queries the streams of a sound file.
* \param buffer The in-memory file buffer.
* \return A vector with as many streams as there are in the file.
* \exception Exception Thrown if the file specified cannot be read.
*/
static std::vector<StreamInfo> queryStreams(std::shared_ptr<Buffer> buffer);
/**
* Creates a file writer that writes a sound to the given file path.

View File

@@ -23,9 +23,11 @@
*/
#include "Audaspace.h"
#include "FileInfo.h"
#include <memory>
#include <string>
#include <vector>
AUD_NAMESPACE_BEGIN
@@ -48,18 +50,36 @@ public:
/**
* Creates a reader for a file to be read.
* \param filename Path to the file to be read.
* \param stream The index of the audio stream within the file if it contains multiple audio streams.
* \return The reader that reads the file.
* \exception Exception Thrown if the file specified cannot be read.
*/
virtual std::shared_ptr<IReader> createReader(std::string filename)=0;
virtual std::shared_ptr<IReader> createReader(std::string filename, int stream = 0)=0;
/**
* Creates a reader for a file to be read from memory.
* \param buffer The in-memory file buffer.
* \param stream The index of the audio stream within the file if it contains multiple audio streams.
* \return The reader that reads the file.
* \exception Exception Thrown if the file specified cannot be read.
*/
virtual std::shared_ptr<IReader> createReader(std::shared_ptr<Buffer> buffer)=0;
virtual std::shared_ptr<IReader> createReader(std::shared_ptr<Buffer> buffer, int stream = 0)=0;
/**
* Queries the streams of a sound file.
* \param filename Path to the file to be read.
* \return A vector with as many streams as there are in the file.
* \exception Exception Thrown if the file specified cannot be read.
*/
virtual std::vector<StreamInfo> queryStreams(std::string filename)=0;
/**
* Queries the streams of a sound file.
* \param buffer The in-memory file buffer.
* \return A vector with as many streams as there are in the file.
* \exception Exception Thrown if the file specified cannot be read.
*/
virtual std::vector<StreamInfo> queryStreams(std::shared_ptr<Buffer> buffer)=0;
};
AUD_NAMESPACE_END

View File

@@ -67,4 +67,4 @@ public:
virtual void read(int& length, bool& eos, sample_t* buffer);
};
AUD_NAMESPACE_END
AUD_NAMESPACE_END

View File

@@ -0,0 +1,97 @@
/*******************************************************************************
* Copyright 2009-2021 Jörg Müller
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
#pragma once
/**
* @file RingBuffer.h
* @ingroup util
* The RingBuffer class.
*/
#include "Audaspace.h"
#include "Buffer.h"
#include <cstddef>
AUD_NAMESPACE_BEGIN
/**
* This class is a simple ring buffer in RAM which is 32 Byte aligned and provides
* functionality for concurrent reading and writting without locks.
*/
class AUD_API RingBuffer
{
private:
/// The buffer storing the actual data.
Buffer m_buffer;
/// The reading pointer.
volatile size_t m_read;
/// The writing pointer.
volatile size_t m_write;
// delete copy constructor and operator=
RingBuffer(const RingBuffer&) = delete;
RingBuffer& operator=(const RingBuffer&) = delete;
public:
/**
* Creates a new ring buffer.
* \param size The size of the buffer in bytes.
*/
RingBuffer(int size = 0);
/**
* Returns the pointer to the ring buffer in memory.
*/
sample_t* getBuffer() const;
/**
* Returns the size of the ring buffer in bytes.
*/
int getSize() const;
size_t getReadSize() const;
size_t getWriteSize() const;
size_t read(data_t* target, size_t size);
size_t write(data_t* source, size_t size);
/**
* Resets the ring buffer to a state where nothing has been written or read.
*/
void reset();
/**
* Resizes the ring buffer.
* \param size The new size of the ring buffer, measured in bytes.
*/
void resize(int size);
/**
* Makes sure the ring buffer has a minimum size.
* If size is >= current size, nothing will happen.
* Otherwise the ring buffer is resized with keep as parameter.
* \param size The new minimum size of the ring buffer, measured in bytes.
*/
void assureSize(int size);
};
AUD_NAMESPACE_END

View File

@@ -35,14 +35,24 @@ void FFMPEG::registerPlugin()
FileManager::registerOutput(plugin);
}
std::shared_ptr<IReader> FFMPEG::createReader(std::string filename)
std::shared_ptr<IReader> FFMPEG::createReader(std::string filename, int stream)
{
return std::shared_ptr<IReader>(new FFMPEGReader(filename));
return std::shared_ptr<IReader>(new FFMPEGReader(filename, stream));
}
std::shared_ptr<IReader> FFMPEG::createReader(std::shared_ptr<Buffer> buffer)
std::shared_ptr<IReader> FFMPEG::createReader(std::shared_ptr<Buffer> buffer, int stream)
{
return std::shared_ptr<IReader>(new FFMPEGReader(buffer));
return std::shared_ptr<IReader>(new FFMPEGReader(buffer, stream));
}
std::vector<StreamInfo> FFMPEG::queryStreams(std::string filename)
{
return FFMPEGReader(filename).queryStreams();
}
std::vector<StreamInfo> FFMPEG::queryStreams(std::shared_ptr<Buffer> buffer)
{
return FFMPEGReader(buffer).queryStreams();
}
std::shared_ptr<IWriter> FFMPEG::createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate)

View File

@@ -52,8 +52,10 @@ public:
*/
static void registerPlugin();
virtual std::shared_ptr<IReader> createReader(std::string filename);
virtual std::shared_ptr<IReader> createReader(std::shared_ptr<Buffer> buffer);
virtual std::shared_ptr<IReader> createReader(std::string filename, int stream = 0);
virtual std::shared_ptr<IReader> createReader(std::shared_ptr<Buffer> buffer, int stream = 0);
virtual std::vector<StreamInfo> queryStreams(std::string filename);
virtual std::vector<StreamInfo> queryStreams(std::shared_ptr<Buffer> buffer);
virtual std::shared_ptr<IWriter> createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
};

View File

@@ -31,6 +31,25 @@ AUD_NAMESPACE_BEGIN
#define FFMPEG_OLD_CODE
#endif
SampleFormat FFMPEGReader::convertSampleFormat(AVSampleFormat format)
{
switch(av_get_packed_sample_fmt(format))
{
case AV_SAMPLE_FMT_U8:
return FORMAT_U8;
case AV_SAMPLE_FMT_S16:
return FORMAT_S16;
case AV_SAMPLE_FMT_S32:
return FORMAT_S32;
case AV_SAMPLE_FMT_FLT:
return FORMAT_FLOAT32;
case AV_SAMPLE_FMT_DBL:
return FORMAT_FLOAT64;
default:
AUD_THROW(FileException, "FFMPEG sample format unknown.");
}
}
int FFMPEGReader::decode(AVPacket& packet, Buffer& buffer)
{
int buf_size = buffer.getSize();
@@ -68,7 +87,7 @@ int FFMPEGReader::decode(AVPacket& packet, Buffer& buffer)
for(int i = 0; i < m_frame->nb_samples; i++)
{
std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos + ((m_codecCtx->channels * i) + channel) * single_size,
m_frame->data[channel] + i * single_size, single_size);
m_frame->data[channel] + i * single_size, single_size);
}
}
}
@@ -109,7 +128,7 @@ int FFMPEGReader::decode(AVPacket& packet, Buffer& buffer)
for(int i = 0; i < m_frame->nb_samples; i++)
{
std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos + ((m_codecCtx->channels * i) + channel) * single_size,
m_frame->data[channel] + i * single_size, single_size);
m_frame->data[channel] + i * single_size, single_size);
}
}
}
@@ -123,13 +142,10 @@ int FFMPEGReader::decode(AVPacket& packet, Buffer& buffer)
return buf_pos;
}
void FFMPEGReader::init()
void FFMPEGReader::init(int stream)
{
m_position = 0;
m_start_offset = 0.0f;
m_pkgbuf_left = 0;
m_st_time = 0;
m_duration = 0;
if(avformat_find_stream_info(m_formatCtx, nullptr) < 0)
AUD_THROW(FileException, "File couldn't be read, ffmpeg couldn't find the stream info.");
@@ -137,43 +153,22 @@ void FFMPEGReader::init()
// find audio stream and codec
m_stream = -1;
double dur_sec = 0;
for(unsigned int i = 0; i < m_formatCtx->nb_streams; i++)
{
#ifdef FFMPEG_OLD_CODE
if(m_formatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
if((m_formatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
#else
if(m_formatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
if((m_formatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
#endif
&& (m_stream < 0))
{
AVStream *audio_stream = m_formatCtx->streams[i];
double audio_timebase = av_q2d(audio_stream->time_base);
if (audio_stream->start_time != AV_NOPTS_VALUE)
if(stream == 0)
{
m_st_time = audio_stream->start_time;
}
int64_t ctx_start_time = 0;
if (m_formatCtx->start_time != AV_NOPTS_VALUE) {
ctx_start_time = m_formatCtx->start_time;
}
m_start_offset = m_st_time * audio_timebase - (double)ctx_start_time / AV_TIME_BASE;
if(audio_stream->duration != AV_NOPTS_VALUE)
{
dur_sec = audio_stream->duration * audio_timebase;
m_stream=i;
break;
}
else
{
/* If the audio starts after the stream start time, subract this from the total duration. */
dur_sec = (double)m_formatCtx->duration / AV_TIME_BASE - m_start_offset;
}
m_stream=i;
break;
stream--;
}
}
@@ -242,10 +237,9 @@ void FFMPEGReader::init()
}
m_specs.rate = (SampleRate) m_codecCtx->sample_rate;
m_duration = lround(dur_sec * m_codecCtx->sample_rate);
}
FFMPEGReader::FFMPEGReader(std::string filename) :
FFMPEGReader::FFMPEGReader(std::string filename, int stream) :
m_pkgbuf(),
m_formatCtx(nullptr),
m_codecCtx(nullptr),
@@ -259,7 +253,7 @@ FFMPEGReader::FFMPEGReader(std::string filename) :
try
{
init();
init(stream);
}
catch(Exception&)
{
@@ -268,7 +262,7 @@ FFMPEGReader::FFMPEGReader(std::string filename) :
}
}
FFMPEGReader::FFMPEGReader(std::shared_ptr<Buffer> buffer) :
FFMPEGReader::FFMPEGReader(std::shared_ptr<Buffer> buffer, int stream) :
m_pkgbuf(),
m_codecCtx(nullptr),
m_frame(nullptr),
@@ -295,7 +289,7 @@ FFMPEGReader::FFMPEGReader(std::shared_ptr<Buffer> buffer) :
try
{
init();
init(stream);
}
catch(Exception&)
{
@@ -318,6 +312,51 @@ FFMPEGReader::~FFMPEGReader()
avformat_close_input(&m_formatCtx);
}
std::vector<StreamInfo> FFMPEGReader::queryStreams()
{
std::vector<StreamInfo> result;
for(unsigned int i = 0; i < m_formatCtx->nb_streams; i++)
{
#ifdef FFMPEG_OLD_CODE
if(m_formatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
#else
if(m_formatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
#endif
{
StreamInfo info;
double time_base = av_q2d(m_formatCtx->streams[i]->time_base);
if(m_formatCtx->streams[i]->start_time != AV_NOPTS_VALUE)
info.start = m_formatCtx->streams[i]->start_time * time_base;
else
info.start = 0;
if(m_formatCtx->streams[i]->duration != AV_NOPTS_VALUE)
info.duration = m_formatCtx->streams[i]->duration * time_base;
else if(m_formatCtx->duration != AV_NOPTS_VALUE)
info.duration = double(m_formatCtx->duration) / AV_TIME_BASE - info.start;
else
info.duration = 0;
#ifdef FFMPEG_OLD_CODE
info.specs.channels = Channels(m_formatCtx->streams[i]->codec->channels);
info.specs.rate = m_formatCtx->streams[i]->codec->sample_rate;
info.specs.format = convertSampleFormat(m_formatCtx->streams[i]->codec->sample_fmt);
#else
info.specs.channels = Channels(m_formatCtx->streams[i]->codecpar->channels);
info.specs.rate = m_formatCtx->streams[i]->codecpar->sample_rate;
info.specs.format = convertSampleFormat(AVSampleFormat(m_formatCtx->streams[i]->codecpar->format));
#endif
result.emplace_back(info);
}
}
return result;
}
int FFMPEGReader::read_packet(void* opaque, uint8_t* buf, int buf_size)
{
FFMPEGReader* reader = reinterpret_cast<FFMPEGReader*>(opaque);
@@ -368,18 +407,16 @@ void FFMPEGReader::seek(int position)
{
if(position >= 0)
{
double pts_time_base =
av_q2d(m_formatCtx->streams[m_stream]->time_base);
double pts_time_base = av_q2d(m_formatCtx->streams[m_stream]->time_base);
uint64_t seek_pts = (((uint64_t)position) / ((uint64_t)m_specs.rate)) / pts_time_base;
uint64_t st_time = m_formatCtx->streams[m_stream]->start_time;
uint64_t seek_pos = (uint64_t)(position / (pts_time_base * m_specs.rate));
if(m_st_time != AV_NOPTS_VALUE) {
seek_pts += m_st_time;
}
if(st_time != AV_NOPTS_VALUE)
seek_pos += st_time;
// a value < 0 tells us that seeking failed
if(av_seek_frame(m_formatCtx, m_stream, seek_pts,
AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_ANY) >= 0)
if(av_seek_frame(m_formatCtx, m_stream, seek_pos, AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_ANY) >= 0)
{
avcodec_flush_buffers(m_codecCtx);
m_position = position;
@@ -400,7 +437,7 @@ void FFMPEGReader::seek(int position)
if(packet.pts != AV_NOPTS_VALUE)
{
// calculate real position, and read to frame!
m_position = (packet.pts - m_st_time) * pts_time_base * m_specs.rate;
m_position = (packet.pts - (st_time != AV_NOPTS_VALUE ? st_time : 0)) * pts_time_base * m_specs.rate;
if(m_position < position)
{
@@ -430,8 +467,25 @@ void FFMPEGReader::seek(int position)
int FFMPEGReader::getLength() const
{
auto stream = m_formatCtx->streams[m_stream];
double time_base = av_q2d(stream->time_base);
double duration;
if(stream->duration != AV_NOPTS_VALUE)
duration = stream->duration * time_base;
else if(m_formatCtx->duration != AV_NOPTS_VALUE)
{
duration = float(m_formatCtx->duration) / AV_TIME_BASE;
if(stream->start_time != AV_NOPTS_VALUE)
duration -= stream->start_time * time_base;
}
else
duration = -1;
// return approximated remaning size
return m_duration - m_position;
return (int)(duration * m_codecCtx->sample_rate) - m_position;
}
int FFMPEGReader::getPosition() const
@@ -439,11 +493,6 @@ int FFMPEGReader::getPosition() const
return m_position;
}
double FFMPEGReader::getStartOffset() const
{
return m_start_offset;
}
Specs FFMPEGReader::getSpecs() const
{
return m_specs.specs;
@@ -480,13 +529,11 @@ void FFMPEGReader::read(int& length, bool& eos, sample_t* buffer)
// decode the package
pkgbuf_pos = decode(packet, m_pkgbuf);
if (packet.pts >= m_st_time) {
// copy to output buffer
data_size = std::min(pkgbuf_pos, left * sample_size);
m_convert((data_t*) buf, (data_t*) m_pkgbuf.getBuffer(), data_size / AUD_FORMAT_SIZE(m_specs.format));
buf += data_size / AUD_FORMAT_SIZE(m_specs.format);
left -= data_size / sample_size;
}
// copy to output buffer
data_size = std::min(pkgbuf_pos, left * sample_size);
m_convert((data_t*) buf, (data_t*) m_pkgbuf.getBuffer(), data_size / AUD_FORMAT_SIZE(m_specs.format));
buf += data_size / AUD_FORMAT_SIZE(m_specs.format);
left -= data_size / sample_size;
}
av_packet_unref(&packet);
}

View File

@@ -29,9 +29,11 @@
#include "respec/ConverterFunctions.h"
#include "IReader.h"
#include "util/Buffer.h"
#include "file/FileInfo.h"
#include <string>
#include <memory>
#include <vector>
struct AVCodecContext;
extern "C" {
@@ -54,22 +56,6 @@ private:
*/
int m_position;
/**
* The start offset in seconds relative to the media container start time.
* IE how much the sound should be delayed to be kept in sync with the rest of the containter streams.
*/
double m_start_offset;
/**
* The start time pts of the stream. All packets before this timestamp shouldn't be played back (only decoded).
*/
int64_t m_st_time;
/**
* The duration of the audio stream in samples.
*/
int64_t m_duration;
/**
* The specification of the audio data.
*/
@@ -135,6 +121,13 @@ private:
*/
bool m_tointerleave;
/**
* Converts an ffmpeg sample format to an audaspace one.
* \param format The AVSampleFormat sample format.
* \return The sample format as SampleFormat.
*/
AUD_LOCAL static SampleFormat convertSampleFormat(AVSampleFormat format);
/**
* Decodes a packet into the given buffer.
* \param packet The AVPacket to decode.
@@ -145,8 +138,9 @@ private:
/**
* Initializes the object.
* \param stream The index of the audio stream within the file if it contains multiple audio streams.
*/
AUD_LOCAL void init();
AUD_LOCAL void init(int stream);
// delete copy constructor and operator=
FFMPEGReader(const FFMPEGReader&) = delete;
@@ -156,24 +150,33 @@ public:
/**
* Creates a new reader.
* \param filename The path to the file to be read.
* \param stream The index of the audio stream within the file if it contains multiple audio streams.
* \exception Exception Thrown if the file specified does not exist or
* cannot be read with ffmpeg.
*/
FFMPEGReader(std::string filename);
FFMPEGReader(std::string filename, int stream = 0);
/**
* Creates a new reader.
* \param buffer The buffer to read from.
* \param stream The index of the audio stream within the file if it contains multiple audio streams.
* \exception Exception Thrown if the buffer specified cannot be read
* with ffmpeg.
*/
FFMPEGReader(std::shared_ptr<Buffer> buffer);
FFMPEGReader(std::shared_ptr<Buffer> buffer, int stream = 0);
/**
* Destroys the reader and closes the file.
*/
virtual ~FFMPEGReader();
/**
* Queries the streams of a sound file.
* \return A vector with as many streams as there are in the file.
* \exception Exception Thrown if the file specified cannot be read.
*/
virtual std::vector<StreamInfo> queryStreams();
/**
* Reads data to a memory buffer.
* This function is used for avio only.
@@ -198,7 +201,6 @@ public:
virtual void seek(int position);
virtual int getLength() const;
virtual int getPosition() const;
virtual double getStartOffset() const;
virtual Specs getSpecs() const;
virtual void read(int& length, bool& eos, sample_t* buffer);
};

View File

@@ -32,16 +32,26 @@ void SndFile::registerPlugin()
FileManager::registerOutput(plugin);
}
std::shared_ptr<IReader> SndFile::createReader(std::string filename)
std::shared_ptr<IReader> SndFile::createReader(std::string filename, int stream)
{
return std::shared_ptr<IReader>(new SndFileReader(filename));
}
std::shared_ptr<IReader> SndFile::createReader(std::shared_ptr<Buffer> buffer)
std::shared_ptr<IReader> SndFile::createReader(std::shared_ptr<Buffer> buffer, int stream)
{
return std::shared_ptr<IReader>(new SndFileReader(buffer));
}
std::vector<StreamInfo> SndFile::queryStreams(std::string filename)
{
return SndFileReader(filename).queryStreams();
}
std::vector<StreamInfo> SndFile::queryStreams(std::shared_ptr<Buffer> buffer)
{
return SndFileReader(buffer).queryStreams();
}
std::shared_ptr<IWriter> SndFile::createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate)
{
return std::shared_ptr<IWriter>(new SndFileWriter(filename, specs, format, codec, bitrate));

View File

@@ -52,8 +52,10 @@ public:
*/
static void registerPlugin();
virtual std::shared_ptr<IReader> createReader(std::string filename);
virtual std::shared_ptr<IReader> createReader(std::shared_ptr<Buffer> buffer);
virtual std::shared_ptr<IReader> createReader(std::string filename, int stream = 0);
virtual std::shared_ptr<IReader> createReader(std::shared_ptr<Buffer> buffer, int stream = 0);
virtual std::vector<StreamInfo> queryStreams(std::string filename);
virtual std::vector<StreamInfo> queryStreams(std::shared_ptr<Buffer> buffer);
virtual std::shared_ptr<IWriter> createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
};

View File

@@ -118,6 +118,21 @@ SndFileReader::~SndFileReader()
sf_close(m_sndfile);
}
std::vector<StreamInfo> SndFileReader::queryStreams()
{
std::vector<StreamInfo> result;
StreamInfo info;
info.start = 0;
info.duration = double(getLength()) / m_specs.rate;
info.specs.specs = m_specs;
info.specs.format = FORMAT_FLOAT32;
result.emplace_back(info);
return result;
}
bool SndFileReader::isSeekable() const
{
return m_seekable;

View File

@@ -28,9 +28,12 @@
* The SndFileReader class.
*/
#include "file/FileInfo.h"
#include <string>
#include <sndfile.h>
#include <memory>
#include <vector>
AUD_NAMESPACE_BEGIN
@@ -96,6 +99,7 @@ public:
/**
* Creates a new reader.
* \param filename The path to the file to be read.
* \param stream The index of the audio stream within the file if it contains multiple audio streams.
* \exception Exception Thrown if the file specified does not exist or
* cannot be read with libsndfile.
*/
@@ -104,6 +108,7 @@ public:
/**
* Creates a new reader.
* \param buffer The buffer to read from.
* \param stream The index of the audio stream within the file if it contains multiple audio streams.
* \exception Exception Thrown if the buffer specified cannot be read
* with libsndfile.
*/
@@ -114,6 +119,13 @@ public:
*/
virtual ~SndFileReader();
/**
* Queries the streams of a sound file.
* \return A vector with as many streams as there are in the file.
* \exception Exception Thrown if the file specified cannot be read.
*/
virtual std::vector<StreamInfo> queryStreams();
virtual bool isSeekable() const;
virtual void seek(int position);
virtual int getLength() const;

View File

@@ -23,95 +23,121 @@
AUD_NAMESPACE_BEGIN
PulseAudioDevice::PulseAudioSynchronizer::PulseAudioSynchronizer(PulseAudioDevice *device) :
m_device(device)
{
}
double PulseAudioDevice::PulseAudioSynchronizer::getPosition(std::shared_ptr<IHandle> handle)
{
pa_usec_t latency;
int negative;
AUD_pa_stream_get_latency(m_device->m_stream, &latency, &negative);
double delay = m_device->m_ring_buffer.getReadSize() / (AUD_SAMPLE_SIZE(m_device->m_specs) * m_device->m_specs.rate) + latency * 1.0e-6;
return handle->getPosition() - delay;
}
void PulseAudioDevice::updateRingBuffer()
{
unsigned int samplesize = AUD_SAMPLE_SIZE(m_specs);
std::unique_lock<std::mutex> lock(m_mixingLock);
Buffer buffer;
while(m_valid)
{
size_t size = m_ring_buffer.getWriteSize();
size_t sample_count = size / samplesize;
if(sample_count > 0)
{
size = sample_count * samplesize;
buffer.assureSize(size);
mix(reinterpret_cast<data_t*>(buffer.getBuffer()), sample_count);
m_ring_buffer.write(reinterpret_cast<data_t*>(buffer.getBuffer()), size);
}
m_mixingCondition.wait(lock);
}
}
void PulseAudioDevice::PulseAudio_state_callback(pa_context *context, void *data)
{
PulseAudioDevice* device = (PulseAudioDevice*)data;
std::lock_guard<ILockable> lock(*device);
device->m_state = AUD_pa_context_get_state(context);
AUD_pa_threaded_mainloop_signal(device->m_mainloop, 0);
}
void PulseAudioDevice::PulseAudio_request(pa_stream *stream, size_t total_bytes, void *data)
{
PulseAudioDevice* device = (PulseAudioDevice*)data;
void* buffer;
data_t* buffer;
size_t sample_size = AUD_DEVICE_SAMPLE_SIZE(device->m_specs);
while(total_bytes > 0)
{
size_t num_bytes = total_bytes;
AUD_pa_stream_begin_write(stream, &buffer, &num_bytes);
AUD_pa_stream_begin_write(stream, reinterpret_cast<void**>(&buffer), &num_bytes);
device->mix((data_t*)buffer, num_bytes / AUD_DEVICE_SAMPLE_SIZE(device->m_specs));
size_t readsamples = device->m_ring_buffer.getReadSize();
AUD_pa_stream_write(stream, buffer, num_bytes, nullptr, 0, PA_SEEK_RELATIVE);
readsamples = std::min(readsamples, size_t(num_bytes)) / sample_size;
device->m_ring_buffer.read(buffer, readsamples * sample_size);
if(readsamples * sample_size < num_bytes)
std::memset(buffer + readsamples * sample_size, 0, num_bytes - readsamples * sample_size);
if(device->m_mixingLock.try_lock())
{
device->m_mixingCondition.notify_all();
device->m_mixingLock.unlock();
}
AUD_pa_stream_write(stream, reinterpret_cast<void*>(buffer), num_bytes, nullptr, 0, PA_SEEK_RELATIVE);
total_bytes -= num_bytes;
}
}
void PulseAudioDevice::PulseAudio_underflow(pa_stream *stream, void *data)
void PulseAudioDevice::playing(bool playing)
{
PulseAudioDevice* device = (PulseAudioDevice*)data;
m_playback = playing;
DeviceSpecs specs = device->getSpecs();
if(++device->m_underflows > 4 && device->m_buffersize < AUD_DEVICE_SAMPLE_SIZE(specs) * specs.rate * 2)
{
device->m_buffersize <<= 1;
device->m_underflows = 0;
pa_buffer_attr buffer_attr;
buffer_attr.fragsize = -1U;
buffer_attr.maxlength = -1U;
buffer_attr.minreq = -1U;
buffer_attr.prebuf = -1U;
buffer_attr.tlength = device->m_buffersize;
AUD_pa_stream_set_buffer_attr(stream, &buffer_attr, nullptr, nullptr);
}
}
void PulseAudioDevice::runMixingThread()
{
for(;;)
{
{
std::lock_guard<ILockable> lock(*this);
if(shouldStop())
{
AUD_pa_stream_cork(m_stream, 1, nullptr, nullptr);
AUD_pa_stream_flush(m_stream, nullptr, nullptr);
doStop();
return;
}
}
if(AUD_pa_stream_is_corked(m_stream))
AUD_pa_stream_cork(m_stream, 0, nullptr, nullptr);
// similar to AUD_pa_mainloop_iterate(m_mainloop, false, nullptr); except with a longer timeout
AUD_pa_mainloop_prepare(m_mainloop, 1 << 14);
AUD_pa_mainloop_poll(m_mainloop);
AUD_pa_mainloop_dispatch(m_mainloop);
}
AUD_pa_threaded_mainloop_lock(m_mainloop);
AUD_pa_stream_cork(m_stream, playing ? 0 : 1, nullptr, nullptr);
AUD_pa_threaded_mainloop_unlock(m_mainloop);
}
PulseAudioDevice::PulseAudioDevice(std::string name, DeviceSpecs specs, int buffersize) :
m_synchronizer(this),
m_playback(false),
m_state(PA_CONTEXT_UNCONNECTED),
m_valid(true),
m_underflows(0)
{
m_mainloop = AUD_pa_mainloop_new();
m_mainloop = AUD_pa_threaded_mainloop_new();
m_context = AUD_pa_context_new(AUD_pa_mainloop_get_api(m_mainloop), name.c_str());
AUD_pa_threaded_mainloop_lock(m_mainloop);
m_context = AUD_pa_context_new(AUD_pa_threaded_mainloop_get_api(m_mainloop), name.c_str());
if(!m_context)
{
AUD_pa_mainloop_free(m_mainloop);
AUD_pa_threaded_mainloop_unlock(m_mainloop);
AUD_pa_threaded_mainloop_free(m_mainloop);
AUD_THROW(DeviceException, "Could not connect to PulseAudio.");
}
@@ -120,21 +146,26 @@ PulseAudioDevice::PulseAudioDevice(std::string name, DeviceSpecs specs, int buff
AUD_pa_context_connect(m_context, nullptr, PA_CONTEXT_NOFLAGS, nullptr);
AUD_pa_threaded_mainloop_start(m_mainloop);
while(m_state != PA_CONTEXT_READY)
{
switch(m_state)
{
case PA_CONTEXT_FAILED:
case PA_CONTEXT_TERMINATED:
AUD_pa_threaded_mainloop_unlock(m_mainloop);
AUD_pa_threaded_mainloop_stop(m_mainloop);
AUD_pa_context_disconnect(m_context);
AUD_pa_context_unref(m_context);
AUD_pa_mainloop_free(m_mainloop);
AUD_pa_threaded_mainloop_free(m_mainloop);
AUD_THROW(DeviceException, "Could not connect to PulseAudio.");
break;
default:
AUD_pa_mainloop_iterate(m_mainloop, true, nullptr);
AUD_pa_threaded_mainloop_wait(m_mainloop);
break;
}
}
@@ -182,16 +213,18 @@ PulseAudioDevice::PulseAudioDevice(std::string name, DeviceSpecs specs, int buff
if(!m_stream)
{
AUD_pa_threaded_mainloop_unlock(m_mainloop);
AUD_pa_threaded_mainloop_stop(m_mainloop);
AUD_pa_context_disconnect(m_context);
AUD_pa_context_unref(m_context);
AUD_pa_mainloop_free(m_mainloop);
AUD_pa_threaded_mainloop_free(m_mainloop);
AUD_THROW(DeviceException, "Could not create PulseAudio stream.");
}
AUD_pa_stream_set_write_callback(m_stream, PulseAudio_request, this);
AUD_pa_stream_set_underflow_callback(m_stream, PulseAudio_underflow, this);
buffersize *= AUD_DEVICE_SAMPLE_SIZE(m_specs);
m_buffersize = buffersize;
@@ -204,31 +237,53 @@ PulseAudioDevice::PulseAudioDevice(std::string name, DeviceSpecs specs, int buff
buffer_attr.prebuf = -1U;
buffer_attr.tlength = buffersize;
if(AUD_pa_stream_connect_playback(m_stream, nullptr, &buffer_attr, static_cast<pa_stream_flags_t>(PA_STREAM_START_CORKED | PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_ADJUST_LATENCY | PA_STREAM_AUTO_TIMING_UPDATE), nullptr, nullptr) < 0)
m_ring_buffer.resize(buffersize);
if(AUD_pa_stream_connect_playback(m_stream, nullptr, &buffer_attr, static_cast<pa_stream_flags_t>(PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_ADJUST_LATENCY | PA_STREAM_AUTO_TIMING_UPDATE), nullptr, nullptr) < 0)
{
AUD_pa_threaded_mainloop_unlock(m_mainloop);
AUD_pa_threaded_mainloop_stop(m_mainloop);
AUD_pa_context_disconnect(m_context);
AUD_pa_context_unref(m_context);
AUD_pa_mainloop_free(m_mainloop);
AUD_pa_threaded_mainloop_free(m_mainloop);
AUD_THROW(DeviceException, "Could not connect PulseAudio stream.");
}
AUD_pa_threaded_mainloop_unlock(m_mainloop);
create();
m_mixingThread = std::thread(&PulseAudioDevice::updateRingBuffer, this);
}
PulseAudioDevice::~PulseAudioDevice()
{
stopMixingThread();
m_valid = false;
m_mixingLock.lock();
m_mixingCondition.notify_all();
m_mixingLock.unlock();
m_mixingThread.join();
AUD_pa_threaded_mainloop_stop(m_mainloop);
AUD_pa_context_disconnect(m_context);
AUD_pa_context_unref(m_context);
AUD_pa_mainloop_free(m_mainloop);
AUD_pa_threaded_mainloop_free(m_mainloop);
destroy();
}
ISynchronizer *PulseAudioDevice::getSynchronizer()
{
return &m_synchronizer;
}
class PulseAudioDeviceFactory : public IDeviceFactory
{
private:

View File

@@ -26,7 +26,11 @@
* The PulseAudioDevice class.
*/
#include "devices/ThreadedDevice.h"
#include "devices/SoftwareDevice.h"
#include "util/RingBuffer.h"
#include <condition_variable>
#include <thread>
#include <pulse/pulseaudio.h>
@@ -35,17 +39,65 @@ AUD_NAMESPACE_BEGIN
/**
* This device plays back through PulseAudio, the simple direct media layer.
*/
class AUD_PLUGIN_API PulseAudioDevice : public ThreadedDevice
class AUD_PLUGIN_API PulseAudioDevice : public SoftwareDevice
{
private:
pa_mainloop* m_mainloop;
class PulseAudioSynchronizer : public DefaultSynchronizer
{
PulseAudioDevice* m_device;
public:
PulseAudioSynchronizer(PulseAudioDevice* device);
virtual double getPosition(std::shared_ptr<IHandle> handle);
};
/// Synchronizer.
PulseAudioSynchronizer m_synchronizer;
/**
* Whether there is currently playback.
*/
volatile bool m_playback;
pa_threaded_mainloop* m_mainloop;
pa_context* m_context;
pa_stream* m_stream;
pa_context_state_t m_state;
/**
* The mixing ring buffer.
*/
RingBuffer m_ring_buffer;
/**
* Whether the device is valid.
*/
bool m_valid;
int m_buffersize;
uint32_t m_underflows;
/**
* The mixing thread.
*/
std::thread m_mixingThread;
/**
* Mutex for mixing.
*/
std::mutex m_mixingLock;
/**
* Condition for mixing.
*/
std::condition_variable m_mixingCondition;
/**
* Updates the ring buffer.
*/
AUD_LOCAL void updateRingBuffer();
/**
* Reports the state of the PulseAudio server connection.
* \param context The PulseAudio context.
@@ -61,23 +113,13 @@ private:
*/
AUD_LOCAL static void PulseAudio_request(pa_stream* stream, size_t total_bytes, void* data);
/**
* Reports an underflow from the PulseAudio server.
* Automatically adjusts the latency if this happens too often.
* @param stream The PulseAudio stream.
* \param data The PulseAudio device.
*/
AUD_LOCAL static void PulseAudio_underflow(pa_stream* stream, void* data);
/**
* Streaming thread main function.
*/
AUD_LOCAL void runMixingThread();
// delete copy constructor and operator=
PulseAudioDevice(const PulseAudioDevice&) = delete;
PulseAudioDevice& operator=(const PulseAudioDevice&) = delete;
protected:
virtual void playing(bool playing);
public:
/**
* Opens the PulseAudio audio device for playback.
@@ -93,6 +135,8 @@ public:
*/
virtual ~PulseAudioDevice();
virtual ISynchronizer* getSynchronizer();
/**
* Registers this plugin.
*/

View File

@@ -25,6 +25,7 @@ PULSEAUDIO_SYMBOL(pa_stream_begin_write);
PULSEAUDIO_SYMBOL(pa_stream_connect_playback);
PULSEAUDIO_SYMBOL(pa_stream_cork);
PULSEAUDIO_SYMBOL(pa_stream_flush);
PULSEAUDIO_SYMBOL(pa_stream_get_latency);
PULSEAUDIO_SYMBOL(pa_stream_is_corked);
PULSEAUDIO_SYMBOL(pa_stream_new);
PULSEAUDIO_SYMBOL(pa_stream_set_buffer_attr);
@@ -39,3 +40,13 @@ PULSEAUDIO_SYMBOL(pa_mainloop_iterate);
PULSEAUDIO_SYMBOL(pa_mainloop_prepare);
PULSEAUDIO_SYMBOL(pa_mainloop_poll);
PULSEAUDIO_SYMBOL(pa_mainloop_dispatch);
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_free);
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_get_api);
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_lock);
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_new);
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_signal);
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_start);
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_stop);
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_unlock);
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_wait);

View File

@@ -23,23 +23,31 @@
AUD_NAMESPACE_BEGIN
File::File(std::string filename) :
m_filename(filename)
File::File(std::string filename, int stream) :
m_filename(filename), m_stream(stream)
{
}
File::File(const data_t* buffer, int size) :
m_buffer(new Buffer(size))
File::File(const data_t* buffer, int size, int stream) :
m_buffer(new Buffer(size)), m_stream(stream)
{
std::memcpy(m_buffer->getBuffer(), buffer, size);
}
std::vector<StreamInfo> File::queryStreams()
{
if(m_buffer.get())
return FileManager::queryStreams(m_buffer);
else
return FileManager::queryStreams(m_filename);
}
std::shared_ptr<IReader> File::createReader()
{
if(m_buffer.get())
return FileManager::createReader(m_buffer);
return FileManager::createReader(m_buffer, m_stream);
else
return FileManager::createReader(m_filename);
return FileManager::createReader(m_filename, m_stream);
}
AUD_NAMESPACE_END

View File

@@ -43,13 +43,13 @@ void FileManager::registerOutput(std::shared_ptr<aud::IFileOutput> output)
outputs().push_back(output);
}
std::shared_ptr<IReader> FileManager::createReader(std::string filename)
std::shared_ptr<IReader> FileManager::createReader(std::string filename, int stream)
{
for(std::shared_ptr<IFileInput> input : inputs())
{
try
{
return input->createReader(filename);
return input->createReader(filename, stream);
}
catch(Exception&) {}
}
@@ -57,13 +57,41 @@ std::shared_ptr<IReader> FileManager::createReader(std::string filename)
AUD_THROW(FileException, "The file couldn't be read with any installed file reader.");
}
std::shared_ptr<IReader> FileManager::createReader(std::shared_ptr<Buffer> buffer)
std::shared_ptr<IReader> FileManager::createReader(std::shared_ptr<Buffer> buffer, int stream)
{
for(std::shared_ptr<IFileInput> input : inputs())
{
try
{
return input->createReader(buffer);
return input->createReader(buffer, stream);
}
catch(Exception&) {}
}
AUD_THROW(FileException, "The file couldn't be read with any installed file reader.");
}
std::vector<StreamInfo> FileManager::queryStreams(std::string filename)
{
for(std::shared_ptr<IFileInput> input : inputs())
{
try
{
return input->queryStreams(filename);
}
catch(Exception&) {}
}
AUD_THROW(FileException, "The file couldn't be read with any installed file reader.");
}
std::vector<StreamInfo> FileManager::queryStreams(std::shared_ptr<Buffer> buffer)
{
for(std::shared_ptr<IFileInput> input : inputs())
{
try
{
return input->queryStreams(buffer);
}
catch(Exception&) {}
}

View File

@@ -57,4 +57,4 @@ void VolumeReader::read(int& length, bool& eos, sample_t* buffer)
buffer[i] = buffer[i] * m_volumeStorage->getVolume();
}
AUD_NAMESPACE_END
AUD_NAMESPACE_END

137
extern/audaspace/src/util/RingBuffer.cpp vendored Normal file
View File

@@ -0,0 +1,137 @@
/*******************************************************************************
* Copyright 2009-2021 Jörg Müller
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
#include "util/RingBuffer.h"
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define ALIGNMENT 32
#define ALIGN(a) (a + ALIGNMENT - ((long long)a & (ALIGNMENT-1)))
AUD_NAMESPACE_BEGIN
RingBuffer::RingBuffer(int size) :
m_buffer(size),
m_read(0),
m_write(0)
{
}
sample_t* RingBuffer::getBuffer() const
{
return m_buffer.getBuffer();
}
int RingBuffer::getSize() const
{
return m_buffer.getSize();
}
size_t RingBuffer::getReadSize() const
{
size_t read = m_read;
size_t write = m_write;
if(read > write)
return write + getSize() - read;
else
return write - read;
}
size_t RingBuffer::getWriteSize() const
{
size_t read = m_read;
size_t write = m_write;
if(read > write)
return read - write - 1;
else
return read + getSize() - write - 1;
}
size_t RingBuffer::read(data_t* target, size_t size)
{
size = std::min(size, getReadSize());
data_t* buffer = reinterpret_cast<data_t*>(m_buffer.getBuffer());
if(m_read + size > m_buffer.getSize())
{
size_t read_first = m_buffer.getSize() - m_read;
size_t read_second = size - read_first;
std::memcpy(target, buffer + m_read, read_first);
std::memcpy(target + read_first, buffer, read_second);
m_read = read_second;
}
else
{
std::memcpy(target, buffer + m_read, size);
m_read += size;
}
return size;
}
size_t RingBuffer::write(data_t* source, size_t size)
{
size = std::min(size, getWriteSize());
data_t* buffer = reinterpret_cast<data_t*>(m_buffer.getBuffer());
if(m_write + size > m_buffer.getSize())
{
size_t write_first = m_buffer.getSize() - m_write;
size_t write_second = size - write_first;
std::memcpy(buffer + m_write, source, write_first);
std::memcpy(buffer, source + write_first, write_second);
m_write = write_second;
}
else
{
std::memcpy(buffer + m_write, source, size);
m_write += size;
}
return size;
}
void RingBuffer::reset()
{
m_read = 0;
m_write = 0;
}
void RingBuffer::resize(int size)
{
m_buffer.resize(size);
reset();
}
void RingBuffer::assureSize(int size)
{
m_buffer.assureSize(size);
reset();
}
AUD_NAMESPACE_END

View File

@@ -645,7 +645,8 @@ typedef enum CUdevice_P2PAttribute_enum {
CU_DEVICE_P2P_ATTRIBUTE_PERFORMANCE_RANK = 0x01,
CU_DEVICE_P2P_ATTRIBUTE_ACCESS_SUPPORTED = 0x02,
CU_DEVICE_P2P_ATTRIBUTE_NATIVE_ATOMIC_SUPPORTED = 0x03,
CU_DEVICE_P2P_ATTRIBUTE_ARRAY_ACCESS_ACCESS_SUPPORTED = 0x04,
CU_DEVICE_P2P_ATTRIBUTE_ACCESS_ACCESS_SUPPORTED = 0x04,
CU_DEVICE_P2P_ATTRIBUTE_CUDA_ARRAY_ACCESS_SUPPORTED = 0x04,
} CUdevice_P2PAttribute;
typedef void (CUDA_CB *CUstreamCallback)(CUstream hStream, CUresult status, void* userData);

39
extern/hipew/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,39 @@
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# The Original Code is Copyright (C) 2021, Blender Foundation
# All rights reserved.
# ***** END GPL LICENSE BLOCK *****
set(INC
.
include
)
set(INC_SYS
)
set(SRC
src/hipew.c
include/hipew.h
)
set(LIB
)
blender_add_lib(extern_hipew "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")

1207
extern/hipew/include/hipew.h vendored Normal file

File diff suppressed because it is too large Load Diff

533
extern/hipew/src/hipew.c vendored Normal file
View File

@@ -0,0 +1,533 @@
/*
* Copyright 2011-2021 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
#ifdef _MSC_VER
# if _MSC_VER < 1900
# define snprintf _snprintf
# endif
# define popen _popen
# define pclose _pclose
# define _CRT_SECURE_NO_WARNINGS
#endif
#include <hipew.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#ifdef _WIN32
# define WIN32_LEAN_AND_MEAN
# define VC_EXTRALEAN
# include <windows.h>
/* Utility macros. */
typedef HMODULE DynamicLibrary;
# define dynamic_library_open(path) LoadLibraryA(path)
# define dynamic_library_close(lib) FreeLibrary(lib)
# define dynamic_library_find(lib, symbol) GetProcAddress(lib, symbol)
#else
# include <dlfcn.h>
typedef void* DynamicLibrary;
# define dynamic_library_open(path) dlopen(path, RTLD_NOW)
# define dynamic_library_close(lib) dlclose(lib)
# define dynamic_library_find(lib, symbol) dlsym(lib, symbol)
#endif
#define _LIBRARY_FIND_CHECKED(lib, name) \
name = (t##name *)dynamic_library_find(lib, #name); \
assert(name);
#define _LIBRARY_FIND(lib, name) \
name = (t##name *)dynamic_library_find(lib, #name);
#define HIP_LIBRARY_FIND_CHECKED(name) \
_LIBRARY_FIND_CHECKED(hip_lib, name)
#define HIP_LIBRARY_FIND(name) _LIBRARY_FIND(hip_lib, name)
static DynamicLibrary hip_lib;
/* Function definitions. */
thipGetErrorName *hipGetErrorName;
thipInit *hipInit;
thipDriverGetVersion *hipDriverGetVersion;
thipGetDevice *hipGetDevice;
thipGetDeviceCount *hipGetDeviceCount;
thipDeviceGetName *hipDeviceGetName;
thipDeviceGetAttribute *hipDeviceGetAttribute;
thipDeviceComputeCapability *hipDeviceComputeCapability;
thipDevicePrimaryCtxRetain *hipDevicePrimaryCtxRetain;
thipDevicePrimaryCtxRelease *hipDevicePrimaryCtxRelease;
thipDevicePrimaryCtxSetFlags *hipDevicePrimaryCtxSetFlags;
thipDevicePrimaryCtxGetState *hipDevicePrimaryCtxGetState;
thipDevicePrimaryCtxReset *hipDevicePrimaryCtxReset;
thipCtxCreate *hipCtxCreate;
thipCtxDestroy *hipCtxDestroy;
thipCtxPushCurrent *hipCtxPushCurrent;
thipCtxPopCurrent *hipCtxPopCurrent;
thipCtxSetCurrent *hipCtxSetCurrent;
thipCtxGetCurrent *hipCtxGetCurrent;
thipCtxGetDevice *hipCtxGetDevice;
thipCtxGetFlags *hipCtxGetFlags;
thipCtxSynchronize *hipCtxSynchronize;
thipDeviceSynchronize *hipDeviceSynchronize;
thipCtxGetCacheConfig *hipCtxGetCacheConfig;
thipCtxSetCacheConfig *hipCtxSetCacheConfig;
thipCtxGetSharedMemConfig *hipCtxGetSharedMemConfig;
thipCtxSetSharedMemConfig *hipCtxSetSharedMemConfig;
thipCtxGetApiVersion *hipCtxGetApiVersion;
thipModuleLoad *hipModuleLoad;
thipModuleLoadData *hipModuleLoadData;
thipModuleLoadDataEx *hipModuleLoadDataEx;
thipModuleUnload *hipModuleUnload;
thipModuleGetFunction *hipModuleGetFunction;
thipModuleGetGlobal *hipModuleGetGlobal;
thipModuleGetTexRef *hipModuleGetTexRef;
thipMemGetInfo *hipMemGetInfo;
thipMalloc *hipMalloc;
thipMemAllocPitch *hipMemAllocPitch;
thipFree *hipFree;
thipMemGetAddressRange *hipMemGetAddressRange;
thipHostMalloc *hipHostMalloc;
thipHostFree *hipHostFree;
thipHostGetDevicePointer *hipHostGetDevicePointer;
thipHostGetFlags *hipHostGetFlags;
thipMallocManaged *hipMallocManaged;
thipDeviceGetByPCIBusId *hipDeviceGetByPCIBusId;
thipDeviceGetPCIBusId *hipDeviceGetPCIBusId;
thipMemcpyPeer *hipMemcpyPeer;
thipMemcpyHtoD *hipMemcpyHtoD;
thipMemcpyDtoH *hipMemcpyDtoH;
thipMemcpyDtoD *hipMemcpyDtoD;
thipDrvMemcpy2DUnaligned *hipDrvMemcpy2DUnaligned;
thipMemcpyParam2D *hipMemcpyParam2D;
thipDrvMemcpy3D *hipDrvMemcpy3D;
thipMemcpyHtoDAsync *hipMemcpyHtoDAsync;
thipMemcpyDtoHAsync *hipMemcpyDtoHAsync;
thipMemcpyParam2DAsync *hipMemcpyParam2DAsync;
thipDrvMemcpy3DAsync *hipDrvMemcpy3DAsync;
thipMemsetD8 *hipMemsetD8;
thipMemsetD16 *hipMemsetD16;
thipMemsetD32 *hipMemsetD32;
thipMemsetD8Async *hipMemsetD8Async;
thipMemsetD16Async *hipMemsetD16Async;
thipMemsetD32Async *hipMemsetD32Async;
thipArrayCreate *hipArrayCreate;
thipArrayDestroy *hipArrayDestroy;
thipArray3DCreate *hipArray3DCreate;
thipStreamCreateWithFlags *hipStreamCreateWithFlags;
thipStreamCreateWithPriority *hipStreamCreateWithPriority;
thipStreamGetPriority *hipStreamGetPriority;
thipStreamGetFlags *hipStreamGetFlags;
thipStreamWaitEvent *hipStreamWaitEvent;
thipStreamAddCallback *hipStreamAddCallback;
thipStreamQuery *hipStreamQuery;
thipStreamSynchronize *hipStreamSynchronize;
thipStreamDestroy *hipStreamDestroy;
thipEventCreateWithFlags *hipEventCreateWithFlags;
thipEventRecord *hipEventRecord;
thipEventQuery *hipEventQuery;
thipEventSynchronize *hipEventSynchronize;
thipEventDestroy *hipEventDestroy;
thipEventElapsedTime *hipEventElapsedTime;
thipFuncGetAttribute *hipFuncGetAttribute;
thipFuncSetCacheConfig *hipFuncSetCacheConfig;
thipModuleLaunchKernel *hipModuleLaunchKernel;
thipDrvOccupancyMaxActiveBlocksPerMultiprocessor *hipDrvOccupancyMaxActiveBlocksPerMultiprocessor;
thipDrvOccupancyMaxActiveBlocksPerMultiprocessorWithFlags *hipDrvOccupancyMaxActiveBlocksPerMultiprocessorWithFlags;
thipModuleOccupancyMaxPotentialBlockSize *hipModuleOccupancyMaxPotentialBlockSize;
thipTexRefSetArray *hipTexRefSetArray;
thipTexRefSetAddress *hipTexRefSetAddress;
thipTexRefSetAddress2D *hipTexRefSetAddress2D;
thipTexRefSetFormat *hipTexRefSetFormat;
thipTexRefSetAddressMode *hipTexRefSetAddressMode;
thipTexRefSetFilterMode *hipTexRefSetFilterMode;
thipTexRefSetFlags *hipTexRefSetFlags;
thipTexRefGetAddress *hipTexRefGetAddress;
thipTexRefGetArray *hipTexRefGetArray;
thipTexRefGetAddressMode *hipTexRefGetAddressMode;
thipTexObjectCreate *hipTexObjectCreate;
thipTexObjectDestroy *hipTexObjectDestroy;
thipDeviceCanAccessPeer *hipDeviceCanAccessPeer;
thipCtxEnablePeerAccess *hipCtxEnablePeerAccess;
thipCtxDisablePeerAccess *hipCtxDisablePeerAccess;
thipDeviceGetP2PAttribute *hipDeviceGetP2PAttribute;
thipGraphicsUnregisterResource *hipGraphicsUnregisterResource;
thipGraphicsMapResources *hipGraphicsMapResources;
thipGraphicsUnmapResources *hipGraphicsUnmapResources;
thipGraphicsResourceGetMappedPointer *hipGraphicsResourceGetMappedPointer;
thipGraphicsGLRegisterBuffer *hipGraphicsGLRegisterBuffer;
thipGLGetDevices *hipGLGetDevices;
static DynamicLibrary dynamic_library_open_find(const char **paths) {
int i = 0;
while (paths[i] != NULL) {
DynamicLibrary lib = dynamic_library_open(paths[i]);
if (lib != NULL) {
return lib;
}
++i;
}
return NULL;
}
/* Implementation function. */
static void hipewHipExit(void) {
if (hip_lib != NULL) {
/* Ignore errors. */
dynamic_library_close(hip_lib);
hip_lib = NULL;
}
}
static int hipewHipInit(void) {
/* Library paths. */
#ifdef _WIN32
/* Expected in c:/windows/system or similar, no path needed. */
const char *hip_paths[] = {"amdhip64.dll", NULL};
#elif defined(__APPLE__)
/* Default installation path. */
const char *hip_paths[] = {"", NULL};
#else
const char *hip_paths[] = {"/opt/rocm/hip/lib/libamdhip64.so", NULL};
#endif
static int initialized = 0;
static int result = 0;
int error, driver_version;
if (initialized) {
return result;
}
initialized = 1;
error = atexit(hipewHipExit);
if (error) {
result = HIPEW_ERROR_ATEXIT_FAILED;
return result;
}
/* Load library. */
hip_lib = dynamic_library_open_find(hip_paths);
if (hip_lib == NULL) {
result = HIPEW_ERROR_OPEN_FAILED;
return result;
}
/* Fetch all function pointers. */
HIP_LIBRARY_FIND_CHECKED(hipGetErrorName);
HIP_LIBRARY_FIND_CHECKED(hipInit);
HIP_LIBRARY_FIND_CHECKED(hipDriverGetVersion);
HIP_LIBRARY_FIND_CHECKED(hipGetDevice);
HIP_LIBRARY_FIND_CHECKED(hipGetDeviceCount);
HIP_LIBRARY_FIND_CHECKED(hipDeviceGetName);
HIP_LIBRARY_FIND_CHECKED(hipDeviceGetAttribute);
HIP_LIBRARY_FIND_CHECKED(hipDeviceComputeCapability);
HIP_LIBRARY_FIND_CHECKED(hipDevicePrimaryCtxRetain);
HIP_LIBRARY_FIND_CHECKED(hipDevicePrimaryCtxRelease);
HIP_LIBRARY_FIND_CHECKED(hipDevicePrimaryCtxSetFlags);
HIP_LIBRARY_FIND_CHECKED(hipDevicePrimaryCtxGetState);
HIP_LIBRARY_FIND_CHECKED(hipDevicePrimaryCtxReset);
HIP_LIBRARY_FIND_CHECKED(hipCtxCreate);
HIP_LIBRARY_FIND_CHECKED(hipCtxDestroy);
HIP_LIBRARY_FIND_CHECKED(hipCtxPushCurrent);
HIP_LIBRARY_FIND_CHECKED(hipCtxPopCurrent);
HIP_LIBRARY_FIND_CHECKED(hipCtxSetCurrent);
HIP_LIBRARY_FIND_CHECKED(hipCtxGetCurrent);
HIP_LIBRARY_FIND_CHECKED(hipCtxGetDevice);
HIP_LIBRARY_FIND_CHECKED(hipCtxGetFlags);
HIP_LIBRARY_FIND_CHECKED(hipCtxSynchronize);
HIP_LIBRARY_FIND_CHECKED(hipDeviceSynchronize);
HIP_LIBRARY_FIND_CHECKED(hipCtxGetCacheConfig);
HIP_LIBRARY_FIND_CHECKED(hipCtxSetCacheConfig);
HIP_LIBRARY_FIND_CHECKED(hipCtxGetSharedMemConfig);
HIP_LIBRARY_FIND_CHECKED(hipCtxSetSharedMemConfig);
HIP_LIBRARY_FIND_CHECKED(hipCtxGetApiVersion);
HIP_LIBRARY_FIND_CHECKED(hipModuleLoad);
HIP_LIBRARY_FIND_CHECKED(hipModuleLoadData);
HIP_LIBRARY_FIND_CHECKED(hipModuleLoadDataEx);
HIP_LIBRARY_FIND_CHECKED(hipModuleUnload);
HIP_LIBRARY_FIND_CHECKED(hipModuleGetFunction);
HIP_LIBRARY_FIND_CHECKED(hipModuleGetGlobal);
HIP_LIBRARY_FIND_CHECKED(hipModuleGetTexRef);
HIP_LIBRARY_FIND_CHECKED(hipMemGetInfo);
HIP_LIBRARY_FIND_CHECKED(hipMalloc);
HIP_LIBRARY_FIND_CHECKED(hipMemAllocPitch);
HIP_LIBRARY_FIND_CHECKED(hipFree);
HIP_LIBRARY_FIND_CHECKED(hipMemGetAddressRange);
HIP_LIBRARY_FIND_CHECKED(hipHostMalloc);
HIP_LIBRARY_FIND_CHECKED(hipHostFree);
HIP_LIBRARY_FIND_CHECKED(hipHostGetDevicePointer);
HIP_LIBRARY_FIND_CHECKED(hipHostGetFlags);
HIP_LIBRARY_FIND_CHECKED(hipMallocManaged);
HIP_LIBRARY_FIND_CHECKED(hipDeviceGetByPCIBusId);
HIP_LIBRARY_FIND_CHECKED(hipDeviceGetPCIBusId);
HIP_LIBRARY_FIND_CHECKED(hipMemcpyPeer);
HIP_LIBRARY_FIND_CHECKED(hipMemcpyHtoD);
HIP_LIBRARY_FIND_CHECKED(hipMemcpyDtoH);
HIP_LIBRARY_FIND_CHECKED(hipMemcpyDtoD);
HIP_LIBRARY_FIND_CHECKED(hipMemcpyParam2D);
HIP_LIBRARY_FIND_CHECKED(hipDrvMemcpy3D);
HIP_LIBRARY_FIND_CHECKED(hipMemcpyHtoDAsync);
HIP_LIBRARY_FIND_CHECKED(hipMemcpyDtoHAsync);
HIP_LIBRARY_FIND_CHECKED(hipDrvMemcpy2DUnaligned);
HIP_LIBRARY_FIND_CHECKED(hipMemcpyParam2DAsync);
HIP_LIBRARY_FIND_CHECKED(hipDrvMemcpy3DAsync);
HIP_LIBRARY_FIND_CHECKED(hipMemsetD8);
HIP_LIBRARY_FIND_CHECKED(hipMemsetD16);
HIP_LIBRARY_FIND_CHECKED(hipMemsetD32);
HIP_LIBRARY_FIND_CHECKED(hipMemsetD8Async);
HIP_LIBRARY_FIND_CHECKED(hipMemsetD16Async);
HIP_LIBRARY_FIND_CHECKED(hipMemsetD32Async);
HIP_LIBRARY_FIND_CHECKED(hipArrayCreate);
HIP_LIBRARY_FIND_CHECKED(hipArrayDestroy);
HIP_LIBRARY_FIND_CHECKED(hipArray3DCreate);
HIP_LIBRARY_FIND_CHECKED(hipStreamCreateWithFlags);
HIP_LIBRARY_FIND_CHECKED(hipStreamCreateWithPriority);
HIP_LIBRARY_FIND_CHECKED(hipStreamGetPriority);
HIP_LIBRARY_FIND_CHECKED(hipStreamGetFlags);
HIP_LIBRARY_FIND_CHECKED(hipStreamWaitEvent);
HIP_LIBRARY_FIND_CHECKED(hipStreamAddCallback);
HIP_LIBRARY_FIND_CHECKED(hipStreamQuery);
HIP_LIBRARY_FIND_CHECKED(hipStreamSynchronize);
HIP_LIBRARY_FIND_CHECKED(hipStreamDestroy);
HIP_LIBRARY_FIND_CHECKED(hipEventCreateWithFlags);
HIP_LIBRARY_FIND_CHECKED(hipEventRecord);
HIP_LIBRARY_FIND_CHECKED(hipEventQuery);
HIP_LIBRARY_FIND_CHECKED(hipEventSynchronize);
HIP_LIBRARY_FIND_CHECKED(hipEventDestroy);
HIP_LIBRARY_FIND_CHECKED(hipEventElapsedTime);
HIP_LIBRARY_FIND_CHECKED(hipFuncGetAttribute);
HIP_LIBRARY_FIND_CHECKED(hipFuncSetCacheConfig);
HIP_LIBRARY_FIND_CHECKED(hipModuleLaunchKernel);
HIP_LIBRARY_FIND_CHECKED(hipModuleOccupancyMaxPotentialBlockSize);
HIP_LIBRARY_FIND_CHECKED(hipTexRefSetArray);
HIP_LIBRARY_FIND_CHECKED(hipTexRefSetAddress);
HIP_LIBRARY_FIND_CHECKED(hipTexRefSetAddress2D);
HIP_LIBRARY_FIND_CHECKED(hipTexRefSetFormat);
HIP_LIBRARY_FIND_CHECKED(hipTexRefSetAddressMode);
HIP_LIBRARY_FIND_CHECKED(hipTexRefSetFilterMode);
HIP_LIBRARY_FIND_CHECKED(hipTexRefSetFlags);
HIP_LIBRARY_FIND_CHECKED(hipTexRefGetAddress);
HIP_LIBRARY_FIND_CHECKED(hipTexRefGetAddressMode);
HIP_LIBRARY_FIND_CHECKED(hipTexObjectCreate);
HIP_LIBRARY_FIND_CHECKED(hipTexObjectDestroy);
HIP_LIBRARY_FIND_CHECKED(hipDeviceCanAccessPeer);
HIP_LIBRARY_FIND_CHECKED(hipCtxEnablePeerAccess);
HIP_LIBRARY_FIND_CHECKED(hipCtxDisablePeerAccess);
HIP_LIBRARY_FIND_CHECKED(hipDeviceGetP2PAttribute);
#ifdef _WIN32
HIP_LIBRARY_FIND_CHECKED(hipGraphicsUnregisterResource);
HIP_LIBRARY_FIND_CHECKED(hipGraphicsMapResources);
HIP_LIBRARY_FIND_CHECKED(hipGraphicsUnmapResources);
HIP_LIBRARY_FIND_CHECKED(hipGraphicsResourceGetMappedPointer);
HIP_LIBRARY_FIND_CHECKED(hipGraphicsGLRegisterBuffer);
HIP_LIBRARY_FIND_CHECKED(hipGLGetDevices);
#endif
result = HIPEW_SUCCESS;
return result;
}
int hipewInit(hipuint32_t flags) {
int result = HIPEW_SUCCESS;
if (flags & HIPEW_INIT_HIP) {
result = hipewHipInit();
if (result != HIPEW_SUCCESS) {
return result;
}
}
return result;
}
const char *hipewErrorString(hipError_t result) {
switch (result) {
case hipSuccess: return "No errors";
case hipErrorInvalidValue: return "Invalid value";
case hipErrorOutOfMemory: return "Out of memory";
case hipErrorNotInitialized: return "Driver not initialized";
case hipErrorDeinitialized: return "Driver deinitialized";
case hipErrorProfilerDisabled: return "Profiler disabled";
case hipErrorProfilerNotInitialized: return "Profiler not initialized";
case hipErrorProfilerAlreadyStarted: return "Profiler already started";
case hipErrorProfilerAlreadyStopped: return "Profiler already stopped";
case hipErrorNoDevice: return "No HIP-capable device available";
case hipErrorInvalidDevice: return "Invalid device";
case hipErrorInvalidImage: return "Invalid kernel image";
case hipErrorInvalidContext: return "Invalid context";
case hipErrorContextAlreadyCurrent: return "Context already current";
case hipErrorMapFailed: return "Map failed";
case hipErrorUnmapFailed: return "Unmap failed";
case hipErrorArrayIsMapped: return "Array is mapped";
case hipErrorAlreadyMapped: return "Already mapped";
case hipErrorNoBinaryForGpu: return "No binary for GPU";
case hipErrorAlreadyAcquired: return "Already acquired";
case hipErrorNotMapped: return "Not mapped";
case hipErrorNotMappedAsArray: return "Mapped resource not available for access as an array";
case hipErrorNotMappedAsPointer: return "Mapped resource not available for access as a pointer";
case hipErrorECCNotCorrectable: return "Uncorrectable ECC error detected";
case hipErrorUnsupportedLimit: return "hipLimit_t not supported by device";
case hipErrorContextAlreadyInUse: return "Context already in use";
case hipErrorPeerAccessUnsupported: return "Peer access unsupported";
case hipErrorInvalidKernelFile: return "Invalid ptx";
case hipErrorInvalidGraphicsContext: return "Invalid graphics context";
case hipErrorInvalidSource: return "Invalid source";
case hipErrorFileNotFound: return "File not found";
case hipErrorSharedObjectSymbolNotFound: return "Link to a shared object failed to resolve";
case hipErrorSharedObjectInitFailed: return "Shared object initialization failed";
case hipErrorOperatingSystem: return "Operating system";
case hipErrorInvalidHandle: return "Invalid handle";
case hipErrorNotFound: return "Not found";
case hipErrorNotReady: return "HIP not ready";
case hipErrorIllegalAddress: return "Illegal address";
case hipErrorLaunchOutOfResources: return "Launch exceeded resources";
case hipErrorLaunchTimeOut: return "Launch exceeded timeout";
case hipErrorPeerAccessAlreadyEnabled: return "Peer access already enabled";
case hipErrorPeerAccessNotEnabled: return "Peer access not enabled";
case hipErrorSetOnActiveProcess: return "Primary context active";
case hipErrorAssert: return "Assert";
case hipErrorHostMemoryAlreadyRegistered: return "Host memory already registered";
case hipErrorHostMemoryNotRegistered: return "Host memory not registered";
case hipErrorLaunchFailure: return "Launch failed";
case hipErrorCooperativeLaunchTooLarge: return "Cooperative launch too large";
case hipErrorNotSupported: return "Not supported";
case hipErrorUnknown: return "Unknown error";
default: return "Unknown HIP error value";
}
}
static void path_join(const char *path1,
const char *path2,
int maxlen,
char *result) {
#if defined(WIN32) || defined(_WIN32)
const char separator = '\\';
#else
const char separator = '/';
#endif
int n = snprintf(result, maxlen, "%s%c%s", path1, separator, path2);
if (n != -1 && n < maxlen) {
result[n] = '\0';
}
else {
result[maxlen - 1] = '\0';
}
}
static int path_exists(const char *path) {
struct stat st;
if (stat(path, &st)) {
return 0;
}
return 1;
}
const char *hipewCompilerPath(void) {
#ifdef _WIN32
const char *hipPath = getenv("HIP_ROCCLR_HOME");
const char *windowsCommand = "perl ";
const char *executable = "bin/hipcc";
static char hipcc[65536];
static char finalCommand[65536];
if(hipPath) {
path_join(hipPath, executable, sizeof(hipcc), hipcc);
if(path_exists(hipcc)) {
snprintf(finalCommand, sizeof(hipcc), "%s %s", windowsCommand, hipcc);
return finalCommand;
} else {
printf("Could not find hipcc. Make sure HIP_ROCCLR_HOME points to the directory holding /bin/hipcc");
}
}
#else
const char *hipPath = "opt/rocm/hip/bin";
const char *executable = "hipcc";
static char hipcc[65536];
if(hipPath) {
path_join(hipPath, executable, sizeof(hipcc), hipcc);
if(path_exists(hipcc)){
return hipcc;
}
}
#endif
{
#ifdef _WIN32
FILE *handle = popen("where hipcc", "r");
#else
FILE *handle = popen("which hipcc", "r");
#endif
if (handle) {
char buffer[4096] = {0};
int len = fread(buffer, 1, sizeof(buffer) - 1, handle);
buffer[len] = '\0';
pclose(handle);
if (buffer[0]) {
return "hipcc";
}
}
}
return NULL;
}
int hipewCompilerVersion(void) {
const char *path = hipewCompilerPath();
const char *marker = "Hip compilation tools, release ";
FILE *pipe;
int major, minor;
char *versionstr;
char buf[128];
char output[65536] = "\0";
char command[65536] = "\0";
if (path == NULL) {
return 0;
}
/* get --version output */
strcat(command, "\"");
strncat(command, path, sizeof(command) - 1);
strncat(command, "\" --version", sizeof(command) - strlen(path) - 1);
pipe = popen(command, "r");
if (!pipe) {
fprintf(stderr, "HIP: failed to run compiler to retrieve version");
return 0;
}
while (!feof(pipe)) {
if (fgets(buf, sizeof(buf), pipe) != NULL) {
strncat(output, buf, sizeof(output) - strlen(output) - 1);
}
}
pclose(pipe);
return 40;
}

5
extern/json/README.blender vendored Normal file
View File

@@ -0,0 +1,5 @@
Project: JSON
URL: https://github.com/nlohmann/json/
License: MIT License
Upstream version: 3.10.2
Local modifications: None

26640
extern/json/include/json.hpp vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@
# YOUR INSTALLATION PATHS GO HERE:
MANTA_INSTALLATION=/Users/sebbas/Developer/Mantaflow/mantaflowDevelop
BLENDER_INSTALLATION=/Users/sebbas/Developer/Blender/fluid-mantaflow
BLENDER_INSTALLATION=/Users/sebbas/Developer/Blender
# Try to check out Mantaflow repository before building?
CLEAN_REPOSITORY=0

View File

@@ -28,11 +28,13 @@ extern PyTypeObject PbVec3Type;
extern PyTypeObject PbVec4Type;
struct PbVec3 {
PyObject_HEAD float data[3];
PyObject_HEAD
float data[3];
};
struct PbVec4 {
PyObject_HEAD float data[4];
PyObject_HEAD
float data[4];
};
PyObject *getPyNone()

View File

@@ -25,7 +25,8 @@ namespace Manta {
extern PyTypeObject PbVec3Type;
struct PbVec3 {
PyObject_HEAD float data[3];
PyObject_HEAD
float data[3];
};
static void PbVec3Dealloc(PbVec3 *self)
@@ -293,7 +294,8 @@ inline PyObject *castPy(PyTypeObject *p)
extern PyTypeObject PbVec4Type;
struct PbVec4 {
PyObject_HEAD float data[4];
PyObject_HEAD
float data[4];
};
static PyMethodDef PbVec4Methods[] = {

View File

@@ -76,7 +76,8 @@ struct ClassData {
};
struct PbObject {
PyObject_HEAD Manta::PbClass *instance;
PyObject_HEAD
Manta::PbClass *instance;
ClassData *classdef;
};

View File

@@ -874,6 +874,136 @@ static const Vec3i nb[6] = {Vec3i(1, 0, 0),
Vec3i(0, 0, 1),
Vec3i(0, 0, -1)};
struct knMarkSkipCells : public KernelBase {
knMarkSkipCells(Grid<Real> &phi, Grid<int> &tmp, bool inside)
: KernelBase(&phi, 1), phi(phi), tmp(tmp), inside(inside)
{
runMessage();
run();
}
inline void op(int i, int j, int k, Grid<Real> &phi, Grid<int> &tmp, bool inside) const
{
if (!inside && phi(i, j, k) < 0.) {
tmp(i, j, k) = 1;
}
if (inside && phi(i, j, k) > 0.) {
tmp(i, j, k) = 1;
}
}
inline Grid<Real> &getArg0()
{
return phi;
}
typedef Grid<Real> type0;
inline Grid<int> &getArg1()
{
return tmp;
}
typedef Grid<int> type1;
inline bool &getArg2()
{
return inside;
}
typedef bool type2;
void runMessage()
{
debMsg("Executing kernel knMarkSkipCells ", 3);
debMsg("Kernel range"
<< " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ",
4);
};
void operator()(const tbb::blocked_range<IndexInt> &__r) const
{
const int _maxX = maxX;
const int _maxY = maxY;
if (maxZ > 1) {
for (int k = __r.begin(); k != (int)__r.end(); k++)
for (int j = 1; j < _maxY; j++)
for (int i = 1; i < _maxX; i++)
op(i, j, k, phi, tmp, inside);
}
else {
const int k = 0;
for (int j = __r.begin(); j != (int)__r.end(); j++)
for (int i = 1; i < _maxX; i++)
op(i, j, k, phi, tmp, inside);
}
}
void run()
{
if (maxZ > 1)
tbb::parallel_for(tbb::blocked_range<IndexInt>(minZ, maxZ), *this);
else
tbb::parallel_for(tbb::blocked_range<IndexInt>(1, maxY), *this);
}
Grid<Real> &phi;
Grid<int> &tmp;
bool inside;
};
struct knSetFirstLayer : public KernelBase {
knSetFirstLayer(Grid<int> &tmp, int dim) : KernelBase(&tmp, 1), tmp(tmp), dim(dim)
{
runMessage();
run();
}
inline void op(int i, int j, int k, Grid<int> &tmp, int dim) const
{
Vec3i p(i, j, k);
if (tmp(p))
return;
for (int n = 0; n < 2 * dim; ++n) {
if (tmp(p + nb[n]) == 1) {
tmp(i, j, k) = 2;
break;
}
}
}
inline Grid<int> &getArg0()
{
return tmp;
}
typedef Grid<int> type0;
inline int &getArg1()
{
return dim;
}
typedef int type1;
void runMessage()
{
debMsg("Executing kernel knSetFirstLayer ", 3);
debMsg("Kernel range"
<< " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ",
4);
};
void operator()(const tbb::blocked_range<IndexInt> &__r) const
{
const int _maxX = maxX;
const int _maxY = maxY;
if (maxZ > 1) {
for (int k = __r.begin(); k != (int)__r.end(); k++)
for (int j = 1; j < _maxY; j++)
for (int i = 1; i < _maxX; i++)
op(i, j, k, tmp, dim);
}
else {
const int k = 0;
for (int j = __r.begin(); j != (int)__r.end(); j++)
for (int i = 1; i < _maxX; i++)
op(i, j, k, tmp, dim);
}
}
void run()
{
if (maxZ > 1)
tbb::parallel_for(tbb::blocked_range<IndexInt>(minZ, maxZ), *this);
else
tbb::parallel_for(tbb::blocked_range<IndexInt>(1, maxY), *this);
}
Grid<int> &tmp;
int dim;
};
template<class S> struct knExtrapolateLsSimple : public KernelBase {
knExtrapolateLsSimple(Grid<S> &val, int distance, Grid<int> &tmp, const int d, S direction)
: KernelBase(&val, 1), val(val), distance(distance), tmp(tmp), d(d), direction(direction)
@@ -1043,39 +1173,12 @@ void extrapolateLsSimple(Grid<Real> &phi, int distance = 4, bool inside = false)
tmp.clear();
const int dim = (phi.is3D() ? 3 : 2);
// by default, march outside
Real direction = 1.;
if (!inside) {
// mark all inside
FOR_IJK_BND(phi, 1)
{
if (phi(i, j, k) < 0.) {
tmp(i, j, k) = 1;
}
}
}
else {
direction = -1.;
FOR_IJK_BND(phi, 1)
{
if (phi(i, j, k) > 0.) {
tmp(i, j, k) = 1;
}
}
}
// by default, march outside (ie mark all inside to be skipped)
Real direction = (inside) ? -1. : 1.;
knMarkSkipCells(phi, tmp, inside);
// + first layer around
FOR_IJK_BND(phi, 1)
{
Vec3i p(i, j, k);
if (tmp(p))
continue;
for (int n = 0; n < 2 * dim; ++n) {
if (tmp(p + nb[n]) == 1) {
tmp(i, j, k) = 2;
n = 2 * dim;
}
}
}
knSetFirstLayer(tmp, dim);
// extrapolate for distance
for (int d = 2; d < 1 + distance; ++d) {
@@ -1126,37 +1229,12 @@ void extrapolateVec3Simple(Grid<Vec3> &vel, Grid<Real> &phi, int distance = 4, b
tmp.clear();
const int dim = (vel.is3D() ? 3 : 2);
// mark initial cells, by default, march outside
if (!inside) {
// mark all inside
FOR_IJK_BND(phi, 1)
{
if (phi(i, j, k) < 0.) {
tmp(i, j, k) = 1;
}
}
}
else {
FOR_IJK_BND(phi, 1)
{
if (phi(i, j, k) > 0.) {
tmp(i, j, k) = 1;
}
}
}
// mark initial cells, by default, march outside (ie mark all inside to be skipped)
Real direction = (inside) ? -1. : 1.;
knMarkSkipCells(phi, tmp, inside);
// + first layer next to initial cells
FOR_IJK_BND(vel, 1)
{
Vec3i p(i, j, k);
if (tmp(p))
continue;
for (int n = 0; n < 2 * dim; ++n) {
if (tmp(p + nb[n]) == 1) {
tmp(i, j, k) = 2;
n = 2 * dim;
}
}
}
knSetFirstLayer(tmp, dim);
for (int d = 2; d < 1 + distance; ++d) {
knExtrapolateLsSimple<Vec3>(vel, distance, tmp, d, Vec3(0.));

View File

@@ -1,3 +1,3 @@
#define MANTA_GIT_VERSION "commit 8fbebe02459b7f72575872c20961f7cb757db408"
#define MANTA_GIT_VERSION "commit d5d9a6c28daa8f21426d7a285f48639c0d8fd13f"

6
extern/tinygltf/README.blender vendored Normal file
View File

@@ -0,0 +1,6 @@
Project: TinyGLTF
URL: https://github.com/syoyo/tinygltf
License: MIT
Upstream version: 2.5.0, 19a41d20ec0
Local modifications:
* Silence "enum value not handled in switch" warnings due to JSON dependency.

7761
extern/tinygltf/tiny_gltf.h vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -60,9 +60,108 @@
# define JE_FORCE_SYNC_COMPARE_AND_SWAP_8
#endif
/******************************************************************************/
/* 64-bit operations. */
#if (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) || defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_8))
/* Define the `ATOMIC_FORCE_USE_FALLBACK` to force lock-based fallback implementation to be used
* (even on platforms where there is native implementation available via compiler.
* Useful for development purposes. */
#undef ATOMIC_FORCE_USE_FALLBACK
/* -------------------------------------------------------------------- */
/** \name Spin-lock implementation
*
* Used to implement atomics on unsupported platforms.
* The spin implementation is shared for all platforms to make sure it compiles and tested.
* \{ */
typedef struct AtomicSpinLock {
volatile int lock;
/* Pad the structure size to a cache-line, to avoid unwanted sharing with other data. */
int pad[32 - sizeof(int)];
} __attribute__((aligned(32))) AtomicSpinLock;
ATOMIC_INLINE void atomic_spin_lock(volatile AtomicSpinLock *lock)
{
while (__sync_lock_test_and_set(&lock->lock, 1)) {
while (lock->lock) {
}
}
}
ATOMIC_INLINE void atomic_spin_unlock(volatile AtomicSpinLock *lock)
{
__sync_lock_release(&lock->lock);
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Common part of locking fallback implementation
* \{ */
/* Global lock, shared by all atomic operations implementations.
*
* Could be split into per-size locks, although added complexity and being more error-proone does
* not seem to worth it for a fall-back implementation. */
static _ATOMIC_MAYBE_UNUSED AtomicSpinLock _atomic_global_lock = {0};
#define ATOMIC_LOCKING_OP_AND_FETCH_DEFINE(_type, _op_name, _op) \
ATOMIC_INLINE _type##_t atomic_##_op_name##_and_fetch_##_type(_type##_t *p, _type##_t x) \
{ \
atomic_spin_lock(&_atomic_global_lock); \
const _type##_t original_value = *(p); \
const _type##_t new_value = original_value _op(x); \
*(p) = new_value; \
atomic_spin_unlock(&_atomic_global_lock); \
return new_value; \
}
#define ATOMIC_LOCKING_FETCH_AND_OP_DEFINE(_type, _op_name, _op) \
ATOMIC_INLINE _type##_t atomic_fetch_and_##_op_name##_##_type(_type##_t *p, _type##_t x) \
{ \
atomic_spin_lock(&_atomic_global_lock); \
const _type##_t original_value = *(p); \
*(p) = original_value _op(x); \
atomic_spin_unlock(&_atomic_global_lock); \
return original_value; \
}
#define ATOMIC_LOCKING_ADD_AND_FETCH_DEFINE(_type) \
ATOMIC_LOCKING_OP_AND_FETCH_DEFINE(_type, add, +)
#define ATOMIC_LOCKING_SUB_AND_FETCH_DEFINE(_type) \
ATOMIC_LOCKING_OP_AND_FETCH_DEFINE(_type, sub, -)
#define ATOMIC_LOCKING_FETCH_AND_ADD_DEFINE(_type) \
ATOMIC_LOCKING_FETCH_AND_OP_DEFINE(_type, add, +)
#define ATOMIC_LOCKING_FETCH_AND_SUB_DEFINE(_type) \
ATOMIC_LOCKING_FETCH_AND_OP_DEFINE(_type, sub, -)
#define ATOMIC_LOCKING_FETCH_AND_OR_DEFINE(_type) ATOMIC_LOCKING_FETCH_AND_OP_DEFINE(_type, or, |)
#define ATOMIC_LOCKING_FETCH_AND_AND_DEFINE(_type) \
ATOMIC_LOCKING_FETCH_AND_OP_DEFINE(_type, and, &)
#define ATOMIC_LOCKING_CAS_DEFINE(_type) \
ATOMIC_INLINE _type##_t atomic_cas_##_type(_type##_t *v, _type##_t old, _type##_t _new) \
{ \
atomic_spin_lock(&_atomic_global_lock); \
const _type##_t original_value = *v; \
if (*v == old) { \
*v = _new; \
} \
atomic_spin_unlock(&_atomic_global_lock); \
return original_value; \
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name 64-bit operations
* \{ */
#if !defined(ATOMIC_FORCE_USE_FALLBACK) && \
(defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) || defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_8))
/* Unsigned */
ATOMIC_INLINE uint64_t atomic_add_and_fetch_uint64(uint64_t *p, uint64_t x)
{
@@ -115,7 +214,7 @@ ATOMIC_INLINE int64_t atomic_cas_int64(int64_t *v, int64_t old, int64_t _new)
return __sync_val_compare_and_swap(v, old, _new);
}
#elif (defined(__amd64__) || defined(__x86_64__))
#elif !defined(ATOMIC_FORCE_USE_FALLBACK) && (defined(__amd64__) || defined(__x86_64__))
/* Unsigned */
ATOMIC_INLINE uint64_t atomic_fetch_and_add_uint64(uint64_t *p, uint64_t x)
{
@@ -190,12 +289,36 @@ ATOMIC_INLINE int64_t atomic_cas_int64(int64_t *v, int64_t old, int64_t _new)
return ret;
}
#else
# error "Missing implementation for 64-bit atomic operations"
/* Unsigned */
ATOMIC_LOCKING_ADD_AND_FETCH_DEFINE(uint64)
ATOMIC_LOCKING_SUB_AND_FETCH_DEFINE(uint64)
ATOMIC_LOCKING_FETCH_AND_ADD_DEFINE(uint64)
ATOMIC_LOCKING_FETCH_AND_SUB_DEFINE(uint64)
ATOMIC_LOCKING_CAS_DEFINE(uint64)
/* Signed */
ATOMIC_LOCKING_ADD_AND_FETCH_DEFINE(int64)
ATOMIC_LOCKING_SUB_AND_FETCH_DEFINE(int64)
ATOMIC_LOCKING_FETCH_AND_ADD_DEFINE(int64)
ATOMIC_LOCKING_FETCH_AND_SUB_DEFINE(int64)
ATOMIC_LOCKING_CAS_DEFINE(int64)
#endif
/******************************************************************************/
/* 32-bit operations. */
#if (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) || defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_4))
/** \} */
/* -------------------------------------------------------------------- */
/** \name 32-bit operations
* \{ */
#if !defined(ATOMIC_FORCE_USE_FALLBACK) && \
(defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) || defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_4))
/* Unsigned */
ATOMIC_INLINE uint32_t atomic_add_and_fetch_uint32(uint32_t *p, uint32_t x)
{
@@ -228,7 +351,8 @@ ATOMIC_INLINE int32_t atomic_cas_int32(int32_t *v, int32_t old, int32_t _new)
return __sync_val_compare_and_swap(v, old, _new);
}
#elif (defined(__i386__) || defined(__amd64__) || defined(__x86_64__))
#elif !defined(ATOMIC_FORCE_USE_FALLBACK) && \
(defined(__i386__) || defined(__amd64__) || defined(__x86_64__))
/* Unsigned */
ATOMIC_INLINE uint32_t atomic_add_and_fetch_uint32(uint32_t *p, uint32_t x)
{
@@ -286,10 +410,25 @@ ATOMIC_INLINE int32_t atomic_cas_int32(int32_t *v, int32_t old, int32_t _new)
}
#else
# error "Missing implementation for 32-bit atomic operations"
/* Unsigned */
ATOMIC_LOCKING_ADD_AND_FETCH_DEFINE(uint32)
ATOMIC_LOCKING_SUB_AND_FETCH_DEFINE(uint32)
ATOMIC_LOCKING_CAS_DEFINE(uint32)
/* Signed */
ATOMIC_LOCKING_ADD_AND_FETCH_DEFINE(int32)
ATOMIC_LOCKING_SUB_AND_FETCH_DEFINE(int32)
ATOMIC_LOCKING_CAS_DEFINE(int32)
#endif
#if (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) || defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_4))
#if !defined(ATOMIC_FORCE_USE_FALLBACK) && \
(defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) || defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_4))
/* Unsigned */
ATOMIC_INLINE uint32_t atomic_fetch_and_add_uint32(uint32_t *p, uint32_t x)
{
@@ -323,12 +462,27 @@ ATOMIC_INLINE int32_t atomic_fetch_and_and_int32(int32_t *p, int32_t x)
}
#else
# error "Missing implementation for 32-bit atomic operations"
/* Unsigned */
ATOMIC_LOCKING_FETCH_AND_ADD_DEFINE(uint32)
ATOMIC_LOCKING_FETCH_AND_OR_DEFINE(uint32)
ATOMIC_LOCKING_FETCH_AND_AND_DEFINE(uint32)
/* Signed */
ATOMIC_LOCKING_FETCH_AND_ADD_DEFINE(int32)
ATOMIC_LOCKING_FETCH_AND_OR_DEFINE(int32)
ATOMIC_LOCKING_FETCH_AND_AND_DEFINE(int32)
#endif
/******************************************************************************/
/* 16-bit operations. */
#if (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) || defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_2))
/** \} */
/* -------------------------------------------------------------------- */
/** \name 16-bit operations
* \{ */
#if !defined(ATOMIC_FORCE_USE_FALLBACK) && \
(defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) || defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_2))
/* Signed */
ATOMIC_INLINE int16_t atomic_fetch_and_and_int16(int16_t *p, int16_t b)
@@ -341,12 +495,21 @@ ATOMIC_INLINE int16_t atomic_fetch_and_or_int16(int16_t *p, int16_t b)
}
#else
# error "Missing implementation for 16-bit atomic operations"
ATOMIC_LOCKING_FETCH_AND_AND_DEFINE(int16)
ATOMIC_LOCKING_FETCH_AND_OR_DEFINE(int16)
#endif
/******************************************************************************/
/* 8-bit operations. */
#if (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) || defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_1))
/** \} */
/* -------------------------------------------------------------------- */
/** \name 8-bit operations
* \{ */
#if !defined(ATOMIC_FORCE_USE_FALLBACK) && \
(defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) || defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_1))
/* Unsigned */
ATOMIC_INLINE uint8_t atomic_fetch_and_and_uint8(uint8_t *p, uint8_t b)
{
@@ -368,7 +531,27 @@ ATOMIC_INLINE int8_t atomic_fetch_and_or_int8(int8_t *p, int8_t b)
}
#else
# error "Missing implementation for 8-bit atomic operations"
/* Unsigned */
ATOMIC_LOCKING_FETCH_AND_AND_DEFINE(uint8)
ATOMIC_LOCKING_FETCH_AND_OR_DEFINE(uint8)
/* Signed */
ATOMIC_LOCKING_FETCH_AND_AND_DEFINE(int8)
ATOMIC_LOCKING_FETCH_AND_OR_DEFINE(int8)
#endif
/** \} */
#undef ATOMIC_LOCKING_OP_AND_FETCH_DEFINE
#undef ATOMIC_LOCKING_FETCH_AND_OP_DEFINE
#undef ATOMIC_LOCKING_ADD_AND_FETCH_DEFINE
#undef ATOMIC_LOCKING_SUB_AND_FETCH_DEFINE
#undef ATOMIC_LOCKING_FETCH_AND_ADD_DEFINE
#undef ATOMIC_LOCKING_FETCH_AND_SUB_DEFINE
#undef ATOMIC_LOCKING_FETCH_AND_OR_DEFINE
#undef ATOMIC_LOCKING_FETCH_AND_AND_DEFINE
#undef ATOMIC_LOCKING_CAS_DEFINE
#endif /* __ATOMIC_OPS_UNIX_H__ */

View File

@@ -64,9 +64,11 @@
#ifdef __GNUC__
# define _ATOMIC_LIKELY(x) __builtin_expect(!!(x), 1)
# define _ATOMIC_UNLIKELY(x) __builtin_expect(!!(x), 0)
# define _ATOMIC_MAYBE_UNUSED __attribute__((unused))
#else
# define _ATOMIC_LIKELY(x) (x)
# define _ATOMIC_UNLIKELY(x) (x)
# define _ATOMIC_MAYBE_UNUSED
#endif
#if defined(__SIZEOF_POINTER__)

View File

@@ -247,7 +247,7 @@ if(WITH_CYCLES_OSL)
endif()
if(WITH_CYCLES_DEVICE_OPTIX)
find_package(OptiX)
find_package(OptiX 7.3.0)
if(OPTIX_FOUND)
add_definitions(-DWITH_OPTIX)
@@ -286,11 +286,18 @@ if(WITH_OPENSUBDIV)
)
endif()
if(WITH_OPENIMAGEDENOISE)
add_definitions(-DWITH_OPENIMAGEDENOISE)
add_definitions(-DOIDN_STATIC_LIB)
include_directories(
SYSTEM
${OPENIMAGEDENOISE_INCLUDE_DIRS}
)
endif()
if(WITH_CYCLES_STANDALONE)
set(WITH_CYCLES_DEVICE_OPENCL TRUE)
set(WITH_CYCLES_DEVICE_CUDA TRUE)
# Experimental and unfinished.
set(WITH_CYCLES_NETWORK FALSE)
set(WITH_CYCLES_DEVICE_HIP TRUE)
endif()
# TODO(sergey): Consider removing it, only causes confusion in interface.
set(WITH_CYCLES_DEVICE_MULTI TRUE)
@@ -386,18 +393,12 @@ if(WITH_CYCLES_BLENDER)
add_subdirectory(blender)
endif()
if(WITH_CYCLES_NETWORK)
add_definitions(-DWITH_NETWORK)
endif()
if(WITH_CYCLES_STANDALONE OR WITH_CYCLES_NETWORK OR WITH_CYCLES_CUBIN_COMPILER)
add_subdirectory(app)
endif()
add_subdirectory(app)
add_subdirectory(bvh)
add_subdirectory(device)
add_subdirectory(doc)
add_subdirectory(graph)
add_subdirectory(integrator)
add_subdirectory(kernel)
add_subdirectory(render)
add_subdirectory(subd)

View File

@@ -64,6 +64,8 @@ if(WITH_CYCLES_STANDALONE)
cycles_standalone.cpp
cycles_xml.cpp
cycles_xml.h
oiio_output_driver.cpp
oiio_output_driver.h
)
add_executable(cycles ${SRC} ${INC} ${INC_SYS})
unset(SRC)
@@ -73,7 +75,7 @@ if(WITH_CYCLES_STANDALONE)
if(APPLE)
if(WITH_OPENCOLORIO)
set_property(TARGET cycles APPEND_STRING PROPERTY LINK_FLAGS " -framework IOKit")
set_property(TARGET cycles APPEND_STRING PROPERTY LINK_FLAGS " -framework IOKit -framework Carbon")
endif()
if(WITH_OPENIMAGEDENOISE AND "${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64")
# OpenImageDenoise uses BNNS from the Accelerate framework.
@@ -90,24 +92,6 @@ if(WITH_CYCLES_STANDALONE)
endif()
endif()
#####################################################################
# Cycles network server executable
#####################################################################
if(WITH_CYCLES_NETWORK)
set(SRC
cycles_server.cpp
)
add_executable(cycles_server ${SRC})
target_link_libraries(cycles_server ${LIBRARIES})
cycles_target_link_libraries(cycles_server)
if(UNIX AND NOT APPLE)
set_target_properties(cycles_server PROPERTIES INSTALL_RPATH $ORIGIN/lib)
endif()
unset(SRC)
endif()
#####################################################################
# Cycles cubin compiler executable
#####################################################################

View File

@@ -36,6 +36,9 @@
#include "util/util_unique_ptr.h"
#include "util/util_version.h"
#include "app/cycles_xml.h"
#include "app/oiio_output_driver.h"
#ifdef WITH_CYCLES_STANDALONE_GUI
# include "util/util_view.h"
#endif
@@ -53,7 +56,8 @@ struct Options {
SessionParams session_params;
bool quiet;
bool show_help, interactive, pause;
string output_path;
string output_filepath;
string output_pass;
} options;
static void session_print(const string &str)
@@ -89,30 +93,6 @@ static void session_print_status()
session_print(status);
}
static bool write_render(const uchar *pixels, int w, int h, int channels)
{
string msg = string_printf("Writing image %s", options.output_path.c_str());
session_print(msg);
unique_ptr<ImageOutput> out = unique_ptr<ImageOutput>(ImageOutput::create(options.output_path));
if (!out) {
return false;
}
ImageSpec spec(w, h, channels, TypeDesc::UINT8);
if (!out->open(options.output_path, spec)) {
return false;
}
/* conversion for different top/bottom convention */
out->write_image(
TypeDesc::UINT8, pixels + (h - 1) * w * channels, AutoStride, -w * channels, AutoStride);
out->close();
return true;
}
static BufferParams &session_buffer_params()
{
static BufferParams buffer_params;
@@ -126,7 +106,7 @@ static BufferParams &session_buffer_params()
static void scene_init()
{
options.scene = new Scene(options.scene_params, options.session->device);
options.scene = options.session->scene;
/* Read XML */
xml_read_file(options.scene, options.filepath.c_str());
@@ -147,8 +127,13 @@ static void scene_init()
static void session_init()
{
options.session_params.write_render_cb = write_render;
options.session = new Session(options.session_params);
options.output_pass = "combined";
options.session = new Session(options.session_params, options.scene_params);
if (!options.output_filepath.empty()) {
options.session->set_output_driver(make_unique<OIIOOutputDriver>(
options.output_filepath, options.output_pass, session_print));
}
if (options.session_params.background && !options.quiet)
options.session->progress.set_update_callback(function_bind(&session_print_status));
@@ -159,9 +144,13 @@ static void session_init()
/* load scene */
scene_init();
options.session->scene = options.scene;
options.session->reset(session_buffer_params(), options.session_params.samples);
/* add pass for output. */
Pass *pass = options.scene->create_node<Pass>();
pass->set_name(ustring(options.output_pass.c_str()));
pass->set_type(PASS_COMBINED);
options.session->reset(options.session_params, session_buffer_params());
options.session->start();
}
@@ -223,9 +212,7 @@ static void display_info(Progress &progress)
static void display()
{
static DeviceDrawParams draw_params = DeviceDrawParams();
options.session->draw(session_buffer_params(), draw_params);
options.session->draw();
display_info(options.session->progress);
}
@@ -255,7 +242,7 @@ static void motion(int x, int y, int button)
options.session->scene->camera->need_flags_update = true;
options.session->scene->camera->need_device_update = true;
options.session->reset(session_buffer_params(), options.session_params.samples);
options.session->reset(options.session_params, session_buffer_params());
}
}
@@ -272,7 +259,7 @@ static void resize(int width, int height)
options.session->scene->camera->need_flags_update = true;
options.session->scene->camera->need_device_update = true;
options.session->reset(session_buffer_params(), options.session_params.samples);
options.session->reset(options.session_params, session_buffer_params());
}
}
@@ -284,7 +271,7 @@ static void keyboard(unsigned char key)
/* Reset */
else if (key == 'r')
options.session->reset(session_buffer_params(), options.session_params.samples);
options.session->reset(options.session_params, session_buffer_params());
/* Cancel */
else if (key == 27) // escape
@@ -321,7 +308,7 @@ static void keyboard(unsigned char key)
options.session->scene->camera->need_flags_update = true;
options.session->scene->camera->need_device_update = true;
options.session->reset(session_buffer_params(), options.session_params.samples);
options.session->reset(options.session_params, session_buffer_params());
}
/* Set Max Bounces */
@@ -347,7 +334,7 @@ static void keyboard(unsigned char key)
options.session->scene->integrator->set_max_bounce(bounce);
options.session->reset(session_buffer_params(), options.session_params.samples);
options.session->reset(options.session_params, session_buffer_params());
}
}
#endif
@@ -362,11 +349,13 @@ static int files_parse(int argc, const char *argv[])
static void options_parse(int argc, const char **argv)
{
options.width = 0;
options.height = 0;
options.width = 1024;
options.height = 512;
options.filepath = "";
options.session = NULL;
options.quiet = false;
options.session_params.use_auto_tile = false;
options.session_params.tile_size = 0;
/* device names */
string device_names = "";
@@ -412,7 +401,7 @@ static void options_parse(int argc, const char **argv)
&options.session_params.samples,
"Number of samples to render",
"--output %s",
&options.output_path,
&options.output_filepath,
"File path to write output image",
"--threads %d",
&options.session_params.threads,
@@ -423,12 +412,9 @@ static void options_parse(int argc, const char **argv)
"--height %d",
&options.height,
"Window height in pixel",
"--tile-width %d",
&options.session_params.tile_size.x,
"Tile width in pixels",
"--tile-height %d",
&options.session_params.tile_size.y,
"Tile height in pixels",
"--tile-size %d",
&options.session_params.tile_size,
"Tile size in pixels",
"--list-devices",
&list,
"List information about all available devices",
@@ -490,8 +476,9 @@ static void options_parse(int argc, const char **argv)
options.session_params.background = true;
#endif
/* Use progressive rendering */
options.session_params.progressive = true;
if (options.session_params.tile_size > 0) {
options.session_params.use_auto_tile = true;
}
/* find matching device */
DeviceType device_type = Device::type_from_string(devicename.c_str());
@@ -527,9 +514,6 @@ static void options_parse(int argc, const char **argv)
fprintf(stderr, "No file path specified\n");
exit(EXIT_FAILURE);
}
/* For smoother Viewport */
options.session_params.start_resolution = 64;
}
CCL_NAMESPACE_END

View File

@@ -333,6 +333,7 @@ static void xml_read_shader_graph(XMLReadState &state, Shader *shader, xml_node
}
snode = (ShaderNode *)node_type->create(node_type);
snode->set_owner(graph);
}
xml_read_node(graph_reader, snode, node);
@@ -703,7 +704,7 @@ void xml_read_file(Scene *scene, const char *filepath)
xml_read_include(state, path_filename(filepath));
scene->params.bvh_type = SceneParams::BVH_STATIC;
scene->params.bvh_type = BVH_TYPE_STATIC;
}
CCL_NAMESPACE_END

View File

@@ -0,0 +1,71 @@
/*
* Copyright 2021 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "app/oiio_output_driver.h"
CCL_NAMESPACE_BEGIN
OIIOOutputDriver::OIIOOutputDriver(const string_view filepath,
const string_view pass,
LogFunction log)
: filepath_(filepath), pass_(pass), log_(log)
{
}
OIIOOutputDriver::~OIIOOutputDriver()
{
}
void OIIOOutputDriver::write_render_tile(const Tile &tile)
{
/* Only write the full buffer, no intermediate tiles. */
if (!(tile.size == tile.full_size)) {
return;
}
log_(string_printf("Writing image %s", filepath_.c_str()));
unique_ptr<ImageOutput> image_output(ImageOutput::create(filepath_));
if (image_output == nullptr) {
log_("Failed to create image file");
return;
}
const int width = tile.size.x;
const int height = tile.size.y;
ImageSpec spec(width, height, 4, TypeDesc::FLOAT);
if (!image_output->open(filepath_, spec)) {
log_("Failed to create image file");
return;
}
vector<float> pixels(width * height * 4);
if (!tile.get_pass_pixels(pass_, 4, pixels.data())) {
log_("Failed to read render pass pixels");
return;
}
/* Manipulate offset and stride to convert from bottom-up to top-down convention. */
image_output->write_image(TypeDesc::FLOAT,
pixels.data() + (height - 1) * width * 4,
AutoStride,
-width * 4 * sizeof(float),
AutoStride);
image_output->close();
}
CCL_NAMESPACE_END

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2019 Blender Foundation
* Copyright 2021 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,16 +14,29 @@
* limitations under the License.
*/
#include "render/output_driver.h"
#include "util/util_function.h"
#include "util/util_image.h"
#include "util/util_string.h"
#include "util/util_unique_ptr.h"
#include "util/util_vector.h"
CCL_NAMESPACE_BEGIN
ccl_device void kernel_adaptive_filter_y(KernelGlobals *kg)
{
int pixel_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
if (pixel_index < kernel_split_params.tile.w &&
kernel_split_params.tile.start_sample + kernel_split_params.tile.num_samples >=
kernel_data.integrator.adaptive_min_samples) {
int x = kernel_split_params.tile.x + pixel_index;
kernel_do_adaptive_filter_y(kg, x, &kernel_split_params.tile);
}
}
class OIIOOutputDriver : public OutputDriver {
public:
typedef function<void(const string &)> LogFunction;
OIIOOutputDriver(const string_view filepath, const string_view pass, LogFunction log);
virtual ~OIIOOutputDriver();
void write_render_tile(const Tile &tile) override;
protected:
string filepath_;
string pass_;
LogFunction log_;
};
CCL_NAMESPACE_END

View File

@@ -31,12 +31,14 @@ set(INC_SYS
set(SRC
blender_camera.cpp
blender_device.cpp
blender_display_driver.cpp
blender_image.cpp
blender_geometry.cpp
blender_light.cpp
blender_mesh.cpp
blender_object.cpp
blender_object_cull.cpp
blender_output_driver.cpp
blender_particles.cpp
blender_curves.cpp
blender_logging.cpp
@@ -50,9 +52,11 @@ set(SRC
CCL_api.h
blender_device.h
blender_display_driver.h
blender_id_map.h
blender_image.h
blender_object_cull.h
blender_output_driver.h
blender_sync.h
blender_session.h
blender_texture.h
@@ -93,14 +97,9 @@ set(ADDON_FILES
add_definitions(${GL_DEFINITIONS})
if(WITH_CYCLES_DEVICE_OPENCL)
add_definitions(-DWITH_OPENCL)
if(WITH_CYCLES_DEVICE_HIP)
add_definitions(-DWITH_HIP)
endif()
if(WITH_CYCLES_NETWORK)
add_definitions(-DWITH_NETWORK)
endif()
if(WITH_MOD_FLUID)
add_definitions(-DWITH_FLUID)
endif()

View File

@@ -58,7 +58,6 @@ class CyclesRender(bpy.types.RenderEngine):
bl_use_eevee_viewport = True
bl_use_preview = True
bl_use_exclude_layers = True
bl_use_save_buffers = True
bl_use_spherical_stereo = True
bl_use_custom_freestyle = True
bl_use_alembic_procedural = True
@@ -85,6 +84,12 @@ class CyclesRender(bpy.types.RenderEngine):
def render(self, depsgraph):
engine.render(self, depsgraph)
def render_frame_finish(self):
engine.render_frame_finish(self)
def draw(self, context, depsgraph):
engine.draw(self, depsgraph, context.space_data)
def bake(self, depsgraph, obj, pass_type, pass_filter, width, height):
engine.bake(self, depsgraph, obj, pass_type, pass_filter, width, height)
@@ -98,7 +103,7 @@ class CyclesRender(bpy.types.RenderEngine):
engine.sync(self, depsgraph, context.blend_data)
def view_draw(self, context, depsgraph):
engine.draw(self, depsgraph, context.region, context.space_data, context.region_data)
engine.view_draw(self, depsgraph, context.region, context.space_data, context.region_data)
def update_script_node(self, node):
if engine.with_osl():

View File

@@ -18,62 +18,17 @@
from __future__ import annotations
def _is_using_buggy_driver():
import gpu
# We need to be conservative here because in multi-GPU systems display card
# might be quite old, but others one might be just good.
#
# So We shouldn't disable possible good dedicated cards just because display
# card seems weak. And instead we only blacklist configurations which are
# proven to cause problems.
if gpu.platform.vendor_get() == "ATI Technologies Inc.":
import re
version = gpu.platform.version_get()
if version.endswith("Compatibility Profile Context"):
# Old HD 4xxx and 5xxx series drivers did not have driver version
# in the version string, but those cards do not quite work and
# causing crashes.
return True
regex = re.compile(".*Compatibility Profile Context ([0-9]+(\\.[0-9]+)+)$")
if not regex.match(version):
# Skip cards like FireGL
return False
version = regex.sub("\\1", version).split('.')
return int(version[0]) == 8
return False
def _workaround_buggy_drivers():
if _is_using_buggy_driver():
import _cycles
if hasattr(_cycles, "opencl_disable"):
print("Cycles: OpenGL driver known to be buggy, disabling OpenCL platform.")
_cycles.opencl_disable()
def _configure_argument_parser():
import argparse
# No help because it conflicts with general Python scripts argument parsing
parser = argparse.ArgumentParser(description="Cycles Addon argument parser",
add_help=False)
parser.add_argument("--cycles-resumable-num-chunks",
help="Number of chunks to split sample range into",
default=None)
parser.add_argument("--cycles-resumable-current-chunk",
help="Current chunk of samples range to render",
default=None)
parser.add_argument("--cycles-resumable-start-chunk",
help="Start chunk to render",
default=None)
parser.add_argument("--cycles-resumable-end-chunk",
help="End chunk to render",
default=None)
parser.add_argument("--cycles-print-stats",
help="Print rendering statistics to stderr",
action='store_true')
parser.add_argument("--cycles-device",
help="Set the device to use for Cycles, overriding user preferences and the scene setting."
"Valid options are 'CPU', 'CUDA', 'OPTIX' or 'OPENCL'."
"Valid options are 'CPU', 'CUDA', 'OPTIX', or 'HIP'"
"Additionally, you can append '+CPU' to any GPU type for hybrid rendering.",
default=None)
return parser
@@ -89,21 +44,6 @@ def _parse_command_line():
parser = _configure_argument_parser()
args, _ = parser.parse_known_args(argv[argv.index("--") + 1:])
if args.cycles_resumable_num_chunks is not None:
if args.cycles_resumable_current_chunk is not None:
import _cycles
_cycles.set_resumable_chunk(
int(args.cycles_resumable_num_chunks),
int(args.cycles_resumable_current_chunk),
)
elif args.cycles_resumable_start_chunk is not None and \
args.cycles_resumable_end_chunk:
import _cycles
_cycles.set_resumable_chunk_range(
int(args.cycles_resumable_num_chunks),
int(args.cycles_resumable_start_chunk),
int(args.cycles_resumable_end_chunk),
)
if args.cycles_print_stats:
import _cycles
_cycles.enable_print_stats()
@@ -118,23 +58,11 @@ def init():
import _cycles
import os.path
# Workaround possibly buggy legacy drivers which crashes on the OpenCL
# device enumeration.
#
# This checks are not really correct because they might still fail
# in the case of multiple GPUs. However, currently buggy drivers
# are really old and likely to be used in single GPU systems only
# anyway.
#
# Can't do it in the background mode, so we hope OpenCL is no enabled
# in the user preferences.
if not bpy.app.background:
_workaround_buggy_drivers()
path = os.path.dirname(__file__)
user_path = os.path.dirname(os.path.abspath(bpy.utils.user_resource('CONFIG', path='')))
temp_path = bpy.app.tempdir
_cycles.init(path, user_path, bpy.app.background)
_cycles.init(path, user_path, temp_path, bpy.app.background)
_parse_command_line()
@@ -177,6 +105,25 @@ def render(engine, depsgraph):
_cycles.render(engine.session, depsgraph.as_pointer())
def render_frame_finish(engine):
if not engine.session:
return
import _cycles
_cycles.render_frame_finish(engine.session)
def draw(engine, depsgraph, space_image):
if not engine.session:
return
depsgraph_ptr = depsgraph.as_pointer()
space_image_ptr = space_image.as_pointer()
screen_ptr = space_image.id_data.as_pointer()
import _cycles
_cycles.draw(engine.session, depsgraph_ptr, screen_ptr, space_image_ptr)
def bake(engine, depsgraph, obj, pass_type, pass_filter, width, height):
import _cycles
session = getattr(engine, "session", None)
@@ -204,14 +151,14 @@ def sync(engine, depsgraph, data):
_cycles.sync(engine.session, depsgraph.as_pointer())
def draw(engine, depsgraph, region, v3d, rv3d):
def view_draw(engine, depsgraph, region, v3d, rv3d):
import _cycles
depsgraph = depsgraph.as_pointer()
v3d = v3d.as_pointer()
rv3d = rv3d.as_pointer()
# draw render image
_cycles.draw(engine.session, depsgraph, v3d, rv3d)
_cycles.view_draw(engine.session, depsgraph, v3d, rv3d)
def available_devices():
@@ -224,11 +171,6 @@ def with_osl():
return _cycles.with_osl
def with_network():
import _cycles
return _cycles.with_network
def system_info():
import _cycles
return _cycles.system_info()
@@ -243,6 +185,7 @@ def list_render_passes(scene, srl):
# Data passes.
if srl.use_pass_z: yield ("Depth", "Z", 'VALUE')
if srl.use_pass_mist: yield ("Mist", "Z", 'VALUE')
if srl.use_pass_position: yield ("Position", "XYZ", 'VECTOR')
if srl.use_pass_normal: yield ("Normal", "XYZ", 'VECTOR')
if srl.use_pass_vector: yield ("Vector", "XYZW", 'VECTOR')
if srl.use_pass_uv: yield ("UV", "UVA", 'VECTOR')
@@ -265,6 +208,7 @@ def list_render_passes(scene, srl):
if srl.use_pass_environment: yield ("Env", "RGB", 'COLOR')
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')
# Debug passes.
if crl.pass_debug_render_time: yield ("Debug Render Time", "X", 'VALUE')
@@ -283,30 +227,20 @@ def list_render_passes(scene, srl):
yield ("CryptoAsset" + '{:02d}'.format(i), "RGBA", 'COLOR')
# Denoising passes.
if (scene.cycles.use_denoising and crl.use_denoising) or crl.denoising_store_passes:
if scene.cycles.use_denoising and crl.use_denoising:
yield ("Noisy Image", "RGBA", 'COLOR')
if crl.denoising_store_passes:
yield ("Denoising Normal", "XYZ", 'VECTOR')
yield ("Denoising Albedo", "RGB", 'COLOR')
yield ("Denoising Depth", "Z", 'VALUE')
if scene.cycles.denoiser == 'NLM':
yield ("Denoising Shadowing", "X", 'VALUE')
yield ("Denoising Variance", "RGB", 'COLOR')
yield ("Denoising Intensity", "X", 'VALUE')
clean_options = ("denoising_diffuse_direct", "denoising_diffuse_indirect",
"denoising_glossy_direct", "denoising_glossy_indirect",
"denoising_transmission_direct", "denoising_transmission_indirect")
if any(getattr(crl, option) for option in clean_options):
yield ("Denoising Clean", "RGB", 'COLOR')
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')
# Custom AOV passes.
for aov in srl.aovs:
if aov.type == 'VALUE':
yield (aov.name, "X", 'VALUE')
else:
yield (aov.name, "RGBA", 'COLOR')
yield (aov.name, "RGB", 'COLOR')
def register_passes(engine, scene, view_layer):

View File

@@ -60,32 +60,48 @@ class AddPresetSampling(AddPresetBase, Operator):
]
preset_values = [
"cycles.use_adaptive_sampling",
"cycles.samples",
"cycles.preview_samples",
"cycles.aa_samples",
"cycles.preview_aa_samples",
"cycles.diffuse_samples",
"cycles.glossy_samples",
"cycles.transmission_samples",
"cycles.ao_samples",
"cycles.mesh_light_samples",
"cycles.subsurface_samples",
"cycles.volume_samples",
"cycles.use_square_samples",
"cycles.progressive",
"cycles.seed",
"cycles.sample_clamp_direct",
"cycles.sample_clamp_indirect",
"cycles.sample_all_lights_direct",
"cycles.sample_all_lights_indirect",
"cycles.adaptive_threshold",
"cycles.adaptive_min_samples",
"cycles.time_limit",
"cycles.use_denoising",
"cycles.denoiser",
"cycles.denoising_input_passes",
"cycles.denoising_prefilter",
]
preset_subdir = "cycles/sampling"
class AddPresetViewportSampling(AddPresetBase, Operator):
'''Add a Viewport Sampling Preset'''
bl_idname = "render.cycles_viewport_sampling_preset_add"
bl_label = "Add Viewport Sampling Preset"
preset_menu = "CYCLES_PT_viewport_sampling_presets"
preset_defines = [
"cycles = bpy.context.scene.cycles"
]
preset_values = [
"cycles.use_preview_adaptive_sampling",
"cycles.preview_samples",
"cycles.preview_adaptive_threshold",
"cycles.preview_adaptive_min_samples",
"cycles.use_preview_denoising",
"cycles.preview_denoiser",
"cycles.preview_denoising_input_passes",
"cycles.preview_denoising_prefilter",
"cycles.preview_denoising_start_sample",
]
preset_subdir = "cycles/viewport_sampling"
classes = (
AddPresetIntegrator,
AddPresetSampling,
AddPresetViewportSampling,
)

View File

@@ -39,11 +39,6 @@ enum_devices = (
('GPU', "GPU Compute", "Use GPU compute device for rendering, configured in the system tab in the user preferences"),
)
from _cycles import with_network
if with_network:
enum_devices += (('NETWORK', "Networked Device", "Use networked device for rendering"),)
del with_network
enum_feature_set = (
('SUPPORTED', "Supported", "Only use finished and supported features"),
('EXPERIMENTAL', "Experimental", "Use experimental and incomplete features that might be broken or change in the future", 'ERROR', 1),
@@ -84,15 +79,6 @@ enum_curve_shape = (
('THICK', "3D Curves", "Render hair as 3D curve, for accurate results when viewing hair close up"),
)
enum_tile_order = (
('CENTER', "Center", "Render from center to the edges"),
('RIGHT_TO_LEFT', "Right to Left", "Render from right to left"),
('LEFT_TO_RIGHT', "Left to Right", "Render from left to right"),
('TOP_TO_BOTTOM', "Top to Bottom", "Render from top to bottom"),
('BOTTOM_TO_TOP', "Bottom to Top", "Render from bottom to top"),
('HILBERT_SPIRAL', "Hilbert Spiral", "Render in a Hilbert Spiral"),
)
enum_use_layer_samples = (
('USE', "Use", "Per render layer number of samples override scene samples"),
('BOUNDED', "Bounded", "Bound per render layer number of samples by global samples"),
@@ -101,15 +87,9 @@ enum_use_layer_samples = (
enum_sampling_pattern = (
('SOBOL', "Sobol", "Use Sobol random sampling pattern"),
('CORRELATED_MUTI_JITTER', "Correlated Multi-Jitter", "Use Correlated Multi-Jitter random sampling pattern"),
('PROGRESSIVE_MUTI_JITTER', "Progressive Multi-Jitter", "Use Progressive Multi-Jitter random sampling pattern"),
)
enum_integrator = (
('BRANCHED_PATH', "Branched Path Tracing", "Path tracing integrator that branches on the first bounce, giving more control over the number of light and material samples"),
('PATH', "Path Tracing", "Pure path tracing integrator"),
)
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"),
@@ -131,7 +111,7 @@ enum_device_type = (
('CPU', "CPU", "CPU", 0),
('CUDA', "CUDA", "CUDA", 1),
('OPTIX', "OptiX", "OptiX", 3),
('OPENCL', "OpenCL", "OpenCL", 2)
("HIP", "HIP", "HIP", 4)
)
enum_texture_limit = (
@@ -145,38 +125,45 @@ enum_texture_limit = (
('8192', "8192", "Limit texture size to 8192 pixels", 7),
)
# NOTE: Identifiers are expected to be an upper case version of identifiers from `Pass::get_type_enum()`
enum_view3d_shading_render_pass = (
('', "General", ""),
('COMBINED', "Combined", "Show the Combined Render pass", 1),
('EMISSION', "Emission", "Show the Emission render pass", 33),
('BACKGROUND', "Background", "Show the Background render pass", 34),
('AO', "Ambient Occlusion", "Show the Ambient Occlusion render pass", 35),
('COMBINED', "Combined", "Show the Combined Render pass"),
('EMISSION', "Emission", "Show the Emission render pass"),
('BACKGROUND', "Background", "Show the Background render pass"),
('AO', "Ambient Occlusion", "Show the Ambient Occlusion render pass"),
('SHADOW', "Shadow", "Show the Shadow render pass"),
('SHADOW_CATCHER', "Shadow Catcher", "Show the Shadow Catcher render pass"),
('', "Light", ""),
('DIFFUSE_DIRECT', "Diffuse Direct", "Show the Diffuse Direct render pass", 38),
('DIFFUSE_INDIRECT', "Diffuse Indirect", "Show the Diffuse Indirect render pass", 39),
('DIFFUSE_COLOR', "Diffuse Color", "Show the Diffuse Color render pass", 40),
('DIFFUSE_DIRECT', "Diffuse Direct", "Show the Diffuse Direct render pass"),
('DIFFUSE_INDIRECT', "Diffuse Indirect", "Show the Diffuse Indirect render pass"),
('DIFFUSE_COLOR', "Diffuse Color", "Show the Diffuse Color render pass"),
('GLOSSY_DIRECT', "Glossy Direct", "Show the Glossy Direct render pass", 41),
('GLOSSY_INDIRECT', "Glossy Indirect", "Show the Glossy Indirect render pass", 42),
('GLOSSY_COLOR', "Glossy Color", "Show the Glossy Color render pass", 43),
('GLOSSY_DIRECT', "Glossy Direct", "Show the Glossy Direct render pass"),
('GLOSSY_INDIRECT', "Glossy Indirect", "Show the Glossy Indirect render pass"),
('GLOSSY_COLOR', "Glossy Color", "Show the Glossy Color render pass"),
('', "", ""),
('TRANSMISSION_DIRECT', "Transmission Direct", "Show the Transmission Direct render pass", 44),
('TRANSMISSION_INDIRECT', "Transmission Indirect", "Show the Transmission Indirect render pass", 45),
('TRANSMISSION_COLOR', "Transmission Color", "Show the Transmission Color render pass", 46),
('TRANSMISSION_DIRECT', "Transmission Direct", "Show the Transmission Direct render pass"),
('TRANSMISSION_INDIRECT', "Transmission Indirect", "Show the Transmission Indirect render pass"),
('TRANSMISSION_COLOR', "Transmission Color", "Show the Transmission Color render pass"),
('VOLUME_DIRECT', "Volume Direct", "Show the Volume Direct render pass", 50),
('VOLUME_INDIRECT', "Volume Indirect", "Show the Volume Indirect render pass", 51),
('VOLUME_DIRECT', "Volume Direct", "Show the Volume Direct render pass"),
('VOLUME_INDIRECT', "Volume Indirect", "Show the Volume Indirect render pass"),
('', "Data", ""),
('NORMAL', "Normal", "Show the Normal render pass", 3),
('UV', "UV", "Show the UV render pass", 4),
('MIST', "Mist", "Show the Mist render pass", 32),
('POSITION', "Position", "Show the Position render pass"),
('NORMAL', "Normal", "Show the Normal render pass"),
('UV', "UV", "Show the UV render pass"),
('MIST', "Mist", "Show the Mist render pass"),
('DENOISING_ALBEDO', "Denoising Albedo", "Albedo pass used by denoiser"),
('DENOISING_NORMAL', "Denoising Normal", "Normal pass used by denoiser"),
('SAMPLE_COUNT', "Sample Count", "Per-pixel number of samples"),
)
@@ -208,18 +195,23 @@ def enum_preview_denoiser(self, context):
def enum_denoiser(self, context):
items = [('NLM', "NLM", "Cycles native non-local means denoiser, running on any compute device", 1)]
items = []
items += enum_optix_denoiser(self, context)
items += enum_openimagedenoise_denoiser(self, context)
return items
enum_denoising_input_passes = (
('RGB', "Color", "Use only color as input", 1),
('RGB_ALBEDO', "Color + Albedo", "Use color and albedo data as input", 2),
('RGB_ALBEDO_NORMAL', "Color + Albedo + Normal", "Use color, albedo and normal data as input", 3),
('RGB', "None", "Don't use utility passes for denoising", 1),
('RGB_ALBEDO', "Albedo", "Use albedo pass for denoising", 2),
('RGB_ALBEDO_NORMAL', "Albedo and Normal", "Use albedo and normal passes for denoising", 3),
)
enum_denoising_prefilter = (
('NONE', "None", "No prefiltering, use when guiding passes are noise-free", 1),
('FAST', "Fast", "Denoise color and guiding passes together. Improves quality when guiding passes are noisy using least amount of extra processing time", 2),
('ACCURATE', "Accurate", "Prefilter noisy guiding passes before denoising color. Improves quality when guiding passes are noisy using extra processing time", 3),
)
def update_render_passes(self, context):
scene = context.scene
@@ -252,13 +244,6 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
description="Use Open Shading Language (CPU rendering only)",
)
progressive: EnumProperty(
name="Integrator",
description="Method to sample lights and materials",
items=enum_integrator,
default='PATH',
)
preview_pause: BoolProperty(
name="Pause Preview",
description="Pause all viewport preview renders",
@@ -268,110 +253,88 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
use_denoising: BoolProperty(
name="Use Denoising",
description="Denoise the rendered image",
default=False,
default=True,
update=update_render_passes,
)
denoiser: EnumProperty(
name="Denoiser",
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.
update=update_render_passes,
)
denoising_prefilter: EnumProperty(
name="Denoising Prefilter",
description="Prefilter noisy guiding (albedo and normal) passes to improve denoising quality when using OpenImageDenoiser",
items=enum_denoising_prefilter,
default='ACCURATE',
)
denoising_input_passes: EnumProperty(
name="Denoising Input Passes",
description="Passes used by the denoiser to distinguish noise from shader and geometry detail",
items=enum_denoising_input_passes,
default='RGB_ALBEDO_NORMAL',
)
use_preview_denoising: BoolProperty(
name="Use Viewport Denoising",
description="Denoise the image in the 3D viewport",
default=False,
)
denoiser: EnumProperty(
name="Denoiser",
description="Denoise the image with the selected denoiser. "
"For denoising the image after rendering, denoising data render passes "
"also adapt to the selected denoiser",
items=enum_denoiser,
default=1,
update=update_render_passes,
)
preview_denoiser: EnumProperty(
name="Viewport Denoiser",
description="Denoise the image after each preview update with the selected denoiser",
items=enum_preview_denoiser,
default=0,
)
use_square_samples: BoolProperty(
name="Square Samples",
description="Square sampling values for easier artist control",
default=False,
preview_denoising_prefilter: EnumProperty(
name="Viewport Denoising Prefilter",
description="Prefilter noisy guiding (albedo and normal) passes to improve denoising quality when using OpenImageDenoiser",
items=enum_denoising_prefilter,
default='FAST',
)
preview_denoising_input_passes: EnumProperty(
name="Viewport Denoising Input Passes",
description="Passes used by the denoiser to distinguish noise from shader and geometry detail",
items=enum_denoising_input_passes,
default='RGB_ALBEDO',
)
preview_denoising_start_sample: IntProperty(
name="Start Denoising",
description="Sample to start denoising the preview at",
min=0, max=(1 << 24),
default=1,
)
samples: IntProperty(
name="Samples",
description="Number of samples to render for each pixel",
min=1, max=(1 << 24),
default=128,
default=4096,
)
preview_samples: IntProperty(
name="Viewport Samples",
description="Number of samples to render in the viewport, unlimited if 0",
min=0, max=(1 << 24),
default=32,
)
aa_samples: IntProperty(
name="AA Samples",
description="Number of antialiasing samples to render for each pixel",
min=1, max=2097151,
default=128,
)
preview_aa_samples: IntProperty(
name="AA Samples",
description="Number of antialiasing samples to render in the viewport, unlimited if 0",
min=0, max=2097151,
default=32,
default=1024,
)
diffuse_samples: IntProperty(
name="Diffuse Samples",
description="Number of diffuse bounce samples to render for each AA sample",
min=1, max=1024,
default=1,
)
glossy_samples: IntProperty(
name="Glossy Samples",
description="Number of glossy bounce samples to render for each AA sample",
min=1, max=1024,
default=1,
)
transmission_samples: IntProperty(
name="Transmission Samples",
description="Number of transmission bounce samples to render for each AA sample",
min=1, max=1024,
default=1,
)
ao_samples: IntProperty(
name="Ambient Occlusion Samples",
description="Number of ambient occlusion samples to render for each AA sample",
min=1, max=1024,
default=1,
)
mesh_light_samples: IntProperty(
name="Mesh Light Samples",
description="Number of mesh emission light samples to render for each AA sample",
min=1, max=1024,
default=1,
)
subsurface_samples: IntProperty(
name="Subsurface Samples",
description="Number of subsurface scattering samples to render for each AA sample",
min=1, max=1024,
default=1,
)
volume_samples: IntProperty(
name="Volume Samples",
description="Number of volume scattering samples to render for each AA sample",
min=1, max=1024,
default=1,
time_limit: FloatProperty(
name="Time Limit",
description="Limit the render time (excluding synchronization time)."
"Zero disables the limit",
min=0.0,
default=0.0,
step=100.0,
unit='TIME_ABSOLUTE',
)
sampling_pattern: EnumProperty(
name="Sampling Pattern",
description="Random sampling pattern used by the integrator",
items=enum_sampling_pattern,
default='SOBOL',
default='PROGRESSIVE_MUTI_JITTER',
)
use_layer_samples: EnumProperty(
@@ -381,17 +344,6 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
default='USE',
)
sample_all_lights_direct: BoolProperty(
name="Sample All Direct Lights",
description="Sample all lights (for direct samples), rather than randomly picking one",
default=True,
)
sample_all_lights_indirect: BoolProperty(
name="Sample All Indirect Lights",
description="Sample all lights (for indirect samples), rather than randomly picking one",
default=True,
)
light_sampling_threshold: FloatProperty(
name="Light Sampling Threshold",
description="Probabilistically terminate light samples when the light contribution is below this threshold (more noise but faster rendering). "
@@ -403,19 +355,39 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
use_adaptive_sampling: BoolProperty(
name="Use Adaptive Sampling",
description="Automatically reduce the number of samples per pixel based on estimated noise level",
default=False,
default=True,
)
adaptive_threshold: FloatProperty(
name="Adaptive Sampling Threshold",
description="Noise level step to stop sampling at, lower values reduce noise the cost of render time. Zero for automatic setting based on number of AA samples",
description="Noise level step to stop sampling at, lower values reduce noise at the cost of render time. Zero for automatic setting based on number of AA samples",
min=0.0, max=1.0,
default=0.0,
soft_min=0.001,
default=0.01,
precision=4,
)
adaptive_min_samples: IntProperty(
name="Adaptive Min Samples",
description="Minimum AA samples for adaptive sampling, to discover noisy features before stopping sampling. Zero for automatic setting based on number of AA samples",
description="Minimum AA samples for adaptive sampling, to discover noisy features before stopping sampling. Zero for automatic setting based on noise threshold",
min=0, max=4096,
default=0,
)
use_preview_adaptive_sampling: BoolProperty(
name="Use Adaptive Sampling",
description="Automatically reduce the number of samples per pixel based on estimated noise level, for viewport renders",
default=True,
)
preview_adaptive_threshold: FloatProperty(
name="Adaptive Sampling Threshold",
description="Noise level step to stop sampling at, lower values reduce noise at the cost of render time. Zero for automatic setting based on number of AA samples, for viewport renders",
min=0.0, max=1.0,
soft_min=0.001,
default=0.1,
precision=4,
)
preview_adaptive_min_samples: IntProperty(
name="Adaptive Min Samples",
description="Minimum AA samples for adaptive sampling, to discover noisy features before stopping sampling. Zero for automatic setting based on noise threshold, for viewport renders",
min=0, max=4096,
default=0,
)
@@ -632,53 +604,6 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
default=10.0,
)
debug_tile_size: IntProperty(
name="Tile Size",
description="",
min=1, max=4096,
default=1024,
)
preview_start_resolution: IntProperty(
name="Start Resolution",
description="Resolution to start rendering preview at, "
"progressively increasing it to the full viewport size",
min=8, max=16384,
default=64,
subtype='PIXEL'
)
preview_denoising_start_sample: IntProperty(
name="Start Denoising",
description="Sample to start denoising the preview at",
min=0, max=(1 << 24),
default=1,
)
preview_denoising_input_passes: EnumProperty(
name="Viewport Input Passes",
description="Passes used by the denoiser to distinguish noise from shader and geometry detail",
items=enum_denoising_input_passes,
default='RGB_ALBEDO',
)
debug_reset_timeout: FloatProperty(
name="Reset timeout",
description="",
min=0.01, max=10.0,
default=0.1,
)
debug_cancel_timeout: FloatProperty(
name="Cancel timeout",
description="",
min=0.01, max=10.0,
default=0.1,
)
debug_text_timeout: FloatProperty(
name="Text timeout",
description="",
min=0.01, max=10.0,
default=1.0,
)
debug_bvh_type: EnumProperty(
name="Viewport BVH Type",
description="Choose between faster updates, or faster render",
@@ -701,38 +626,24 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
default=0,
min=0, max=16,
)
tile_order: EnumProperty(
name="Tile Order",
description="Tile order for rendering",
items=enum_tile_order,
default='HILBERT_SPIRAL',
options=set(), # Not animatable!
)
use_progressive_refine: BoolProperty(
name="Progressive Refine",
description="Instead of rendering each tile until it is finished, "
"refine the whole image progressively "
"(this renders somewhat slower, "
"but time can be saved by manually stopping the render when the noise is low enough)",
default=False,
)
bake_type: EnumProperty(
name="Bake Type",
default='COMBINED',
description="Type of pass to bake",
items=(
('COMBINED', "Combined", ""),
('AO', "Ambient Occlusion", ""),
('SHADOW', "Shadow", ""),
('NORMAL', "Normal", ""),
('UV', "UV", ""),
('ROUGHNESS', "Roughness", ""),
('EMIT', "Emit", ""),
('ENVIRONMENT', "Environment", ""),
('DIFFUSE', "Diffuse", ""),
('GLOSSY', "Glossy", ""),
('TRANSMISSION', "Transmission", ""),
('COMBINED', "Combined", "", 0),
('AO', "Ambient Occlusion", "", 1),
('SHADOW', "Shadow", "", 2),
('POSITION', "Position", "", 11),
('NORMAL', "Normal", "", 3),
('UV', "UV", "", 4),
('ROUGHNESS', "Roughness", "", 5),
('EMIT', "Emit", "", 6),
('ENVIRONMENT', "Environment", "", 7),
('DIFFUSE', "Diffuse", "", 8),
('GLOSSY', "Glossy", "", 9),
('TRANSMISSION', "Transmission", "", 10),
),
)
@@ -827,6 +738,18 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
min=0, max=1024,
)
use_auto_tile: BoolProperty(
name="Auto Tiles",
description="Automatically render high resolution images in tiles to reduce memory usage, using the specified tile size. Tiles are cached to disk while rendering to save memory",
default=True,
)
tile_size: IntProperty(
name="Tile Size",
default=2048,
description="",
min=8, max=16384,
)
# Various fine-tuning debug flags
def _devices_update_callback(self, context):
@@ -844,45 +767,13 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
items=enum_bvh_layouts,
default='EMBREE',
)
debug_use_cpu_split_kernel: BoolProperty(name="Split Kernel", default=False)
debug_use_cuda_adaptive_compile: BoolProperty(name="Adaptive Compile", default=False)
debug_use_cuda_split_kernel: BoolProperty(name="Split Kernel", default=False)
debug_optix_cuda_streams: IntProperty(name="CUDA Streams", default=1, min=1)
debug_optix_curves_api: BoolProperty(name="Native OptiX Curve Primitive", default=False)
debug_opencl_kernel_type: EnumProperty(
name="OpenCL Kernel Type",
default='DEFAULT',
items=(
('DEFAULT', "Default", ""),
('MEGA', "Mega", ""),
('SPLIT', "Split", ""),
),
update=CyclesRenderSettings._devices_update_callback
)
debug_opencl_device_type: EnumProperty(
name="OpenCL Device Type",
default='ALL',
items=(
('NONE', "None", ""),
('ALL', "All", ""),
('DEFAULT', "Default", ""),
('CPU', "CPU", ""),
('GPU', "GPU", ""),
('ACCELERATOR', "Accelerator", ""),
),
update=CyclesRenderSettings._devices_update_callback
)
debug_use_opencl_debug: BoolProperty(name="Debug OpenCL", default=False)
debug_opencl_mem_limit: IntProperty(
name="Memory limit",
default=0,
description="Artificial limit on OpenCL memory usage in MB (0 to disable limit)"
debug_use_optix_debug: BoolProperty(
name="OptiX Module Debug",
description="Load OptiX module in debug mode: lower logging verbosity level, enable validations, and lower optimization level",
default=False
)
@classmethod
@@ -1031,12 +922,6 @@ class CyclesLightSettings(bpy.types.PropertyGroup):
description="Light casts shadows",
default=True,
)
samples: IntProperty(
name="Samples",
description="Number of light samples to render for each AA sample",
min=1, max=10000,
default=1,
)
max_bounces: IntProperty(
name="Max Bounces",
description="Maximum number of bounces the light will contribute to the render",
@@ -1084,12 +969,6 @@ class CyclesWorldSettings(bpy.types.PropertyGroup):
min=4, max=8192,
default=1024,
)
samples: IntProperty(
name="Samples",
description="Number of light samples to render for each AA sample",
min=1, max=10000,
default=1,
)
max_bounces: IntProperty(
name="Max Bounces",
description="Maximum number of bounces the background light will contribute to the render",
@@ -1343,91 +1222,25 @@ class CyclesRenderLayerSettings(bpy.types.PropertyGroup):
update=update_render_passes,
)
use_pass_shadow_catcher: BoolProperty(
name="Shadow Catcher",
description="Pass containing shadows and light which is to be multiplied into backdrop",
default=False,
update=update_render_passes,
)
use_denoising: BoolProperty(
name="Use Denoising",
description="Denoise the rendered image",
default=True,
update=update_render_passes,
)
denoising_diffuse_direct: BoolProperty(
name="Diffuse Direct",
description="Denoise the direct diffuse lighting",
default=True,
)
denoising_diffuse_indirect: BoolProperty(
name="Diffuse Indirect",
description="Denoise the indirect diffuse lighting",
default=True,
)
denoising_glossy_direct: BoolProperty(
name="Glossy Direct",
description="Denoise the direct glossy lighting",
default=True,
)
denoising_glossy_indirect: BoolProperty(
name="Glossy Indirect",
description="Denoise the indirect glossy lighting",
default=True,
)
denoising_transmission_direct: BoolProperty(
name="Transmission Direct",
description="Denoise the direct transmission lighting",
default=True,
)
denoising_transmission_indirect: BoolProperty(
name="Transmission Indirect",
description="Denoise the indirect transmission lighting",
default=True,
)
denoising_strength: FloatProperty(
name="Denoising Strength",
description="Controls neighbor pixel weighting for the denoising filter (lower values preserve more detail, but aren't as smooth)",
min=0.0, max=1.0,
default=0.5,
)
denoising_feature_strength: FloatProperty(
name="Denoising Feature Strength",
description="Controls removal of noisy image feature passes (lower values preserve more detail, but aren't as smooth)",
min=0.0, max=1.0,
default=0.5,
)
denoising_radius: IntProperty(
name="Denoising Radius",
description="Size of the image area that's used to denoise a pixel (higher values are smoother, but might lose detail and are slower)",
min=1, max=25,
default=8,
subtype="PIXEL",
)
denoising_relative_pca: BoolProperty(
name="Relative Filter",
description="When removing pixels that don't carry information, use a relative threshold instead of an absolute one (can help to reduce artifacts, but might cause detail loss around edges)",
default=False,
)
denoising_store_passes: BoolProperty(
name="Store Denoising Passes",
description="Store the denoising feature passes and the noisy image. The passes adapt to the denoiser selected for rendering",
default=False,
update=update_render_passes,
)
denoising_neighbor_frames: IntProperty(
name="Neighbor Frames",
description="Number of neighboring frames to use for denoising animations (more frames produce smoother results at the cost of performance)",
min=0, max=7,
default=0,
)
denoising_optix_input_passes: EnumProperty(
name="Input Passes",
description="Passes used by the denoiser to distinguish noise from shader and geometry detail",
items=enum_denoising_input_passes,
default='RGB_ALBEDO',
)
denoising_openimagedenoise_input_passes: EnumProperty(
name="Input Passes",
description="Passes used by the denoiser to distinguish noise from shader and geometry detail",
items=enum_denoising_input_passes,
default='RGB_ALBEDO_NORMAL',
)
@classmethod
def register(cls):
@@ -1454,14 +1267,16 @@ class CyclesPreferences(bpy.types.AddonPreferences):
def get_device_types(self, context):
import _cycles
has_cuda, has_optix, has_opencl = _cycles.get_device_types()
has_cuda, has_optix, has_hip = _cycles.get_device_types()
list = [('NONE', "None", "Don't use compute device", 0)]
if has_cuda:
list.append(('CUDA', "CUDA", "Use CUDA for GPU acceleration", 1))
if has_optix:
list.append(('OPTIX', "OptiX", "Use OptiX for GPU acceleration", 3))
if has_opencl:
list.append(('OPENCL', "OpenCL", "Use OpenCL for GPU acceleration", 2))
if has_hip:
list.append(('HIP', "HIP", "Use HIP for GPU acceleration", 4))
return list
compute_device_type: EnumProperty(
@@ -1486,7 +1301,7 @@ class CyclesPreferences(bpy.types.AddonPreferences):
def update_device_entries(self, device_list):
for device in device_list:
if not device[1] in {'CUDA', 'OPTIX', 'OPENCL', 'CPU'}:
if not device[1] in {'CUDA', 'OPTIX', 'CPU', 'HIP'}:
continue
# Try to find existing Device entry
entry = self.find_existing_device_entry(device)
@@ -1520,22 +1335,23 @@ class CyclesPreferences(bpy.types.AddonPreferences):
elif entry.type == 'CPU':
cpu_devices.append(entry)
# Extend all GPU devices with CPU.
if compute_device_type in {'CUDA', 'OPTIX', 'OPENCL'}:
if compute_device_type != 'CPU' and compute_device_type != 'HIP':
devices.extend(cpu_devices)
return devices
# For backwards compatibility, only returns CUDA and OpenCL but still
# refreshes all devices.
def get_devices(self, compute_device_type=''):
# Refresh device list. This does not happen automatically on Blender
# startup due to unstable OpenCL implementations that can cause crashes.
def refresh_devices(self):
import _cycles
# Ensure `self.devices` is not re-allocated when the second call to
# get_devices_for_type is made, freeing items from the first list.
for device_type in ('CUDA', 'OPTIX', 'OPENCL'):
for device_type in ('CUDA', 'OPTIX', 'HIP'):
self.update_device_entries(_cycles.available_devices(device_type))
cuda_devices = self.get_devices_for_type('CUDA')
opencl_devices = self.get_devices_for_type('OPENCL')
return cuda_devices, opencl_devices
# Deprecated: use refresh_devices instead.
def get_devices(self, compute_device_type=''):
self.refresh_devices()
return None
def get_num_gpu_devices(self):
import _cycles
@@ -1601,6 +1417,10 @@ class CyclesView3DShadingSettings(bpy.types.PropertyGroup):
items=enum_view3d_shading_render_pass,
default='COMBINED',
)
show_active_pixels: BoolProperty(
name="Show Active Pixels",
description="When using adaptive sampling highlight pixels which are being sampled",
)
def register():

View File

@@ -34,6 +34,12 @@ class CYCLES_PT_sampling_presets(PresetPanel, Panel):
preset_add_operator = "render.cycles_sampling_preset_add"
COMPAT_ENGINES = {'CYCLES'}
class CYCLES_PT_viewport_sampling_presets(PresetPanel, Panel):
bl_label = "Viewport Sampling Presets"
preset_subdir = "cycles/viewport_sampling"
preset_operator = "script.execute_preset"
preset_add_operator = "render.cycles_viewport_sampling_preset_add"
COMPAT_ENGINES = {'CYCLES'}
class CYCLES_PT_integrator_presets(PresetPanel, Panel):
bl_label = "Integrator Presets"
@@ -54,6 +60,15 @@ class CyclesButtonsPanel:
return context.engine in cls.COMPAT_ENGINES
class CyclesDebugButtonsPanel(CyclesButtonsPanel):
@classmethod
def poll(cls, context):
prefs = bpy.context.preferences
return (CyclesButtonsPanel.poll(context)
and prefs.experimental.use_cycles_debug
and prefs.view.show_developer_ui)
# Adapt properties editor panel to display in node editor. We have to
# copy the class rather than inherit due to the way bpy registration works.
def node_panel(cls):
@@ -78,30 +93,23 @@ def use_cpu(context):
return (get_device_type(context) == 'NONE' or cscene.device == 'CPU')
def use_opencl(context):
cscene = context.scene.cycles
return (get_device_type(context) == 'OPENCL' and cscene.device == 'GPU')
def use_cuda(context):
cscene = context.scene.cycles
return (get_device_type(context) == 'CUDA' and cscene.device == 'GPU')
def use_hip(context):
cscene = context.scene.cycles
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_branched_path(context):
cscene = context.scene.cycles
return (cscene.progressive == 'BRANCHED_PATH' and not use_optix(context))
def use_sample_all_lights(context):
cscene = context.scene.cycles
@@ -115,55 +123,93 @@ def show_device_active(context):
return context.preferences.addons[__package__].preferences.has_active_device()
def draw_samples_info(layout, context):
cscene = context.scene.cycles
integrator = cscene.progressive
def get_effective_preview_denoiser(context):
scene = context.scene
cscene = scene.cycles
# Calculate sample values
if integrator == 'PATH':
aa = cscene.samples
if cscene.use_square_samples:
aa = aa * aa
else:
aa = cscene.aa_samples
d = cscene.diffuse_samples
g = cscene.glossy_samples
t = cscene.transmission_samples
ao = cscene.ao_samples
ml = cscene.mesh_light_samples
sss = cscene.subsurface_samples
vol = cscene.volume_samples
if cscene.preview_denoiser != "AUTO":
return cscene.preview_denoiser
if cscene.use_square_samples:
aa = aa * aa
d = d * d
g = g * g
t = t * t
ao = ao * ao
ml = ml * ml
sss = sss * sss
vol = vol * vol
if context.preferences.addons[__package__].preferences.get_devices_for_type('OPTIX'):
return 'OPTIX'
return 'OIDN'
# Draw interface
# Do not draw for progressive, when Square Samples are disabled
if use_branched_path(context) or (cscene.use_square_samples and integrator == 'PATH'):
col = layout.column(align=True)
col.scale_y = 0.6
col.label(text="Total Samples:")
col.separator()
if integrator == 'PATH':
col.label(text="%s AA" % aa)
else:
col.label(text="%s AA, %s Diffuse, %s Glossy, %s Transmission" %
(aa, d * aa, g * aa, t * aa))
col.separator()
col.label(text="%s AO, %s Mesh Light, %s Subsurface, %s Volume" %
(ao * aa, ml * aa, sss * aa, vol * aa))
class CYCLES_RENDER_PT_sampling(CyclesButtonsPanel, Panel):
bl_label = "Sampling"
def draw(self, context):
pass
class CYCLES_RENDER_PT_sampling_viewport(CyclesButtonsPanel, Panel):
bl_label = "Viewport"
bl_parent_id = "CYCLES_RENDER_PT_sampling"
def draw_header_preset(self, context):
CYCLES_PT_viewport_sampling_presets.draw_panel_header(self.layout)
def draw(self, context):
layout = self.layout
scene = context.scene
cscene = scene.cycles
layout.use_property_split = True
layout.use_property_decorate = False
heading = layout.column(align=True, heading="Noise Threshold")
row = heading.row(align=True)
row.prop(cscene, "use_preview_adaptive_sampling", text="")
sub = row.row()
sub.active = cscene.use_preview_adaptive_sampling
sub.prop(cscene, "preview_adaptive_threshold", text="")
if cscene.use_preview_adaptive_sampling:
col = layout.column(align=True)
col.prop(cscene, "preview_samples", text=" Max Samples")
col.prop(cscene, "preview_adaptive_min_samples", text="Min Samples")
else:
layout.prop(cscene, "preview_samples", text="Samples")
class CYCLES_RENDER_PT_sampling_viewport_denoise(CyclesButtonsPanel, Panel):
bl_label = "Denoise"
bl_parent_id = 'CYCLES_RENDER_PT_sampling_viewport'
bl_options = {'DEFAULT_CLOSED'}
def draw_header(self, context):
scene = context.scene
cscene = scene.cycles
self.layout.prop(context.scene.cycles, "use_preview_denoising", text="")
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
scene = context.scene
cscene = scene.cycles
col = layout.column()
col.active = cscene.use_preview_denoising
col.prop(cscene, "preview_denoiser", text="Denoiser")
col.prop(cscene, "preview_denoising_input_passes", text="Passes")
effective_preview_denoiser = get_effective_preview_denoiser(context)
if effective_preview_denoiser == 'OPENIMAGEDENOISE':
col.prop(cscene, "preview_denoising_prefilter", text="Prefilter")
col.prop(cscene, "preview_denoising_start_sample", text="Start Sample")
class CYCLES_RENDER_PT_sampling_render(CyclesButtonsPanel, Panel):
bl_label = "Render"
bl_parent_id = "CYCLES_RENDER_PT_sampling"
def draw_header_preset(self, context):
CYCLES_PT_sampling_presets.draw_panel_header(self.layout)
@@ -176,64 +222,32 @@ class CYCLES_RENDER_PT_sampling(CyclesButtonsPanel, Panel):
layout.use_property_split = True
layout.use_property_decorate = False
if not use_optix(context):
layout.prop(cscene, "progressive")
if not use_branched_path(context):
col = layout.column(align=True)
col.prop(cscene, "samples", text="Render")
col.prop(cscene, "preview_samples", text="Viewport")
else:
col = layout.column(align=True)
col.prop(cscene, "aa_samples", text="Render")
col.prop(cscene, "preview_aa_samples", text="Viewport")
if not use_branched_path(context):
draw_samples_info(layout, context)
class CYCLES_RENDER_PT_sampling_sub_samples(CyclesButtonsPanel, Panel):
bl_label = "Sub Samples"
bl_parent_id = "CYCLES_RENDER_PT_sampling"
@classmethod
def poll(cls, context):
return use_branched_path(context)
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
scene = context.scene
cscene = scene.cycles
heading = layout.column(align=True, heading="Noise Threshold")
row = heading.row(align=True)
row.prop(cscene, "use_adaptive_sampling", text="")
sub = row.row()
sub.active = cscene.use_adaptive_sampling
sub.prop(cscene, "adaptive_threshold", text="")
col = layout.column(align=True)
col.prop(cscene, "diffuse_samples", text="Diffuse")
col.prop(cscene, "glossy_samples", text="Glossy")
col.prop(cscene, "transmission_samples", text="Transmission")
col.prop(cscene, "ao_samples", text="AO")
sub = col.row(align=True)
sub.active = use_sample_all_lights(context)
sub.prop(cscene, "mesh_light_samples", text="Mesh Light")
col.prop(cscene, "subsurface_samples", text="Subsurface")
col.prop(cscene, "volume_samples", text="Volume")
draw_samples_info(layout, context)
if cscene.use_adaptive_sampling:
col.prop(cscene, "samples", text=" Max Samples")
col.prop(cscene, "adaptive_min_samples", text="Min Samples")
else:
col.prop(cscene, "samples", text="Samples")
col.prop(cscene, "time_limit")
class CYCLES_RENDER_PT_sampling_adaptive(CyclesButtonsPanel, Panel):
bl_label = "Adaptive Sampling"
bl_parent_id = "CYCLES_RENDER_PT_sampling"
class CYCLES_RENDER_PT_sampling_render_denoise(CyclesButtonsPanel, Panel):
bl_label = "Denoise"
bl_parent_id = 'CYCLES_RENDER_PT_sampling_render'
bl_options = {'DEFAULT_CLOSED'}
def draw_header(self, context):
layout = self.layout
scene = context.scene
cscene = scene.cycles
layout.prop(cscene, "use_adaptive_sampling", text="")
self.layout.prop(context.scene.cycles, "use_denoising", text="")
def draw(self, context):
layout = self.layout
@@ -243,53 +257,12 @@ class CYCLES_RENDER_PT_sampling_adaptive(CyclesButtonsPanel, Panel):
scene = context.scene
cscene = scene.cycles
layout.active = cscene.use_adaptive_sampling
col = layout.column(align=True)
col.prop(cscene, "adaptive_threshold", text="Noise Threshold")
col.prop(cscene, "adaptive_min_samples", text="Min Samples")
class CYCLES_RENDER_PT_sampling_denoising(CyclesButtonsPanel, Panel):
bl_label = "Denoising"
bl_parent_id = "CYCLES_RENDER_PT_sampling"
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
scene = context.scene
cscene = scene.cycles
heading = layout.column(align=True, heading="Render")
row = heading.row(align=True)
row.prop(cscene, "use_denoising", text="")
sub = row.row()
sub.active = cscene.use_denoising
for view_layer in scene.view_layers:
if view_layer.cycles.denoising_store_passes:
sub.active = True
sub.prop(cscene, "denoiser", text="")
layout.separator()
heading = layout.column(align=False, heading="Viewport")
row = heading.row(align=True)
row.prop(cscene, "use_preview_denoising", text="")
sub = row.row()
sub.active = cscene.use_preview_denoising
sub.prop(cscene, "preview_denoiser", text="")
sub = heading.row(align=True)
sub.active = cscene.use_preview_denoising
sub.prop(cscene, "preview_denoising_start_sample", text="Start Sample")
sub = heading.row(align=True)
sub.active = cscene.use_preview_denoising
sub.prop(cscene, "preview_denoising_input_passes", text="Input Passes")
col = layout.column()
col.active = cscene.use_denoising
col.prop(cscene, "denoiser", text="Denoiser")
col.prop(cscene, "denoising_input_passes", text="Passes")
if cscene.denoiser == 'OPENIMAGEDENOISE':
col.prop(cscene, "denoising_prefilter", text="Prefilter")
class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel):
@@ -313,8 +286,6 @@ class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel):
col.active = not(cscene.use_adaptive_sampling)
col.prop(cscene, "sampling_pattern", text="Pattern")
layout.prop(cscene, "use_square_samples")
layout.separator()
col = layout.column(align=True)
@@ -322,11 +293,6 @@ class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel):
col.prop(cscene, "min_transparent_bounces")
col.prop(cscene, "light_sampling_threshold", text="Light Threshold")
if cscene.progressive != 'PATH' and use_branched_path(context):
col = layout.column(align=True)
col.prop(cscene, "sample_all_lights_direct")
col.prop(cscene, "sample_all_lights_indirect")
for view_layer in scene.view_layers:
if view_layer.samples > 0:
layout.separator()
@@ -334,62 +300,6 @@ class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel):
break
class CYCLES_RENDER_PT_sampling_total(CyclesButtonsPanel, Panel):
bl_label = "Total Samples"
bl_parent_id = "CYCLES_RENDER_PT_sampling"
@classmethod
def poll(cls, context):
scene = context.scene
cscene = scene.cycles
if cscene.use_square_samples:
return True
return cscene.progressive != 'PATH' and use_branched_path(context)
def draw(self, context):
layout = self.layout
cscene = context.scene.cycles
integrator = cscene.progressive
# Calculate sample values
if integrator == 'PATH':
aa = cscene.samples
if cscene.use_square_samples:
aa = aa * aa
else:
aa = cscene.aa_samples
d = cscene.diffuse_samples
g = cscene.glossy_samples
t = cscene.transmission_samples
ao = cscene.ao_samples
ml = cscene.mesh_light_samples
sss = cscene.subsurface_samples
vol = cscene.volume_samples
if cscene.use_square_samples:
aa = aa * aa
d = d * d
g = g * g
t = t * t
ao = ao * ao
ml = ml * ml
sss = sss * sss
vol = vol * vol
col = layout.column(align=True)
col.scale_y = 0.6
if integrator == 'PATH':
col.label(text="%s AA" % aa)
else:
col.label(text="%s AA, %s Diffuse, %s Glossy, %s Transmission" %
(aa, d * aa, g * aa, t * aa))
col.separator()
col.label(text="%s AO, %s Mesh Light, %s Subsurface, %s Volume" %
(ao * aa, ml * aa, sss * aa, vol * aa))
class CYCLES_RENDER_PT_subdivision(CyclesButtonsPanel, Panel):
bl_label = "Subdivision"
bl_options = {'DEFAULT_CLOSED'}
@@ -548,6 +458,8 @@ class CYCLES_RENDER_PT_light_paths_fast_gi(CyclesButtonsPanel, Panel):
layout.use_property_split = True
layout.use_property_decorate = False
layout.active = cscene.use_fast_gi
col = layout.column(align=True)
col.prop(cscene, "ao_bounces", text="Viewport Bounces")
col.prop(cscene, "ao_bounces_render", text="Render Bounces")
@@ -706,8 +618,8 @@ class CYCLES_RENDER_PT_performance_threads(CyclesButtonsPanel, Panel):
sub.prop(rd, "threads")
class CYCLES_RENDER_PT_performance_tiles(CyclesButtonsPanel, Panel):
bl_label = "Tiles"
class CYCLES_RENDER_PT_performance_memory(CyclesButtonsPanel, Panel):
bl_label = "Memory"
bl_parent_id = "CYCLES_RENDER_PT_performance"
def draw(self, context):
@@ -716,19 +628,13 @@ class CYCLES_RENDER_PT_performance_tiles(CyclesButtonsPanel, Panel):
layout.use_property_decorate = False
scene = context.scene
rd = scene.render
cscene = scene.cycles
col = layout.column()
sub = col.column(align=True)
sub.prop(rd, "tile_x", text="Tiles X")
sub.prop(rd, "tile_y", text="Y")
col.prop(cscene, "tile_order", text="Order")
col.prop(cscene, "use_auto_tile")
sub = col.column()
sub.active = not rd.use_save_buffers and not cscene.use_adaptive_sampling
sub.prop(cscene, "use_progressive_refine")
sub.active = cscene.use_auto_tile
sub.prop(cscene, "tile_size")
class CYCLES_RENDER_PT_performance_acceleration_structure(CyclesButtonsPanel, Panel):
@@ -778,7 +684,6 @@ class CYCLES_RENDER_PT_performance_final_render(CyclesButtonsPanel, Panel):
col = layout.column()
col.prop(rd, "use_save_buffers")
col.prop(rd, "use_persistent_data", text="Persistent Data")
@@ -797,7 +702,6 @@ class CYCLES_RENDER_PT_performance_viewport(CyclesButtonsPanel, Panel):
col = layout.column()
col.prop(rd, "preview_pixel_size", text="Pixel Size")
col.prop(cscene, "preview_start_resolution", text="Start Pixels")
class CYCLES_RENDER_PT_filter(CyclesButtonsPanel, Panel):
@@ -818,7 +722,6 @@ class CYCLES_RENDER_PT_filter(CyclesButtonsPanel, Panel):
col = layout.column(heading="Include")
col.prop(view_layer, "use_sky", text="Environment")
col.prop(view_layer, "use_ao", text="Ambient Occlusion")
col.prop(view_layer, "use_solid", text="Surfaces")
col.prop(view_layer, "use_strand", text="Hair")
col.prop(view_layer, "use_volumes", text="Volumes")
@@ -827,6 +730,9 @@ class CYCLES_RENDER_PT_filter(CyclesButtonsPanel, Panel):
sub = col.row()
sub.prop(view_layer, "use_motion_blur", text="Motion Blur")
sub.active = rd.use_motion_blur
sub = col.row()
sub.prop(view_layer.cycles, 'use_denoising', text='Denoising')
sub.active = scene.cycles.use_denoising
class CYCLES_RENDER_PT_override(CyclesButtonsPanel, Panel):
@@ -872,6 +778,7 @@ class CYCLES_RENDER_PT_passes_data(CyclesButtonsPanel, Panel):
col.prop(view_layer, "use_pass_combined")
col.prop(view_layer, "use_pass_z")
col.prop(view_layer, "use_pass_mist")
col.prop(view_layer, "use_pass_position")
col.prop(view_layer, "use_pass_normal")
sub = col.column()
sub.active = not rd.use_motion_blur
@@ -928,6 +835,7 @@ class CYCLES_RENDER_PT_passes_light(CyclesButtonsPanel, Panel):
col.prop(view_layer, "use_pass_environment")
col.prop(view_layer, "use_pass_shadow")
col.prop(view_layer, "use_pass_ambient_occlusion", text="Ambient Occlusion")
col.prop(cycles_view_layer, "use_pass_shadow_catcher")
class CYCLES_RENDER_PT_passes_crypto(CyclesButtonsPanel, ViewLayerCryptomattePanel, Panel):
@@ -942,70 +850,6 @@ class CYCLES_RENDER_PT_passes_aov(CyclesButtonsPanel, ViewLayerAOVPanel):
bl_parent_id = "CYCLES_RENDER_PT_passes"
class CYCLES_RENDER_PT_denoising(CyclesButtonsPanel, Panel):
bl_label = "Denoising"
bl_context = "view_layer"
bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
cscene = context.scene.cycles
return CyclesButtonsPanel.poll(context) and cscene.use_denoising
def draw_header(self, context):
scene = context.scene
view_layer = context.view_layer
cycles_view_layer = view_layer.cycles
layout = self.layout
layout.prop(cycles_view_layer, "use_denoising", text="")
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
scene = context.scene
view_layer = context.view_layer
cycles_view_layer = view_layer.cycles
denoiser = scene.cycles.denoiser
layout.active = denoiser != 'NONE' and cycles_view_layer.use_denoising
col = layout.column()
if denoiser == 'OPTIX':
col.prop(cycles_view_layer, "denoising_optix_input_passes")
return
elif denoiser == 'OPENIMAGEDENOISE':
col.prop(cycles_view_layer, "denoising_openimagedenoise_input_passes")
return
col.prop(cycles_view_layer, "denoising_radius", text="Radius")
col = layout.column()
col.prop(cycles_view_layer, "denoising_strength", slider=True, text="Strength")
col.prop(cycles_view_layer, "denoising_feature_strength", slider=True, text="Feature Strength")
col.prop(cycles_view_layer, "denoising_relative_pca")
layout.separator()
col = layout.column()
col.active = cycles_view_layer.use_denoising or cycles_view_layer.denoising_store_passes
row = col.row(heading="Diffuse", align=True)
row.prop(cycles_view_layer, "denoising_diffuse_direct", text="Direct", toggle=True)
row.prop(cycles_view_layer, "denoising_diffuse_indirect", text="Indirect", toggle=True)
row = col.row(heading="Glossy", align=True)
row.prop(cycles_view_layer, "denoising_glossy_direct", text="Direct", toggle=True)
row.prop(cycles_view_layer, "denoising_glossy_indirect", text="Indirect", toggle=True)
row = col.row(heading="Transmission", align=True)
row.prop(cycles_view_layer, "denoising_transmission_direct", text="Direct", toggle=True)
row.prop(cycles_view_layer, "denoising_transmission_indirect", text="Indirect", toggle=True)
class CYCLES_PT_post_processing(CyclesButtonsPanel, Panel):
bl_label = "Post Processing"
bl_options = {'DEFAULT_CLOSED'}
@@ -1417,10 +1261,6 @@ class CYCLES_LIGHT_PT_light(CyclesButtonsPanel, Panel):
if not (light.type == 'AREA' and clamp.is_portal):
sub = col.column()
if use_branched_path(context):
subsub = sub.row(align=True)
subsub.active = use_sample_all_lights(context)
subsub.prop(clamp, "samples")
sub.prop(clamp, "max_bounces")
sub = col.column(align=True)
@@ -1526,34 +1366,6 @@ class CYCLES_WORLD_PT_volume(CyclesButtonsPanel, Panel):
panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Volume')
class CYCLES_WORLD_PT_ambient_occlusion(CyclesButtonsPanel, Panel):
bl_label = "Ambient Occlusion"
bl_context = "world"
bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
return context.world and CyclesButtonsPanel.poll(context)
def draw_header(self, context):
light = context.world.light_settings
self.layout.prop(light, "use_ambient_occlusion", text="")
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
light = context.world.light_settings
scene = context.scene
col = layout.column()
sub = col.column()
sub.active = light.use_ambient_occlusion or scene.render.use_simplify
sub.prop(light, "ao_factor", text="Factor")
col.prop(light, "distance", text="Distance")
class CYCLES_WORLD_PT_mist(CyclesButtonsPanel, Panel):
bl_label = "Mist Pass"
bl_context = "world"
@@ -1650,10 +1462,6 @@ class CYCLES_WORLD_PT_settings_surface(CyclesButtonsPanel, Panel):
subsub = sub.row(align=True)
subsub.active = cworld.sampling_method == 'MANUAL'
subsub.prop(cworld, "sample_map_resolution")
if use_branched_path(context):
subsub = sub.column(align=True)
subsub.active = use_sample_all_lights(context)
subsub.prop(cworld, "samples")
sub.prop(cworld, "max_bounces")
@@ -1677,8 +1485,7 @@ class CYCLES_WORLD_PT_settings_volume(CyclesButtonsPanel, Panel):
col = layout.column()
sub = col.column()
sub.active = use_cpu(context)
sub.prop(cworld, "volume_sampling", text="Sampling")
col.prop(cworld, "volume_sampling", text="Sampling")
col.prop(cworld, "volume_interpolation", text="Interpolation")
col.prop(cworld, "homogeneous_volume", text="Homogeneous")
sub = col.column()
@@ -1817,8 +1624,7 @@ class CYCLES_MATERIAL_PT_settings_volume(CyclesButtonsPanel, Panel):
col = layout.column()
sub = col.column()
sub.active = use_cpu(context)
sub.prop(cmat, "volume_sampling", text="Sampling")
col.prop(cmat, "volume_sampling", text="Sampling")
col.prop(cmat, "volume_interpolation", text="Interpolation")
col.prop(cmat, "homogeneous_volume", text="Homogeneous")
sub = col.column()
@@ -1845,9 +1651,6 @@ class CYCLES_RENDER_PT_bake(CyclesButtonsPanel, Panel):
cbk = scene.render.bake
rd = scene.render
if use_optix(context):
layout.label(text="Baking is performed using CUDA instead of OptiX", icon='INFO')
if rd.use_bake_multires:
layout.operator("object.bake_image", icon='RENDER_STILL')
layout.prop(rd, "use_bake_multires")
@@ -1905,7 +1708,6 @@ class CYCLES_RENDER_PT_bake_influence(CyclesButtonsPanel, Panel):
col.prop(cbk, "use_pass_diffuse")
col.prop(cbk, "use_pass_glossy")
col.prop(cbk, "use_pass_transmission")
col.prop(cbk, "use_pass_ambient_occlusion")
col.prop(cbk, "use_pass_emit")
elif cscene.bake_type in {'DIFFUSE', 'GLOSSY', 'TRANSMISSION'}:
@@ -1989,19 +1791,12 @@ class CYCLES_RENDER_PT_bake_output(CyclesButtonsPanel, Panel):
layout.prop(cbk, "use_clear", text="Clear Image")
class CYCLES_RENDER_PT_debug(CyclesButtonsPanel, Panel):
class CYCLES_RENDER_PT_debug(CyclesDebugButtonsPanel, Panel):
bl_label = "Debug"
bl_context = "render"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'CYCLES'}
@classmethod
def poll(cls, context):
prefs = bpy.context.preferences
return (CyclesButtonsPanel.poll(context)
and prefs.experimental.use_cycles_debug
and prefs.view.show_developer_ui)
def draw(self, context):
layout = self.layout
@@ -2018,29 +1813,18 @@ class CYCLES_RENDER_PT_debug(CyclesButtonsPanel, Panel):
row.prop(cscene, "debug_use_cpu_avx", toggle=True)
row.prop(cscene, "debug_use_cpu_avx2", toggle=True)
col.prop(cscene, "debug_bvh_layout")
col.prop(cscene, "debug_use_cpu_split_kernel")
col.separator()
col = layout.column()
col.label(text="CUDA Flags:")
col.prop(cscene, "debug_use_cuda_adaptive_compile")
col.prop(cscene, "debug_use_cuda_split_kernel")
col.separator()
col = layout.column()
col.label(text="OptiX Flags:")
col.prop(cscene, "debug_optix_cuda_streams")
col.prop(cscene, "debug_optix_curves_api")
col.separator()
col = layout.column()
col.label(text="OpenCL Flags:")
col.prop(cscene, "debug_opencl_device_type", text="Device")
col.prop(cscene, "debug_use_opencl_debug", text="Debug")
col.prop(cscene, "debug_opencl_mem_limit")
col.prop(cscene, "debug_use_optix_debug")
col.separator()
@@ -2141,20 +1925,22 @@ class CYCLES_RENDER_PT_simplify_culling(CyclesButtonsPanel, Panel):
sub.prop(cscene, "distance_cull_margin", text="")
class CYCLES_VIEW3D_PT_shading_render_pass(Panel):
class CyclesShadingButtonsPanel(CyclesButtonsPanel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'HEADER'
bl_label = "Render Pass"
bl_parent_id = 'VIEW3D_PT_shading'
COMPAT_ENGINES = {'CYCLES'}
@classmethod
def poll(cls, context):
return (
context.engine in cls.COMPAT_ENGINES and
CyclesButtonsPanel.poll(context) and
context.space_data.shading.type == 'RENDERED'
)
class CYCLES_VIEW3D_PT_shading_render_pass(CyclesShadingButtonsPanel, Panel):
bl_label = "Render Pass"
def draw(self, context):
shading = context.space_data.shading
@@ -2162,6 +1948,26 @@ class CYCLES_VIEW3D_PT_shading_render_pass(Panel):
layout.prop(shading.cycles, "render_pass", text="")
class CYCLES_VIEW3D_PT_shading_debug(CyclesDebugButtonsPanel,
CyclesShadingButtonsPanel,
Panel):
bl_label = "Debug"
@classmethod
def poll(cls, context):
return (
CyclesDebugButtonsPanel.poll(context) and
CyclesShadingButtonsPanel.poll(context)
)
def draw(self, context):
shading = context.space_data.shading
layout = self.layout
layout.active = context.scene.cycles.use_preview_adaptive_sampling
layout.prop(shading.cycles, "show_active_pixels")
class CYCLES_VIEW3D_PT_shading_lighting(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'HEADER'
@@ -2275,11 +2081,13 @@ def get_panels():
classes = (
CYCLES_PT_sampling_presets,
CYCLES_PT_viewport_sampling_presets,
CYCLES_PT_integrator_presets,
CYCLES_RENDER_PT_sampling,
CYCLES_RENDER_PT_sampling_sub_samples,
CYCLES_RENDER_PT_sampling_adaptive,
CYCLES_RENDER_PT_sampling_denoising,
CYCLES_RENDER_PT_sampling_viewport,
CYCLES_RENDER_PT_sampling_viewport_denoise,
CYCLES_RENDER_PT_sampling_render,
CYCLES_RENDER_PT_sampling_render_denoise,
CYCLES_RENDER_PT_sampling_advanced,
CYCLES_RENDER_PT_light_paths,
CYCLES_RENDER_PT_light_paths_max_bounces,
@@ -2296,6 +2104,7 @@ classes = (
CYCLES_VIEW3D_PT_simplify_greasepencil,
CYCLES_VIEW3D_PT_shading_lighting,
CYCLES_VIEW3D_PT_shading_render_pass,
CYCLES_VIEW3D_PT_shading_debug,
CYCLES_RENDER_PT_motion_blur,
CYCLES_RENDER_PT_motion_blur_curve,
CYCLES_RENDER_PT_film,
@@ -2303,7 +2112,7 @@ classes = (
CYCLES_RENDER_PT_film_transparency,
CYCLES_RENDER_PT_performance,
CYCLES_RENDER_PT_performance_threads,
CYCLES_RENDER_PT_performance_tiles,
CYCLES_RENDER_PT_performance_memory,
CYCLES_RENDER_PT_performance_acceleration_structure,
CYCLES_RENDER_PT_performance_final_render,
CYCLES_RENDER_PT_performance_viewport,
@@ -2314,7 +2123,6 @@ classes = (
CYCLES_RENDER_PT_passes_aov,
CYCLES_RENDER_PT_filter,
CYCLES_RENDER_PT_override,
CYCLES_RENDER_PT_denoising,
CYCLES_PT_post_processing,
CYCLES_CAMERA_PT_dof,
CYCLES_CAMERA_PT_dof_aperture,
@@ -2333,7 +2141,6 @@ classes = (
CYCLES_WORLD_PT_preview,
CYCLES_WORLD_PT_surface,
CYCLES_WORLD_PT_volume,
CYCLES_WORLD_PT_ambient_occlusion,
CYCLES_WORLD_PT_mist,
CYCLES_WORLD_PT_ray_visibility,
CYCLES_WORLD_PT_settings,

View File

@@ -109,7 +109,7 @@ def do_versions(self):
library_versions.setdefault(library.version, []).append(library)
# Do versioning per library, since they might have different versions.
max_need_versioning = (2, 93, 7)
max_need_versioning = (3, 0, 25)
for version, libraries in library_versions.items():
if version > max_need_versioning:
continue
@@ -166,10 +166,6 @@ def do_versions(self):
if not cscene.is_property_set("filter_type"):
cscene.pixel_filter_type = 'GAUSSIAN'
# Tile Order
if not cscene.is_property_set("tile_order"):
cscene.tile_order = 'CENTER'
if version <= (2, 76, 10):
cscene = scene.cycles
if cscene.is_property_set("filter_type"):
@@ -186,10 +182,6 @@ def do_versions(self):
if version <= (2, 79, 0):
cscene = scene.cycles
# Default changes
if not cscene.is_property_set("aa_samples"):
cscene.aa_samples = 4
if not cscene.is_property_set("preview_aa_samples"):
cscene.preview_aa_samples = 4
if not cscene.is_property_set("blur_glossy"):
cscene.blur_glossy = 0.0
if not cscene.is_property_set("sample_clamp_indirect"):
@@ -203,7 +195,6 @@ def do_versions(self):
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)
view_layer.use_pass_cryptomatte_accurate = cview_layer.get("pass_crypto_accurate", True)
if version <= (2, 93, 7):
if scene.render.engine == 'CYCLES':
@@ -229,6 +220,35 @@ def do_versions(self):
cscene.ao_bounces = 1
cscene.ao_bounces_render = 1
if version <= (3, 0, 25):
cscene = scene.cycles
# Default changes.
if not cscene.is_property_set("samples"):
cscene.samples = 128
if not cscene.is_property_set("preview_samples"):
cscene.preview_samples = 32
if not cscene.is_property_set("use_adaptive_sampling"):
cscene.use_adaptive_sampling = False
cscene.use_preview_adaptive_sampling = False
if not cscene.is_property_set("use_denoising"):
cscene.use_denoising = False
if not cscene.is_property_set("use_preview_denoising"):
cscene.use_preview_denoising = False
if not cscene.is_property_set("sampling_pattern"):
cscene.sampling_pattern = 'PROGRESSIVE_MUTI_JITTER'
# Removal of square samples.
cscene = scene.cycles
use_square_samples = cscene.get("use_square_samples", False)
if use_square_samples:
cscene.samples *= cscene.samples
cscene.preview_samples *= cscene.preview_samples
for layer in scene.view_layers:
layer.samples *= layer.samples
cscene["use_square_samples"] = False
# Lamps
for light in bpy.data.lights:
if light.library not in libraries:
@@ -249,10 +269,6 @@ def do_versions(self):
if version <= (2, 76, 9):
cworld = world.cycles
# World MIS Samples
if not cworld.is_property_set("samples"):
cworld.samples = 4
# World MIS Resolution
if not cworld.is_property_set("sample_map_resolution"):
cworld.sample_map_resolution = 256

View File

@@ -894,12 +894,8 @@ void BlenderSync::sync_view(BL::SpaceView3D &b_v3d,
}
}
BufferParams BlenderSync::get_buffer_params(BL::SpaceView3D &b_v3d,
BL::RegionView3D &b_rv3d,
Camera *cam,
int width,
int height,
const bool use_denoiser)
BufferParams BlenderSync::get_buffer_params(
BL::SpaceView3D &b_v3d, BL::RegionView3D &b_rv3d, Camera *cam, int width, int height)
{
BufferParams params;
bool use_border = false;
@@ -931,11 +927,6 @@ BufferParams BlenderSync::get_buffer_params(BL::SpaceView3D &b_v3d,
params.height = height;
}
PassType display_pass = update_viewport_display_passes(b_v3d, params.passes);
/* Can only denoise the combined image pass */
params.denoising_data_pass = display_pass == PASS_COMBINED && use_denoiser;
return params;
}

View File

@@ -283,10 +283,13 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa
return;
Attribute *attr_intercept = NULL;
Attribute *attr_length = NULL;
Attribute *attr_random = NULL;
if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT))
attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT);
if (hair->need_attribute(scene, ATTR_STD_CURVE_LENGTH))
attr_length = hair->attributes.add(ATTR_STD_CURVE_LENGTH);
if (hair->need_attribute(scene, ATTR_STD_CURVE_RANDOM))
attr_random = hair->attributes.add(ATTR_STD_CURVE_RANDOM);
@@ -336,6 +339,10 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa
num_curve_keys++;
}
if (attr_length != NULL) {
attr_length->add(CData->curve_length[curve]);
}
if (attr_random != NULL) {
attr_random->add(hash_uint2_to_float(num_curves, 0));
}
@@ -526,8 +533,13 @@ bool BlenderSync::object_has_particle_hair(BL::Object b_ob)
/* Old particle hair. */
void BlenderSync::sync_particle_hair(
Hair *hair, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step)
Hair *hair, BL::Mesh &b_mesh, BObjectInfo &b_ob_info, bool motion, int motion_step)
{
if (!b_ob_info.is_real_object_data()) {
return;
}
BL::Object b_ob = b_ob_info.real_object;
/* obtain general settings */
if (b_ob.mode() == b_ob.mode_PARTICLE_EDIT || b_ob.mode() == b_ob.mode_EDIT) {
return;
@@ -652,11 +664,15 @@ static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
/* Add requested attributes. */
Attribute *attr_intercept = NULL;
Attribute *attr_length = NULL;
Attribute *attr_random = NULL;
if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT)) {
attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT);
}
if (hair->need_attribute(scene, ATTR_STD_CURVE_LENGTH)) {
attr_length = hair->attributes.add(ATTR_STD_CURVE_LENGTH);
}
if (hair->need_attribute(scene, ATTR_STD_CURVE_RANDOM)) {
attr_random = hair->attributes.add(ATTR_STD_CURVE_RANDOM);
}
@@ -709,6 +725,10 @@ static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
}
}
if (attr_length) {
attr_length->add(length);
}
/* Random number per curve. */
if (attr_random != NULL) {
attr_random->add(hash_uint2_to_float(b_curve.index(), 0));
@@ -788,10 +808,10 @@ static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_st
}
/* Hair object. */
void BlenderSync::sync_hair(Hair *hair, BL::Object &b_ob, bool motion, int motion_step)
void BlenderSync::sync_hair(Hair *hair, BObjectInfo &b_ob_info, bool motion, int motion_step)
{
/* Convert Blender hair to Cycles curves. */
BL::Hair b_hair(b_ob.data());
BL::Hair b_hair(b_ob_info.object_data);
if (motion) {
export_hair_curves_motion(hair, b_hair, motion_step);
}
@@ -800,16 +820,16 @@ void BlenderSync::sync_hair(Hair *hair, BL::Object &b_ob, bool motion, int motio
}
}
#else
void BlenderSync::sync_hair(Hair *hair, BL::Object &b_ob, bool motion, int motion_step)
void BlenderSync::sync_hair(Hair *hair, BObjectInfo &b_ob_info, bool motion, int motion_step)
{
(void)hair;
(void)b_ob;
(void)b_ob_info;
(void)motion;
(void)motion_step;
}
#endif
void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Hair *hair)
void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, Hair *hair)
{
/* make a copy of the shaders as the caller in the main thread still need them for syncing the
* attributes */
@@ -819,19 +839,19 @@ void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Hair *ha
new_hair.set_used_shaders(used_shaders);
if (view_layer.use_hair) {
if (b_ob.type() == BL::Object::type_HAIR) {
if (b_ob_info.object_data.is_a(&RNA_Hair)) {
/* Hair object. */
sync_hair(&new_hair, b_ob, false);
sync_hair(&new_hair, b_ob_info, false);
}
else {
/* Particle hair. */
bool need_undeformed = new_hair.need_attribute(scene, ATTR_STD_GENERATED);
BL::Mesh b_mesh = object_to_mesh(
b_data, b_ob, b_depsgraph, need_undeformed, Mesh::SUBDIVISION_NONE);
b_data, b_ob_info, b_depsgraph, need_undeformed, Mesh::SUBDIVISION_NONE);
if (b_mesh) {
sync_particle_hair(&new_hair, b_mesh, b_ob, false);
free_object_to_mesh(b_data, b_ob, b_mesh);
sync_particle_hair(&new_hair, b_mesh, b_ob_info, false);
free_object_to_mesh(b_data, b_ob_info, b_mesh);
}
}
}
@@ -859,7 +879,7 @@ void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Hair *ha
}
void BlenderSync::sync_hair_motion(BL::Depsgraph b_depsgraph,
BL::Object b_ob,
BObjectInfo &b_ob_info,
Hair *hair,
int motion_step)
{
@@ -869,18 +889,19 @@ void BlenderSync::sync_hair_motion(BL::Depsgraph b_depsgraph,
}
/* Export deformed coordinates. */
if (ccl::BKE_object_is_deform_modified(b_ob, b_scene, preview)) {
if (b_ob.type() == BL::Object::type_HAIR) {
if (ccl::BKE_object_is_deform_modified(b_ob_info, b_scene, preview)) {
if (b_ob_info.object_data.is_a(&RNA_Hair)) {
/* Hair object. */
sync_hair(hair, b_ob, true, motion_step);
sync_hair(hair, b_ob_info, true, motion_step);
return;
}
else {
/* Particle hair. */
BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_depsgraph, false, Mesh::SUBDIVISION_NONE);
BL::Mesh b_mesh = object_to_mesh(
b_data, b_ob_info, b_depsgraph, false, Mesh::SUBDIVISION_NONE);
if (b_mesh) {
sync_particle_hair(hair, b_mesh, b_ob, true, motion_step);
free_object_to_mesh(b_data, b_ob, b_mesh);
sync_particle_hair(hair, b_mesh, b_ob_info, true, motion_step);
free_object_to_mesh(b_data, b_ob_info, b_mesh);
return;
}
}

View File

@@ -25,8 +25,8 @@ CCL_NAMESPACE_BEGIN
enum ComputeDevice {
COMPUTE_DEVICE_CPU = 0,
COMPUTE_DEVICE_CUDA = 1,
COMPUTE_DEVICE_OPENCL = 2,
COMPUTE_DEVICE_OPTIX = 3,
COMPUTE_DEVICE_HIP = 4,
COMPUTE_DEVICE_NUM
};
@@ -68,13 +68,6 @@ DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scen
device = Device::get_multi_device(devices, threads, background);
}
}
else if (get_enum(cscene, "device") == 2) {
/* Find network device. */
vector<DeviceInfo> devices = Device::available_devices(DEVICE_MASK_NETWORK);
if (!devices.empty()) {
device = devices.front();
}
}
else if (get_enum(cscene, "device") == 1) {
/* Test if we are using GPU devices. */
ComputeDevice compute_device = (ComputeDevice)get_enum(
@@ -89,8 +82,8 @@ DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scen
else if (compute_device == COMPUTE_DEVICE_OPTIX) {
mask |= DEVICE_MASK_OPTIX;
}
else if (compute_device == COMPUTE_DEVICE_OPENCL) {
mask |= DEVICE_MASK_OPENCL;
else if (compute_device == COMPUTE_DEVICE_HIP) {
mask |= DEVICE_MASK_HIP;
}
vector<DeviceInfo> devices = Device::available_devices(mask);

View File

@@ -0,0 +1,754 @@
/*
* Copyright 2021 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "blender/blender_display_driver.h"
#include "device/device.h"
#include "util/util_logging.h"
#include "util/util_opengl.h"
extern "C" {
struct RenderEngine;
bool RE_engine_has_render_context(struct RenderEngine *engine);
void RE_engine_render_context_enable(struct RenderEngine *engine);
void RE_engine_render_context_disable(struct RenderEngine *engine);
bool DRW_opengl_context_release();
void DRW_opengl_context_activate(bool drw_state);
void *WM_opengl_context_create();
void WM_opengl_context_activate(void *gl_context);
void WM_opengl_context_dispose(void *gl_context);
void WM_opengl_context_release(void *context);
}
CCL_NAMESPACE_BEGIN
/* --------------------------------------------------------------------
* BlenderDisplayShader.
*/
unique_ptr<BlenderDisplayShader> BlenderDisplayShader::create(BL::RenderEngine &b_engine,
BL::Scene &b_scene)
{
if (b_engine.support_display_space_shader(b_scene)) {
return make_unique<BlenderDisplaySpaceShader>(b_engine, b_scene);
}
return make_unique<BlenderFallbackDisplayShader>();
}
int BlenderDisplayShader::get_position_attrib_location()
{
if (position_attribute_location_ == -1) {
const uint shader_program = get_shader_program();
position_attribute_location_ = glGetAttribLocation(shader_program, position_attribute_name);
}
return position_attribute_location_;
}
int BlenderDisplayShader::get_tex_coord_attrib_location()
{
if (tex_coord_attribute_location_ == -1) {
const uint shader_program = get_shader_program();
tex_coord_attribute_location_ = glGetAttribLocation(shader_program, tex_coord_attribute_name);
}
return tex_coord_attribute_location_;
}
/* --------------------------------------------------------------------
* BlenderFallbackDisplayShader.
*/
/* TODO move shaders to standalone .glsl file. */
static const char *FALLBACK_VERTEX_SHADER =
"#version 330\n"
"uniform vec2 fullscreen;\n"
"in vec2 texCoord;\n"
"in vec2 pos;\n"
"out vec2 texCoord_interp;\n"
"\n"
"vec2 normalize_coordinates()\n"
"{\n"
" return (vec2(2.0) * (pos / fullscreen)) - vec2(1.0);\n"
"}\n"
"\n"
"void main()\n"
"{\n"
" gl_Position = vec4(normalize_coordinates(), 0.0, 1.0);\n"
" texCoord_interp = texCoord;\n"
"}\n\0";
static const char *FALLBACK_FRAGMENT_SHADER =
"#version 330\n"
"uniform sampler2D image_texture;\n"
"in vec2 texCoord_interp;\n"
"out vec4 fragColor;\n"
"\n"
"void main()\n"
"{\n"
" fragColor = texture(image_texture, texCoord_interp);\n"
"}\n\0";
static void shader_print_errors(const char *task, const char *log, const char *code)
{
LOG(ERROR) << "Shader: " << task << " error:";
LOG(ERROR) << "===== shader string ====";
stringstream stream(code);
string partial;
int line = 1;
while (getline(stream, partial, '\n')) {
if (line < 10) {
LOG(ERROR) << " " << line << " " << partial;
}
else {
LOG(ERROR) << line << " " << partial;
}
line++;
}
LOG(ERROR) << log;
}
static int compile_fallback_shader(void)
{
const struct Shader {
const char *source;
const GLenum type;
} shaders[2] = {{FALLBACK_VERTEX_SHADER, GL_VERTEX_SHADER},
{FALLBACK_FRAGMENT_SHADER, GL_FRAGMENT_SHADER}};
const GLuint program = glCreateProgram();
for (int i = 0; i < 2; i++) {
const GLuint shader = glCreateShader(shaders[i].type);
string source_str = shaders[i].source;
const char *c_str = source_str.c_str();
glShaderSource(shader, 1, &c_str, NULL);
glCompileShader(shader);
GLint compile_status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status);
if (!compile_status) {
GLchar log[5000];
GLsizei length = 0;
glGetShaderInfoLog(shader, sizeof(log), &length, log);
shader_print_errors("compile", log, c_str);
return 0;
}
glAttachShader(program, shader);
}
/* Link output. */
glBindFragDataLocation(program, 0, "fragColor");
/* Link and error check. */
glLinkProgram(program);
/* TODO(sergey): Find a way to nicely de-duplicate the error checking. */
GLint link_status;
glGetProgramiv(program, GL_LINK_STATUS, &link_status);
if (!link_status) {
GLchar log[5000];
GLsizei length = 0;
/* TODO(sergey): Is it really program passed to glGetShaderInfoLog? */
glGetShaderInfoLog(program, sizeof(log), &length, log);
shader_print_errors("linking", log, FALLBACK_VERTEX_SHADER);
shader_print_errors("linking", log, FALLBACK_FRAGMENT_SHADER);
return 0;
}
return program;
}
void BlenderFallbackDisplayShader::bind(int width, int height)
{
create_shader_if_needed();
if (!shader_program_) {
return;
}
glUseProgram(shader_program_);
glUniform1i(image_texture_location_, 0);
glUniform2f(fullscreen_location_, width, height);
}
void BlenderFallbackDisplayShader::unbind()
{
}
uint BlenderFallbackDisplayShader::get_shader_program()
{
return shader_program_;
}
void BlenderFallbackDisplayShader::create_shader_if_needed()
{
if (shader_program_ || shader_compile_attempted_) {
return;
}
shader_compile_attempted_ = true;
shader_program_ = compile_fallback_shader();
if (!shader_program_) {
return;
}
glUseProgram(shader_program_);
image_texture_location_ = glGetUniformLocation(shader_program_, "image_texture");
if (image_texture_location_ < 0) {
LOG(ERROR) << "Shader doesn't contain the 'image_texture' uniform.";
destroy_shader();
return;
}
fullscreen_location_ = glGetUniformLocation(shader_program_, "fullscreen");
if (fullscreen_location_ < 0) {
LOG(ERROR) << "Shader doesn't contain the 'fullscreen' uniform.";
destroy_shader();
return;
}
}
void BlenderFallbackDisplayShader::destroy_shader()
{
glDeleteProgram(shader_program_);
shader_program_ = 0;
}
/* --------------------------------------------------------------------
* BlenderDisplaySpaceShader.
*/
BlenderDisplaySpaceShader::BlenderDisplaySpaceShader(BL::RenderEngine &b_engine,
BL::Scene &b_scene)
: b_engine_(b_engine), b_scene_(b_scene)
{
DCHECK(b_engine_.support_display_space_shader(b_scene_));
}
void BlenderDisplaySpaceShader::bind(int /*width*/, int /*height*/)
{
b_engine_.bind_display_space_shader(b_scene_);
}
void BlenderDisplaySpaceShader::unbind()
{
b_engine_.unbind_display_space_shader();
}
uint BlenderDisplaySpaceShader::get_shader_program()
{
if (!shader_program_) {
glGetIntegerv(GL_CURRENT_PROGRAM, reinterpret_cast<int *>(&shader_program_));
}
if (!shader_program_) {
LOG(ERROR) << "Error retrieving shader program for display space shader.";
}
return shader_program_;
}
/* --------------------------------------------------------------------
* BlenderDisplayDriver.
*/
BlenderDisplayDriver::BlenderDisplayDriver(BL::RenderEngine &b_engine, BL::Scene &b_scene)
: b_engine_(b_engine), display_shader_(BlenderDisplayShader::create(b_engine, b_scene))
{
/* Create context while on the main thread. */
gl_context_create();
}
BlenderDisplayDriver::~BlenderDisplayDriver()
{
gl_resources_destroy();
}
/* --------------------------------------------------------------------
* Update procedure.
*/
bool BlenderDisplayDriver::update_begin(const Params &params,
int texture_width,
int texture_height)
{
/* Note that it's the responsibility of BlenderDisplayDriver to ensure updating and drawing
* the texture does not happen at the same time. This is achieved indirectly.
*
* When enabling the OpenGL context, it uses an internal mutex lock DST.gl_context_lock.
* This same lock is also held when do_draw() is called, which together ensure mutual
* exclusion.
*
* This locking is not performed on the Cycles side, because that would cause lock inversion. */
if (!gl_context_enable()) {
return false;
}
if (gl_render_sync_) {
glWaitSync((GLsync)gl_render_sync_, 0, GL_TIMEOUT_IGNORED);
}
if (!gl_texture_resources_ensure()) {
gl_context_disable();
return false;
}
/* Update texture dimensions if needed. */
if (texture_.width != texture_width || texture_.height != texture_height) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture_.gl_id);
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA16F, texture_width, texture_height, 0, GL_RGBA, GL_HALF_FLOAT, 0);
texture_.width = texture_width;
texture_.height = texture_height;
glBindTexture(GL_TEXTURE_2D, 0);
/* Texture did change, and no pixel storage was provided. Tag for an explicit zeroing out to
* avoid undefined content. */
texture_.need_clear = true;
}
/* Update PBO dimensions if needed.
*
* NOTE: Allocate the PBO for the the size which will fit the final render resolution (as in,
* at a resolution divider 1. This was we don't need to recreate graphics interoperability
* objects which are costly and which are tied to the specific underlying buffer size.
* The downside of this approach is that when graphics interoperability is not used we are
* sending too much data to GPU when resolution divider is not 1. */
/* TODO(sergey): Investigate whether keeping the PBO exact size of the texture makes non-interop
* mode faster. */
const int buffer_width = params.full_size.x;
const int buffer_height = params.full_size.y;
if (texture_.buffer_width != buffer_width || texture_.buffer_height != buffer_height) {
const size_t size_in_bytes = sizeof(half4) * buffer_width * buffer_height;
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture_.gl_pbo_id);
glBufferData(GL_PIXEL_UNPACK_BUFFER, size_in_bytes, 0, GL_DYNAMIC_DRAW);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
texture_.buffer_width = buffer_width;
texture_.buffer_height = buffer_height;
}
/* New content will be provided to the texture in one way or another, so mark this in a
* centralized place. */
texture_.need_update = true;
return true;
}
void BlenderDisplayDriver::update_end()
{
gl_upload_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
glFlush();
gl_context_disable();
}
/* --------------------------------------------------------------------
* Texture buffer mapping.
*/
half4 *BlenderDisplayDriver::map_texture_buffer()
{
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture_.gl_pbo_id);
half4 *mapped_rgba_pixels = reinterpret_cast<half4 *>(
glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY));
if (!mapped_rgba_pixels) {
LOG(ERROR) << "Error mapping BlenderDisplayDriver pixel buffer object.";
}
if (texture_.need_clear) {
const int64_t texture_width = texture_.width;
const int64_t texture_height = texture_.height;
memset(reinterpret_cast<void *>(mapped_rgba_pixels),
0,
texture_width * texture_height * sizeof(half4));
texture_.need_clear = false;
}
return mapped_rgba_pixels;
}
void BlenderDisplayDriver::unmap_texture_buffer()
{
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
}
/* --------------------------------------------------------------------
* Graphics interoperability.
*/
BlenderDisplayDriver::GraphicsInterop BlenderDisplayDriver::graphics_interop_get()
{
GraphicsInterop interop_dst;
interop_dst.buffer_width = texture_.buffer_width;
interop_dst.buffer_height = texture_.buffer_height;
interop_dst.opengl_pbo_id = texture_.gl_pbo_id;
interop_dst.need_clear = texture_.need_clear;
texture_.need_clear = false;
return interop_dst;
}
void BlenderDisplayDriver::graphics_interop_activate()
{
gl_context_enable();
}
void BlenderDisplayDriver::graphics_interop_deactivate()
{
gl_context_disable();
}
/* --------------------------------------------------------------------
* Drawing.
*/
void BlenderDisplayDriver::clear()
{
texture_.need_clear = true;
}
void BlenderDisplayDriver::set_zoom(float zoom_x, float zoom_y)
{
zoom_ = make_float2(zoom_x, zoom_y);
}
void BlenderDisplayDriver::draw(const Params &params)
{
/* See do_update_begin() for why no locking is required here. */
const bool transparent = true; // TODO(sergey): Derive this from Film.
if (!gl_draw_resources_ensure()) {
return;
}
if (use_gl_context_) {
gl_context_mutex_.lock();
}
if (texture_.need_clear) {
/* Texture is requested to be cleared and was not yet cleared.
*
* Do early return which should be equivalent of drawing all-zero texture.
* Watch out for the lock though so that the clear happening during update is properly
* synchronized here. */
gl_context_mutex_.unlock();
return;
}
if (gl_upload_sync_) {
glWaitSync((GLsync)gl_upload_sync_, 0, GL_TIMEOUT_IGNORED);
}
if (transparent) {
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
display_shader_->bind(params.full_size.x, params.full_size.y);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture_.gl_id);
/* Trick to keep sharp rendering without jagged edges on all GPUs.
*
* The idea here is to enforce driver to use linear interpolation when the image is not zoomed
* in.
* For the render result with a resolution divider in effect we always use nearest interpolation.
*
* Use explicit MIN assignment to make sure the driver does not have an undefined behavior at
* the zoom level 1. The MAG filter is always NEAREST. */
const float zoomed_width = params.size.x * zoom_.x;
const float zoomed_height = params.size.y * zoom_.y;
if (texture_.width != params.size.x || texture_.height != params.size.y) {
/* Resolution divider is different from 1, force nearest interpolation. */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
else if (zoomed_width - params.size.x > 0.5f || zoomed_height - params.size.y > 0.5f) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
texture_update_if_needed();
vertex_buffer_update(params);
/* TODO(sergey): Does it make sense/possible to cache/reuse the VAO? */
GLuint vertex_array_object;
glGenVertexArrays(1, &vertex_array_object);
glBindVertexArray(vertex_array_object);
const int texcoord_attribute = display_shader_->get_tex_coord_attrib_location();
const int position_attribute = display_shader_->get_position_attrib_location();
glEnableVertexAttribArray(texcoord_attribute);
glEnableVertexAttribArray(position_attribute);
glVertexAttribPointer(
texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)0);
glVertexAttribPointer(position_attribute,
2,
GL_FLOAT,
GL_FALSE,
4 * sizeof(float),
(const GLvoid *)(sizeof(float) * 2));
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glDeleteVertexArrays(1, &vertex_array_object);
display_shader_->unbind();
if (transparent) {
glDisable(GL_BLEND);
}
gl_render_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
glFlush();
if (use_gl_context_) {
gl_context_mutex_.unlock();
}
}
void BlenderDisplayDriver::gl_context_create()
{
/* When rendering in viewport there is no render context available via engine.
* Check whether own context is to be created here.
*
* NOTE: If the `b_engine_`'s context is not available, we are expected to be on a main thread
* here. */
use_gl_context_ = !RE_engine_has_render_context(
reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
if (use_gl_context_) {
const bool drw_state = DRW_opengl_context_release();
gl_context_ = WM_opengl_context_create();
if (gl_context_) {
/* On Windows an old context is restored after creation, and subsequent release of context
* generates a Win32 error. Harmless for users, but annoying to have possible misleading
* error prints in the console. */
#ifndef _WIN32
WM_opengl_context_release(gl_context_);
#endif
}
else {
LOG(ERROR) << "Error creating OpenGL context.";
}
DRW_opengl_context_activate(drw_state);
}
}
bool BlenderDisplayDriver::gl_context_enable()
{
if (use_gl_context_) {
if (!gl_context_) {
return false;
}
gl_context_mutex_.lock();
WM_opengl_context_activate(gl_context_);
return true;
}
RE_engine_render_context_enable(reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
return true;
}
void BlenderDisplayDriver::gl_context_disable()
{
if (use_gl_context_) {
if (gl_context_) {
WM_opengl_context_release(gl_context_);
gl_context_mutex_.unlock();
}
return;
}
RE_engine_render_context_disable(reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
}
void BlenderDisplayDriver::gl_context_dispose()
{
if (gl_context_) {
const bool drw_state = DRW_opengl_context_release();
WM_opengl_context_activate(gl_context_);
WM_opengl_context_dispose(gl_context_);
DRW_opengl_context_activate(drw_state);
}
}
bool BlenderDisplayDriver::gl_draw_resources_ensure()
{
if (!texture_.gl_id) {
/* If there is no texture allocated, there is nothing to draw. Inform the draw call that it can
* can not continue. Note that this is not an unrecoverable error, so once the texture is known
* we will come back here and create all the GPU resources needed for draw. */
return false;
}
if (gl_draw_resource_creation_attempted_) {
return gl_draw_resources_created_;
}
gl_draw_resource_creation_attempted_ = true;
if (!vertex_buffer_) {
glGenBuffers(1, &vertex_buffer_);
if (!vertex_buffer_) {
LOG(ERROR) << "Error creating vertex buffer.";
return false;
}
}
gl_draw_resources_created_ = true;
return true;
}
void BlenderDisplayDriver::gl_resources_destroy()
{
gl_context_enable();
if (vertex_buffer_ != 0) {
glDeleteBuffers(1, &vertex_buffer_);
}
if (texture_.gl_pbo_id) {
glDeleteBuffers(1, &texture_.gl_pbo_id);
texture_.gl_pbo_id = 0;
}
if (texture_.gl_id) {
glDeleteTextures(1, &texture_.gl_id);
texture_.gl_id = 0;
}
gl_context_disable();
gl_context_dispose();
}
bool BlenderDisplayDriver::gl_texture_resources_ensure()
{
if (texture_.creation_attempted) {
return texture_.is_created;
}
texture_.creation_attempted = true;
DCHECK(!texture_.gl_id);
DCHECK(!texture_.gl_pbo_id);
/* Create texture. */
glGenTextures(1, &texture_.gl_id);
if (!texture_.gl_id) {
LOG(ERROR) << "Error creating texture.";
return false;
}
/* Configure the texture. */
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture_.gl_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
/* Create PBO for the texture. */
glGenBuffers(1, &texture_.gl_pbo_id);
if (!texture_.gl_pbo_id) {
LOG(ERROR) << "Error creating texture pixel buffer object.";
return false;
}
/* Creation finished with a success. */
texture_.is_created = true;
return true;
}
void BlenderDisplayDriver::texture_update_if_needed()
{
if (!texture_.need_update) {
return;
}
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture_.gl_pbo_id);
glTexSubImage2D(
GL_TEXTURE_2D, 0, 0, 0, texture_.width, texture_.height, GL_RGBA, GL_HALF_FLOAT, 0);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
texture_.need_update = false;
}
void BlenderDisplayDriver::vertex_buffer_update(const Params &params)
{
/* Invalidate old contents - avoids stalling if the buffer is still waiting in queue to be
* rendered. */
glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STREAM_DRAW);
float *vpointer = reinterpret_cast<float *>(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
if (!vpointer) {
return;
}
vpointer[0] = 0.0f;
vpointer[1] = 0.0f;
vpointer[2] = params.full_offset.x;
vpointer[3] = params.full_offset.y;
vpointer[4] = 1.0f;
vpointer[5] = 0.0f;
vpointer[6] = (float)params.size.x + params.full_offset.x;
vpointer[7] = params.full_offset.y;
vpointer[8] = 1.0f;
vpointer[9] = 1.0f;
vpointer[10] = (float)params.size.x + params.full_offset.x;
vpointer[11] = (float)params.size.y + params.full_offset.y;
vpointer[12] = 0.0f;
vpointer[13] = 1.0f;
vpointer[14] = params.full_offset.x;
vpointer[15] = (float)params.size.y + params.full_offset.y;
glUnmapBuffer(GL_ARRAY_BUFFER);
}
CCL_NAMESPACE_END

View File

@@ -0,0 +1,210 @@
/*
* Copyright 2021 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <atomic>
#include "MEM_guardedalloc.h"
#include "RNA_blender_cpp.h"
#include "render/display_driver.h"
#include "util/util_thread.h"
#include "util/util_unique_ptr.h"
CCL_NAMESPACE_BEGIN
/* Base class of shader used for display driver rendering. */
class BlenderDisplayShader {
public:
static constexpr const char *position_attribute_name = "pos";
static constexpr const char *tex_coord_attribute_name = "texCoord";
/* Create shader implementation suitable for the given render engine and scene configuration. */
static unique_ptr<BlenderDisplayShader> create(BL::RenderEngine &b_engine, BL::Scene &b_scene);
BlenderDisplayShader() = default;
virtual ~BlenderDisplayShader() = default;
virtual void bind(int width, int height) = 0;
virtual void unbind() = 0;
/* Get attribute location for position and texture coordinate respectively.
* NOTE: The shader needs to be bound to have access to those. */
virtual int get_position_attrib_location();
virtual int get_tex_coord_attrib_location();
protected:
/* Get program of this display shader.
* NOTE: The shader needs to be bound to have access to this. */
virtual uint get_shader_program() = 0;
/* Cached values of various OpenGL resources. */
int position_attribute_location_ = -1;
int tex_coord_attribute_location_ = -1;
};
/* Implementation of display rendering shader used in the case when render engine does not support
* display space shader. */
class BlenderFallbackDisplayShader : public BlenderDisplayShader {
public:
virtual void bind(int width, int height) override;
virtual void unbind() override;
protected:
virtual uint get_shader_program() override;
void create_shader_if_needed();
void destroy_shader();
uint shader_program_ = 0;
int image_texture_location_ = -1;
int fullscreen_location_ = -1;
/* Shader compilation attempted. Which means, that if the shader program is 0 then compilation or
* linking has failed. Do not attempt to re-compile the shader. */
bool shader_compile_attempted_ = false;
};
class BlenderDisplaySpaceShader : public BlenderDisplayShader {
public:
BlenderDisplaySpaceShader(BL::RenderEngine &b_engine, BL::Scene &b_scene);
virtual void bind(int width, int height) override;
virtual void unbind() override;
protected:
virtual uint get_shader_program() override;
BL::RenderEngine b_engine_;
BL::Scene &b_scene_;
/* Cached values of various OpenGL resources. */
uint shader_program_ = 0;
};
/* Display driver implementation which is specific for Blender viewport integration. */
class BlenderDisplayDriver : public DisplayDriver {
public:
BlenderDisplayDriver(BL::RenderEngine &b_engine, BL::Scene &b_scene);
~BlenderDisplayDriver();
virtual void graphics_interop_activate() override;
virtual void graphics_interop_deactivate() override;
virtual void clear() override;
void set_zoom(float zoom_x, float zoom_y);
protected:
virtual bool update_begin(const Params &params, int texture_width, int texture_height) override;
virtual void update_end() override;
virtual half4 *map_texture_buffer() override;
virtual void unmap_texture_buffer() override;
virtual GraphicsInterop graphics_interop_get() override;
virtual void draw(const Params &params) override;
/* Helper function which allocates new GPU context. */
void gl_context_create();
bool gl_context_enable();
void gl_context_disable();
void gl_context_dispose();
/* Make sure texture is allocated and its initial configuration is performed. */
bool gl_texture_resources_ensure();
/* Ensure all runtime GPU resources needed for drawing are allocated.
* Returns true if all resources needed for drawing are available. */
bool gl_draw_resources_ensure();
/* Destroy all GPU resources which are being used by this object. */
void gl_resources_destroy();
/* Update GPU texture dimensions and content if needed (new pixel data was provided).
*
* NOTE: The texture needs to be bound. */
void texture_update_if_needed();
/* Update vertex buffer with new coordinates of vertex positions and texture coordinates.
* This buffer is used to render texture in the viewport.
*
* NOTE: The buffer needs to be bound. */
void vertex_buffer_update(const Params &params);
BL::RenderEngine b_engine_;
/* OpenGL context which is used the render engine doesn't have its own. */
void *gl_context_ = nullptr;
/* The when Blender RenderEngine side context is not available and the DisplayDriver is to create
* its own context. */
bool use_gl_context_ = false;
/* Mutex used to guard the `gl_context_`. */
thread_mutex gl_context_mutex_;
/* Texture which contains pixels of the render result. */
struct {
/* Indicates whether texture creation was attempted and succeeded.
* Used to avoid multiple attempts of texture creation on GPU issues or GPU context
* misconfiguration. */
bool creation_attempted = false;
bool is_created = false;
/* OpenGL resource IDs of the texture itself and Pixel Buffer Object (PBO) used to write
* pixels to it.
*
* NOTE: Allocated on the engine's context. */
uint gl_id = 0;
uint gl_pbo_id = 0;
/* Is true when new data was written to the PBO, meaning, the texture might need to be resized
* and new data is to be uploaded to the GPU. */
bool need_update = false;
/* Content of the texture is to be filled with zeroes. */
std::atomic<bool> need_clear = true;
/* Dimensions of the texture in pixels. */
int width = 0;
int height = 0;
/* Dimensions of the underlying PBO. */
int buffer_width = 0;
int buffer_height = 0;
} texture_;
unique_ptr<BlenderDisplayShader> display_shader_;
/* Special track of whether GPU resources were attempted to be created, to avoid attempts of
* their re-creation on failure on every redraw. */
bool gl_draw_resource_creation_attempted_ = false;
bool gl_draw_resources_created_ = false;
/* Vertex buffer which hold vertices of a triangle fan which is textures with the texture
* holding the render result. */
uint vertex_buffer_ = 0;
void *gl_render_sync_ = nullptr;
void *gl_upload_sync_ = nullptr;
float2 zoom_ = make_float2(1.0f, 1.0f);
};
CCL_NAMESPACE_END

View File

@@ -29,13 +29,15 @@
CCL_NAMESPACE_BEGIN
static Geometry::Type determine_geom_type(BL::Object &b_ob, bool use_particle_hair)
static Geometry::Type determine_geom_type(BObjectInfo &b_ob_info, bool use_particle_hair)
{
if (b_ob.type() == BL::Object::type_HAIR || use_particle_hair) {
if (b_ob_info.object_data.is_a(&RNA_Hair) || use_particle_hair) {
return Geometry::HAIR;
}
if (b_ob.type() == BL::Object::type_VOLUME || object_fluid_gas_domain_find(b_ob)) {
if (b_ob_info.object_data.is_a(&RNA_Volume) ||
(b_ob_info.object_data == b_ob_info.real_object.data() &&
object_fluid_gas_domain_find(b_ob_info.real_object))) {
return Geometry::VOLUME;
}
@@ -71,20 +73,21 @@ array<Node *> BlenderSync::find_used_shaders(BL::Object &b_ob)
}
Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
BL::Object &b_ob,
BL::Object &b_ob_instance,
BObjectInfo &b_ob_info,
bool object_updated,
bool use_particle_hair,
TaskPool *task_pool)
{
/* Test if we can instance or if the object is modified. */
BL::ID b_ob_data = b_ob.data();
BL::ID b_key_id = (BKE_object_is_modified(b_ob)) ? b_ob_instance : b_ob_data;
Geometry::Type geom_type = determine_geom_type(b_ob, use_particle_hair);
Geometry::Type geom_type = determine_geom_type(b_ob_info, use_particle_hair);
BL::ID b_key_id = (b_ob_info.is_real_object_data() &&
BKE_object_is_modified(b_ob_info.real_object)) ?
b_ob_info.real_object :
b_ob_info.object_data;
GeometryKey key(b_key_id.ptr.data, geom_type);
/* Find shader indices. */
array<Node *> used_shaders = find_used_shaders(b_ob);
array<Node *> used_shaders = find_used_shaders(b_ob_info.iter_object);
/* Ensure we only sync instanced geometry once. */
Geometry *geom = geometry_map.find(key);
@@ -144,7 +147,7 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
geometry_synced.insert(geom);
geom->name = ustring(b_ob_data.name().c_str());
geom->name = ustring(b_ob_info.object_data.name().c_str());
/* Store the shaders immediately for the object attribute code. */
geom->set_used_shaders(used_shaders);
@@ -153,19 +156,19 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
if (progress.get_cancel())
return;
progress.set_sync_status("Synchronizing object", b_ob.name());
progress.set_sync_status("Synchronizing object", b_ob_info.real_object.name());
if (geom_type == Geometry::HAIR) {
Hair *hair = static_cast<Hair *>(geom);
sync_hair(b_depsgraph, b_ob, hair);
sync_hair(b_depsgraph, b_ob_info, hair);
}
else if (geom_type == Geometry::VOLUME) {
Volume *volume = static_cast<Volume *>(geom);
sync_volume(b_ob, volume);
sync_volume(b_ob_info, volume);
}
else {
Mesh *mesh = static_cast<Mesh *>(geom);
sync_mesh(b_depsgraph, b_ob, mesh);
sync_mesh(b_depsgraph, b_ob_info, mesh);
}
};
@@ -181,7 +184,7 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
}
void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph,
BL::Object &b_ob,
BObjectInfo &b_ob_info,
Object *object,
float motion_time,
bool use_particle_hair,
@@ -190,8 +193,10 @@ void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph,
/* Ensure we only sync instanced geometry once. */
Geometry *geom = object->get_geometry();
if (geometry_motion_synced.find(geom) != geometry_motion_synced.end())
if (geometry_motion_synced.find(geom) != geometry_motion_synced.end() ||
geometry_motion_attribute_synced.find(geom) != geometry_motion_attribute_synced.end()) {
return;
}
geometry_motion_synced.insert(geom);
@@ -210,16 +215,17 @@ void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph,
if (progress.get_cancel())
return;
if (b_ob.type() == BL::Object::type_HAIR || use_particle_hair) {
if (b_ob_info.object_data.is_a(&RNA_Hair) || use_particle_hair) {
Hair *hair = static_cast<Hair *>(geom);
sync_hair_motion(b_depsgraph, b_ob, hair, motion_step);
sync_hair_motion(b_depsgraph, b_ob_info, hair, motion_step);
}
else if (b_ob.type() == BL::Object::type_VOLUME || object_fluid_gas_domain_find(b_ob)) {
else if (b_ob_info.object_data.is_a(&RNA_Volume) ||
object_fluid_gas_domain_find(b_ob_info.real_object)) {
/* No volume motion blur support yet. */
}
else {
Mesh *mesh = static_cast<Mesh *>(geom);
sync_mesh_motion(b_depsgraph, b_ob, mesh, motion_step);
sync_mesh_motion(b_depsgraph, b_ob_info, mesh, motion_step);
}
};

View File

@@ -27,15 +27,14 @@ CCL_NAMESPACE_BEGIN
void BlenderSync::sync_light(BL::Object &b_parent,
int persistent_id[OBJECT_PERSISTENT_ID_SIZE],
BL::Object &b_ob,
BL::Object &b_ob_instance,
BObjectInfo &b_ob_info,
int random_id,
Transform &tfm,
bool *use_portal)
{
/* test if we need to sync */
ObjectKey key(b_parent, persistent_id, b_ob_instance, false);
BL::Light b_light(b_ob.data());
ObjectKey key(b_parent, persistent_id, b_ob_info.real_object, false);
BL::Light b_light(b_ob_info.object_data);
Light *light = light_map.find(key);
@@ -44,7 +43,7 @@ void BlenderSync::sync_light(BL::Object &b_parent,
const bool tfm_updated = (light && light->get_tfm() != tfm);
/* Update if either object or light data changed. */
if (!light_map.add_or_update(&light, b_ob, b_parent, key) && !tfm_updated) {
if (!light_map.add_or_update(&light, b_ob_info.real_object, b_parent, key) && !tfm_updated) {
Shader *shader;
if (!shader_map.add_or_update(&shader, b_light)) {
if (light->get_is_portal())
@@ -126,24 +125,17 @@ void BlenderSync::sync_light(BL::Object &b_parent,
light->set_shader(static_cast<Shader *>(used_shaders[0]));
/* shadow */
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
PointerRNA clight = RNA_pointer_get(&b_light.ptr, "cycles");
light->set_cast_shadow(get_boolean(clight, "cast_shadow"));
light->set_use_mis(get_boolean(clight, "use_multiple_importance_sampling"));
int samples = get_int(clight, "samples");
if (get_boolean(cscene, "use_square_samples"))
light->set_samples(samples * samples);
else
light->set_samples(samples);
light->set_max_bounces(get_int(clight, "max_bounces"));
if (b_ob != b_ob_instance) {
if (b_ob_info.real_object != b_ob_info.iter_object) {
light->set_random_id(random_id);
}
else {
light->set_random_id(hash_uint2(hash_string(b_ob.name().c_str()), 0));
light->set_random_id(hash_uint2(hash_string(b_ob_info.real_object.name().c_str()), 0));
}
if (light->get_light_type() == LIGHT_AREA)
@@ -155,11 +147,13 @@ void BlenderSync::sync_light(BL::Object &b_parent,
*use_portal = true;
/* visibility */
uint visibility = object_ray_visibility(b_ob);
uint visibility = object_ray_visibility(b_ob_info.real_object);
light->set_use_camera((visibility & PATH_RAY_CAMERA) != 0);
light->set_use_diffuse((visibility & PATH_RAY_DIFFUSE) != 0);
light->set_use_glossy((visibility & PATH_RAY_GLOSSY) != 0);
light->set_use_transmission((visibility & PATH_RAY_TRANSMIT) != 0);
light->set_use_scatter((visibility & PATH_RAY_VOLUME_SCATTER) != 0);
light->set_is_shadow_catcher(b_ob_info.real_object.is_shadow_catcher());
/* tag */
light->tag_update(scene);
@@ -170,7 +164,6 @@ void BlenderSync::sync_background_light(BL::SpaceView3D &b_v3d, bool use_portal)
BL::World b_world = b_scene.world();
if (b_world) {
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
enum SamplingMethod { SAMPLING_NONE = 0, SAMPLING_AUTOMATIC, SAMPLING_MANUAL, SAMPLING_NUM };
@@ -198,12 +191,6 @@ void BlenderSync::sync_background_light(BL::SpaceView3D &b_v3d, bool use_portal)
/* force enable light again when world is resynced */
light->set_is_enabled(true);
int samples = get_int(cworld, "samples");
if (get_boolean(cscene, "use_square_samples"))
light->set_samples(samples * samples);
else
light->set_samples(samples);
light->tag_update(scene);
light_map.set_recalc(b_world);
}
@@ -212,7 +199,7 @@ void BlenderSync::sync_background_light(BL::SpaceView3D &b_v3d, bool use_portal)
world_map = b_world.ptr.data;
world_recalc = false;
viewport_parameters = BlenderViewportParameters(b_v3d);
viewport_parameters = BlenderViewportParameters(b_v3d, use_developer_ui);
}
CCL_NAMESPACE_END

View File

@@ -347,16 +347,57 @@ static void fill_generic_attribute(BL::Mesh &b_mesh,
}
}
static void attr_create_generic(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivision)
static void attr_create_motion(Mesh *mesh, BL::Attribute &b_attribute, const float motion_scale)
{
if (!(b_attribute.domain() == BL::Attribute::domain_POINT) &&
(b_attribute.data_type() == BL::Attribute::data_type_FLOAT_VECTOR)) {
return;
}
BL::FloatVectorAttribute b_vector_attribute(b_attribute);
const int numverts = mesh->get_verts().size();
/* Find or add attribute */
float3 *P = &mesh->get_verts()[0];
Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
if (!attr_mP) {
attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
}
/* Only export previous and next frame, we don't have any in between data. */
float motion_times[2] = {-1.0f, 1.0f};
for (int step = 0; step < 2; step++) {
const float relative_time = motion_times[step] * 0.5f * motion_scale;
float3 *mP = attr_mP->data_float3() + step * numverts;
for (int i = 0; i < numverts; i++) {
mP[i] = P[i] + get_float3(b_vector_attribute.data[i].vector()) * relative_time;
}
}
}
static void attr_create_generic(Scene *scene,
Mesh *mesh,
BL::Mesh &b_mesh,
const bool subdivision,
const bool need_motion,
const float motion_scale)
{
if (subdivision) {
/* TODO: Handle subdivision correctly. */
return;
}
AttributeSet &attributes = mesh->attributes;
static const ustring u_velocity("velocity");
for (BL::Attribute &b_attribute : b_mesh.attributes) {
const ustring name{b_attribute.name().c_str()};
if (need_motion && name == u_velocity) {
attr_create_motion(mesh, b_attribute, motion_scale);
}
if (!mesh->need_attribute(scene, name)) {
continue;
}
@@ -859,8 +900,10 @@ static void create_mesh(Scene *scene,
Mesh *mesh,
BL::Mesh &b_mesh,
const array<Node *> &used_shaders,
bool subdivision = false,
bool subdivide_uvs = true)
const bool need_motion,
const float motion_scale,
const bool subdivision = false,
const bool subdivide_uvs = true)
{
/* count vertices and faces */
int numverts = b_mesh.vertices.length();
@@ -974,7 +1017,7 @@ static void create_mesh(Scene *scene,
attr_create_vertex_color(scene, mesh, b_mesh, subdivision);
attr_create_sculpt_vertex_color(scene, mesh, b_mesh, subdivision);
attr_create_random_per_island(scene, mesh, b_mesh, subdivision);
attr_create_generic(scene, mesh, b_mesh, subdivision);
attr_create_generic(scene, mesh, b_mesh, subdivision, need_motion, motion_scale);
if (subdivision) {
attr_create_subd_uv_map(scene, mesh, b_mesh, subdivide_uvs);
@@ -999,16 +1042,20 @@ static void create_mesh(Scene *scene,
static void create_subd_mesh(Scene *scene,
Mesh *mesh,
BL::Object &b_ob,
BObjectInfo &b_ob_info,
BL::Mesh &b_mesh,
const array<Node *> &used_shaders,
const bool need_motion,
const float motion_scale,
float dicing_rate,
int max_subdivisions)
{
BL::Object b_ob = b_ob_info.real_object;
BL::SubsurfModifier subsurf_mod(b_ob.modifiers[b_ob.modifiers.length() - 1]);
bool subdivide_uvs = subsurf_mod.uv_smooth() != BL::SubsurfModifier::uv_smooth_NONE;
create_mesh(scene, mesh, b_mesh, used_shaders, true, subdivide_uvs);
create_mesh(scene, mesh, b_mesh, used_shaders, need_motion, motion_scale, true, subdivide_uvs);
/* export creases */
size_t num_creases = 0;
@@ -1043,7 +1090,7 @@ static void create_subd_mesh(Scene *scene,
*
* NOTE: This code is run prior to object motion blur initialization. so can not access properties
* set by `sync_object_motion_init()`. */
static bool mesh_need_motion_attribute(BL::Object &b_ob, Scene *scene)
static bool mesh_need_motion_attribute(BObjectInfo &b_ob_info, Scene *scene)
{
const Scene::MotionType need_motion = scene->need_motion();
if (need_motion == Scene::MOTION_NONE) {
@@ -1060,7 +1107,7 @@ static bool mesh_need_motion_attribute(BL::Object &b_ob, Scene *scene)
* - Motion attribute expects non-zero time steps.
*
* Avoid adding motion attributes if the motion blur will enforce 0 motion steps. */
PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
PointerRNA cobject = RNA_pointer_get(&b_ob_info.real_object.ptr, "cycles");
const bool use_motion = get_boolean(cobject, "use_motion_blur");
if (!use_motion) {
return false;
@@ -1072,92 +1119,7 @@ static bool mesh_need_motion_attribute(BL::Object &b_ob, Scene *scene)
return true;
}
static void sync_mesh_cached_velocities(BL::Object &b_ob, Scene *scene, Mesh *mesh)
{
if (!mesh_need_motion_attribute(b_ob, scene)) {
return;
}
BL::MeshSequenceCacheModifier b_mesh_cache = object_mesh_cache_find(b_ob, true);
if (!b_mesh_cache) {
return;
}
if (!MeshSequenceCacheModifier_read_velocity_get(&b_mesh_cache.ptr)) {
return;
}
const size_t numverts = mesh->get_verts().size();
if (b_mesh_cache.vertex_velocities.length() != numverts) {
return;
}
/* Find or add attribute */
float3 *P = &mesh->get_verts()[0];
Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
if (!attr_mP) {
attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
}
/* Only export previous and next frame, we don't have any in between data. */
float motion_times[2] = {-1.0f, 1.0f};
for (int step = 0; step < 2; step++) {
const float relative_time = motion_times[step] * scene->motion_shutter_time() * 0.5f;
float3 *mP = attr_mP->data_float3() + step * numverts;
BL::MeshSequenceCacheModifier::vertex_velocities_iterator vvi;
int i = 0;
for (b_mesh_cache.vertex_velocities.begin(vvi); vvi != b_mesh_cache.vertex_velocities.end();
++vvi, ++i) {
mP[i] = P[i] + get_float3(vvi->velocity()) * relative_time;
}
}
}
static void sync_mesh_fluid_motion(BL::Object &b_ob, Scene *scene, Mesh *mesh)
{
if (!mesh_need_motion_attribute(b_ob, scene)) {
return;
}
BL::FluidDomainSettings b_fluid_domain = object_fluid_liquid_domain_find(b_ob);
if (!b_fluid_domain)
return;
/* If the mesh has modifiers following the fluid domain we can't export motion. */
if (b_fluid_domain.mesh_vertices.length() != mesh->get_verts().size())
return;
/* Find or add attribute */
float3 *P = &mesh->get_verts()[0];
Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
if (!attr_mP) {
attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
}
/* Only export previous and next frame, we don't have any in between data. */
float motion_times[2] = {-1.0f, 1.0f};
for (int step = 0; step < 2; step++) {
float relative_time = motion_times[step] * scene->motion_shutter_time() * 0.5f;
float3 *mP = attr_mP->data_float3() + step * mesh->get_verts().size();
BL::FluidDomainSettings::mesh_vertices_iterator svi;
int i = 0;
for (b_fluid_domain.mesh_vertices.begin(svi); svi != b_fluid_domain.mesh_vertices.end();
++svi, ++i) {
mP[i] = P[i] + get_float3(svi->velocity()) * relative_time;
}
}
}
void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh)
void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, Mesh *mesh)
{
/* make a copy of the shaders as the caller in the main thread still need them for syncing the
* attributes */
@@ -1170,37 +1132,47 @@ void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *me
/* Adaptive subdivision setup. Not for baking since that requires
* exact mapping to the Blender mesh. */
if (!scene->bake_manager->get_baking()) {
new_mesh.set_subdivision_type(object_subdivision_type(b_ob, preview, experimental));
new_mesh.set_subdivision_type(
object_subdivision_type(b_ob_info.real_object, preview, experimental));
}
/* For some reason, meshes do not need this... */
bool need_undeformed = new_mesh.need_attribute(scene, ATTR_STD_GENERATED);
BL::Mesh b_mesh = object_to_mesh(
b_data, b_ob, b_depsgraph, need_undeformed, new_mesh.get_subdivision_type());
b_data, b_ob_info, b_depsgraph, need_undeformed, new_mesh.get_subdivision_type());
if (b_mesh) {
/* Motion blur attribute is relative to seconds, we need it relative to frames. */
const bool need_motion = mesh_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;
/* Sync mesh itself. */
if (new_mesh.get_subdivision_type() != Mesh::SUBDIVISION_NONE)
create_subd_mesh(scene,
&new_mesh,
b_ob,
b_ob_info,
b_mesh,
new_mesh.get_used_shaders(),
need_motion,
motion_scale,
dicing_rate,
max_subdivisions);
else
create_mesh(scene, &new_mesh, b_mesh, new_mesh.get_used_shaders(), false);
create_mesh(scene,
&new_mesh,
b_mesh,
new_mesh.get_used_shaders(),
need_motion,
motion_scale,
false);
free_object_to_mesh(b_data, b_ob, b_mesh);
free_object_to_mesh(b_data, b_ob_info, b_mesh);
}
}
/* cached velocities (e.g. from alembic archive) */
sync_mesh_cached_velocities(b_ob, scene, &new_mesh);
/* mesh fluid motion mantaflow */
sync_mesh_fluid_motion(b_ob, scene, &new_mesh);
/* update original sockets */
mesh->clear_non_sockets();
@@ -1230,22 +1202,10 @@ void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *me
}
void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
BL::Object b_ob,
BObjectInfo &b_ob_info,
Mesh *mesh,
int motion_step)
{
/* Fluid motion blur already exported. */
BL::FluidDomainSettings b_fluid_domain = object_fluid_liquid_domain_find(b_ob);
if (b_fluid_domain) {
return;
}
/* Cached motion blur already exported. */
BL::MeshSequenceCacheModifier mesh_cache = object_mesh_cache_find(b_ob, true);
if (mesh_cache) {
return;
}
/* Skip if no vertices were exported. */
size_t numverts = mesh->get_verts().size();
if (numverts == 0) {
@@ -1255,11 +1215,13 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
/* Skip objects without deforming modifiers. this is not totally reliable,
* would need a more extensive check to see which objects are animated. */
BL::Mesh b_mesh(PointerRNA_NULL);
if (ccl::BKE_object_is_deform_modified(b_ob, b_scene, preview)) {
if (ccl::BKE_object_is_deform_modified(b_ob_info, b_scene, preview)) {
/* get derived mesh */
b_mesh = object_to_mesh(b_data, b_ob, b_depsgraph, false, Mesh::SUBDIVISION_NONE);
b_mesh = object_to_mesh(b_data, b_ob_info, b_depsgraph, false, Mesh::SUBDIVISION_NONE);
}
const std::string ob_name = b_ob_info.real_object.name();
/* TODO(sergey): Perform preliminary check for number of vertices. */
if (b_mesh) {
/* Export deformed coordinates. */
@@ -1295,17 +1257,17 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
memcmp(mP, &mesh->get_verts()[0], sizeof(float3) * numverts) == 0) {
/* no motion, remove attributes again */
if (b_mesh.vertices.length() != numverts) {
VLOG(1) << "Topology differs, disabling motion blur for object " << b_ob.name();
VLOG(1) << "Topology differs, disabling motion blur for object " << ob_name;
}
else {
VLOG(1) << "No actual deformation motion for object " << b_ob.name();
VLOG(1) << "No actual deformation motion for object " << ob_name;
}
mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
if (attr_mN)
mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_NORMAL);
}
else if (motion_step > 0) {
VLOG(1) << "Filling deformation motion for object " << b_ob.name();
VLOG(1) << "Filling deformation motion for object " << ob_name;
/* motion, fill up previous steps that we might have skipped because
* they had no motion, but we need them anyway now */
float3 *P = &mesh->get_verts()[0];
@@ -1319,8 +1281,8 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
}
else {
if (b_mesh.vertices.length() != numverts) {
VLOG(1) << "Topology differs, discarding motion blur for object " << b_ob.name()
<< " at time " << motion_step;
VLOG(1) << "Topology differs, discarding motion blur for object " << ob_name << " at time "
<< motion_step;
memcpy(mP, &mesh->get_verts()[0], sizeof(float3) * numverts);
if (mN != NULL) {
memcpy(mN, attr_N->data_float3(), sizeof(float3) * numverts);
@@ -1328,7 +1290,7 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
}
}
free_object_to_mesh(b_data, b_ob, b_mesh);
free_object_to_mesh(b_data, b_ob_info, b_mesh);
return;
}

View File

@@ -154,7 +154,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
const bool is_instance = b_instance.is_instance();
BL::Object b_ob = b_instance.object();
BL::Object b_parent = is_instance ? b_instance.parent() : b_instance.object();
BL::Object b_ob_instance = is_instance ? b_instance.instance_object() : b_ob;
BObjectInfo b_ob_info{b_ob, is_instance ? b_instance.instance_object() : b_ob, b_ob.data()};
const bool motion = motion_time != 0.0f;
/*const*/ Transform tfm = get_transform(b_ob.matrix_world());
int *persistent_id = NULL;
@@ -178,8 +178,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
{
sync_light(b_parent,
persistent_id,
b_ob,
b_ob_instance,
b_ob_info,
is_instance ? b_instance.random_id() : 0,
tfm,
use_portal);
@@ -231,7 +230,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
TaskPool *object_geom_task_pool = (is_instance) ? NULL : geom_task_pool;
/* key to lookup object */
ObjectKey key(b_parent, persistent_id, b_ob_instance, use_particle_hair);
ObjectKey key(b_parent, persistent_id, b_ob_info.real_object, use_particle_hair);
Object *object;
/* motion vector case */
@@ -249,12 +248,8 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
/* mesh deformation */
if (object->get_geometry())
sync_geometry_motion(b_depsgraph,
b_ob_instance,
object,
motion_time,
use_particle_hair,
object_geom_task_pool);
sync_geometry_motion(
b_depsgraph, b_ob_info, object, motion_time, use_particle_hair, object_geom_task_pool);
}
return object;
@@ -265,15 +260,8 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
(tfm != object->get_tfm());
/* mesh sync */
/* b_ob is owned by the iterator and will go out of scope at the end of the block.
* b_ob_instance is the original object and will remain valid for deferred geometry
* sync. */
Geometry *geometry = sync_geometry(b_depsgraph,
b_ob_instance,
b_ob_instance,
object_updated,
use_particle_hair,
object_geom_task_pool);
Geometry *geometry = sync_geometry(
b_depsgraph, b_ob_info, object_updated, use_particle_hair, object_geom_task_pool);
object->set_geometry(geometry);
/* special case not tracked by object update flags */
@@ -376,7 +364,7 @@ static bool lookup_property(BL::ID b_id, const string &name, float4 *r_value)
if (type == PROP_FLOAT)
value = RNA_property_float_get(&ptr, prop);
else if (type == PROP_INT)
value = RNA_property_int_get(&ptr, prop);
value = static_cast<float>(RNA_property_int_get(&ptr, prop));
else
return false;
@@ -485,7 +473,9 @@ bool BlenderSync::sync_object_attributes(BL::DepsgraphObjectInstance &b_instance
/* Object Loop */
void BlenderSync::sync_procedural(BL::Object &b_ob, BL::MeshSequenceCacheModifier &b_mesh_cache)
void BlenderSync::sync_procedural(BL::Object &b_ob,
BL::MeshSequenceCacheModifier &b_mesh_cache,
bool has_subdivision_modifier)
{
#ifdef WITH_ALEMBIC
BL::CacheFile cache_file = b_mesh_cache.cache_file();
@@ -502,14 +492,14 @@ void BlenderSync::sync_procedural(BL::Object &b_ob, BL::MeshSequenceCacheModifie
procedural_map.used(procedural);
}
float current_frame = b_scene.frame_current();
float current_frame = static_cast<float>(b_scene.frame_current());
if (cache_file.override_frame()) {
current_frame = cache_file.frame();
}
if (!cache_file.override_frame()) {
procedural->set_start_frame(b_scene.frame_start());
procedural->set_end_frame(b_scene.frame_end());
procedural->set_start_frame(static_cast<float>(b_scene.frame_start()));
procedural->set_end_frame(static_cast<float>(b_scene.frame_end()));
}
procedural->set_frame(current_frame);
@@ -521,6 +511,9 @@ void BlenderSync::sync_procedural(BL::Object &b_ob, BL::MeshSequenceCacheModifie
procedural->set_scale(cache_file.scale());
procedural->set_use_prefetch(cache_file.use_prefetch());
procedural->set_prefetch_cache_size(cache_file.prefetch_cache_size());
/* create or update existing AlembicObjects */
ustring object_path = ustring(b_mesh_cache.object_path());
@@ -534,12 +527,15 @@ void BlenderSync::sync_procedural(BL::Object &b_ob, BL::MeshSequenceCacheModifie
abc_object->set_subd_dicing_rate(subd_dicing_rate);
abc_object->set_subd_max_level(max_subdivisions);
abc_object->set_ignore_subdivision(!has_subdivision_modifier);
if (abc_object->is_modified() || procedural->is_modified()) {
procedural->tag_update(scene);
}
#else
(void)b_ob;
(void)b_mesh_cache;
(void)has_subdivision_modifier;
#endif
}
@@ -572,7 +568,7 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph,
/* object loop */
bool cancel = false;
bool use_portal = false;
const bool show_lights = BlenderViewportParameters(b_v3d).use_scene_lights;
const bool show_lights = BlenderViewportParameters(b_v3d, use_developer_ui).use_scene_lights;
BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
BL::Depsgraph::object_instances_iterator b_instance_iter;
@@ -601,13 +597,14 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph,
if (b_instance.show_self()) {
#ifdef WITH_ALEMBIC
bool use_procedural = false;
bool has_subdivision_modifier = false;
BL::MeshSequenceCacheModifier b_mesh_cache(PointerRNA_NULL);
/* Experimental as Blender does not have good support for procedurals at the moment, also
* only available in preview renders since currently do not have a good cache policy, the
* data being loaded at once for all the frames. */
if (experimental && b_v3d) {
b_mesh_cache = object_mesh_cache_find(b_ob, false);
b_mesh_cache = object_mesh_cache_find(b_ob, &has_subdivision_modifier);
use_procedural = b_mesh_cache && b_mesh_cache.cache_file().use_render_procedural();
}
@@ -615,7 +612,7 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph,
/* Skip in the motion case, as generating motion blur data will be handled in the
* procedural. */
if (!motion) {
sync_procedural(b_ob, b_mesh_cache);
sync_procedural(b_ob, b_mesh_cache, has_subdivision_modifier);
}
}
else
@@ -722,6 +719,14 @@ void BlenderSync::sync_motion(BL::RenderSettings &b_render,
}
}
/* Check which geometry already has motion blur so it can be skipped. */
geometry_motion_attribute_synced.clear();
for (Geometry *geom : scene->geometry) {
if (geom->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) {
geometry_motion_attribute_synced.insert(geom);
}
}
/* note iteration over motion_times set happens in sorted order */
foreach (float relative_time, motion_times) {
/* center time is already handled. */
@@ -752,6 +757,8 @@ void BlenderSync::sync_motion(BL::RenderSettings &b_render,
sync_objects(b_depsgraph, b_v3d, relative_time);
}
geometry_motion_attribute_synced.clear();
/* we need to set the python thread state again because this
* function assumes it is being executed from python and will
* try to save the thread state */

View File

@@ -0,0 +1,127 @@
/*
* Copyright 2021 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "blender/blender_output_driver.h"
CCL_NAMESPACE_BEGIN
BlenderOutputDriver::BlenderOutputDriver(BL::RenderEngine &b_engine) : b_engine_(b_engine)
{
}
BlenderOutputDriver::~BlenderOutputDriver()
{
}
bool BlenderOutputDriver::read_render_tile(const Tile &tile)
{
/* Get render result. */
BL::RenderResult b_rr = b_engine_.begin_result(tile.offset.x,
tile.offset.y,
tile.size.x,
tile.size.y,
tile.layer.c_str(),
tile.view.c_str());
/* Can happen if the intersected rectangle gives 0 width or height. */
if (b_rr.ptr.data == NULL) {
return false;
}
BL::RenderResult::layers_iterator b_single_rlay;
b_rr.layers.begin(b_single_rlay);
/* layer will be missing if it was disabled in the UI */
if (b_single_rlay == b_rr.layers.end()) {
return false;
}
BL::RenderLayer b_rlay = *b_single_rlay;
vector<float> pixels(tile.size.x * tile.size.y * 4);
/* Copy each pass.
* TODO:copy only the required ones for better performance? */
for (BL::RenderPass &b_pass : b_rlay.passes) {
tile.set_pass_pixels(b_pass.name(), b_pass.channels(), (float *)b_pass.rect());
}
b_engine_.end_result(b_rr, false, false, false);
return true;
}
bool BlenderOutputDriver::update_render_tile(const Tile &tile)
{
/* Use final write for preview renders, otherwise render result wouldn't be be updated
* quickly on Blender side. For all other cases we use the display driver. */
if (b_engine_.is_preview()) {
write_render_tile(tile);
return true;
}
else {
/* Don't highlight full-frame tile. */
if (!(tile.size == tile.full_size)) {
b_engine_.tile_highlight_clear_all();
b_engine_.tile_highlight_set(tile.offset.x, tile.offset.y, tile.size.x, tile.size.y, true);
}
return false;
}
}
void BlenderOutputDriver::write_render_tile(const Tile &tile)
{
b_engine_.tile_highlight_clear_all();
/* Get render result. */
BL::RenderResult b_rr = b_engine_.begin_result(tile.offset.x,
tile.offset.y,
tile.size.x,
tile.size.y,
tile.layer.c_str(),
tile.view.c_str());
/* Can happen if the intersected rectangle gives 0 width or height. */
if (b_rr.ptr.data == NULL) {
return;
}
BL::RenderResult::layers_iterator b_single_rlay;
b_rr.layers.begin(b_single_rlay);
/* Layer will be missing if it was disabled in the UI. */
if (b_single_rlay == b_rr.layers.end()) {
return;
}
BL::RenderLayer b_rlay = *b_single_rlay;
vector<float> pixels(tile.size.x * tile.size.y * 4);
/* Copy each pass. */
for (BL::RenderPass &b_pass : b_rlay.passes) {
if (!tile.get_pass_pixels(b_pass.name(), b_pass.channels(), &pixels[0])) {
memset(&pixels[0], 0, pixels.size() * sizeof(float));
}
b_pass.rect(&pixels[0]);
}
b_engine_.end_result(b_rr, true, false, true);
}
CCL_NAMESPACE_END

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2019 Blender Foundation
* Copyright 2021 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,17 +14,27 @@
* limitations under the License.
*/
#pragma once
#include "MEM_guardedalloc.h"
#include "RNA_blender_cpp.h"
#include "render/output_driver.h"
CCL_NAMESPACE_BEGIN
ccl_device void kernel_adaptive_filter_x(KernelGlobals *kg)
{
int pixel_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
if (pixel_index < kernel_split_params.tile.h &&
kernel_split_params.tile.start_sample + kernel_split_params.tile.num_samples >=
kernel_data.integrator.adaptive_min_samples) {
int y = kernel_split_params.tile.y + pixel_index;
kernel_do_adaptive_filter_x(kg, y, &kernel_split_params.tile);
}
}
class BlenderOutputDriver : public OutputDriver {
public:
BlenderOutputDriver(BL::RenderEngine &b_engine);
~BlenderOutputDriver();
virtual void write_render_tile(const Tile &tile) override;
virtual bool update_render_tile(const Tile &tile) override;
virtual bool read_render_tile(const Tile &tile) override;
protected:
BL::RenderEngine b_engine_;
};
CCL_NAMESPACE_END

View File

@@ -45,10 +45,6 @@
# include <OSL/oslquery.h>
#endif
#ifdef WITH_OPENCL
# include "device/device_intern.h"
#endif
CCL_NAMESPACE_BEGIN
namespace {
@@ -72,12 +68,10 @@ PyObject *pyunicode_from_string(const char *str)
/* Synchronize debug flags from a given Blender scene.
* Return truth when device list needs invalidation.
*/
bool debug_flags_sync_from_scene(BL::Scene b_scene)
static void debug_flags_sync_from_scene(BL::Scene b_scene)
{
DebugFlagsRef flags = DebugFlags();
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
/* Backup some settings for comparison. */
DebugFlags::OpenCL::DeviceType opencl_device_type = flags.opencl.device_type;
/* Synchronize shared flags. */
flags.viewport_static_bvh = get_enum(cscene, "debug_bvh_type");
/* Synchronize CPU flags. */
@@ -87,50 +81,19 @@ bool debug_flags_sync_from_scene(BL::Scene b_scene)
flags.cpu.sse3 = get_boolean(cscene, "debug_use_cpu_sse3");
flags.cpu.sse2 = get_boolean(cscene, "debug_use_cpu_sse2");
flags.cpu.bvh_layout = (BVHLayout)get_enum(cscene, "debug_bvh_layout");
flags.cpu.split_kernel = get_boolean(cscene, "debug_use_cpu_split_kernel");
/* Synchronize CUDA flags. */
flags.cuda.adaptive_compile = get_boolean(cscene, "debug_use_cuda_adaptive_compile");
flags.cuda.split_kernel = get_boolean(cscene, "debug_use_cuda_split_kernel");
/* Synchronize OptiX flags. */
flags.optix.cuda_streams = get_int(cscene, "debug_optix_cuda_streams");
flags.optix.curves_api = get_boolean(cscene, "debug_optix_curves_api");
/* Synchronize OpenCL device type. */
switch (get_enum(cscene, "debug_opencl_device_type")) {
case 0:
flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_NONE;
break;
case 1:
flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_ALL;
break;
case 2:
flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_DEFAULT;
break;
case 3:
flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_CPU;
break;
case 4:
flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_GPU;
break;
case 5:
flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_ACCELERATOR;
break;
}
/* Synchronize other OpenCL flags. */
flags.opencl.debug = get_boolean(cscene, "debug_use_opencl_debug");
flags.opencl.mem_limit = ((size_t)get_int(cscene, "debug_opencl_mem_limit")) * 1024 * 1024;
return flags.opencl.device_type != opencl_device_type;
flags.optix.use_debug = get_boolean(cscene, "debug_use_optix_debug");
}
/* Reset debug flags to default values.
* Return truth when device list needs invalidation.
*/
bool debug_flags_reset()
static void debug_flags_reset()
{
DebugFlagsRef flags = DebugFlags();
/* Backup some settings for comparison. */
DebugFlags::OpenCL::DeviceType opencl_device_type = flags.opencl.device_type;
flags.reset();
return flags.opencl.device_type != opencl_device_type;
}
} /* namespace */
@@ -175,18 +138,20 @@ static const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
static PyObject *init_func(PyObject * /*self*/, PyObject *args)
{
PyObject *path, *user_path;
PyObject *path, *user_path, *temp_path;
int headless;
if (!PyArg_ParseTuple(args, "OOi", &path, &user_path, &headless)) {
return NULL;
if (!PyArg_ParseTuple(args, "OOOi", &path, &user_path, &temp_path, &headless)) {
return nullptr;
}
PyObject *path_coerce = NULL, *user_path_coerce = NULL;
PyObject *path_coerce = nullptr, *user_path_coerce = nullptr, *temp_path_coerce = nullptr;
path_init(PyC_UnicodeAsByte(path, &path_coerce),
PyC_UnicodeAsByte(user_path, &user_path_coerce));
PyC_UnicodeAsByte(user_path, &user_path_coerce),
PyC_UnicodeAsByte(temp_path, &temp_path_coerce));
Py_XDECREF(path_coerce);
Py_XDECREF(user_path_coerce);
Py_XDECREF(temp_path_coerce);
BlenderSession::headless = headless;
@@ -299,6 +264,50 @@ static PyObject *render_func(PyObject * /*self*/, PyObject *args)
Py_RETURN_NONE;
}
static PyObject *render_frame_finish_func(PyObject * /*self*/, PyObject *args)
{
PyObject *pysession;
if (!PyArg_ParseTuple(args, "O", &pysession)) {
return nullptr;
}
BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(pysession);
/* Allow Blender to execute other Python scripts. */
python_thread_state_save(&session->python_thread_state);
session->render_frame_finish();
python_thread_state_restore(&session->python_thread_state);
Py_RETURN_NONE;
}
static PyObject *draw_func(PyObject * /*self*/, PyObject *args)
{
PyObject *py_session, *py_graph, *py_screen, *py_space_image;
if (!PyArg_ParseTuple(args, "OOOO", &py_session, &py_graph, &py_screen, &py_space_image)) {
return nullptr;
}
BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(py_session);
ID *b_screen = (ID *)PyLong_AsVoidPtr(py_screen);
PointerRNA b_space_image_ptr;
RNA_pointer_create(b_screen,
&RNA_SpaceImageEditor,
pylong_as_voidptr_typesafe(py_space_image),
&b_space_image_ptr);
BL::SpaceImageEditor b_space_image(b_space_image_ptr);
session->draw(b_space_image);
Py_RETURN_NONE;
}
/* pixel_array and result passed as pointers */
static PyObject *bake_func(PyObject * /*self*/, PyObject *args)
{
@@ -336,7 +345,7 @@ static PyObject *bake_func(PyObject * /*self*/, PyObject *args)
Py_RETURN_NONE;
}
static PyObject *draw_func(PyObject * /*self*/, PyObject *args)
static PyObject *view_draw_func(PyObject * /*self*/, PyObject *args)
{
PyObject *pysession, *pygraph, *pyv3d, *pyrv3d;
@@ -350,7 +359,7 @@ static PyObject *draw_func(PyObject * /*self*/, PyObject *args)
int viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
session->draw(viewport[2], viewport[3]);
session->view_draw(viewport[2], viewport[3]);
}
Py_RETURN_NONE;
@@ -697,40 +706,6 @@ static PyObject *system_info_func(PyObject * /*self*/, PyObject * /*value*/)
return pyunicode_from_string(system_info.c_str());
}
#ifdef WITH_OPENCL
static PyObject *opencl_disable_func(PyObject * /*self*/, PyObject * /*value*/)
{
VLOG(2) << "Disabling OpenCL platform.";
DebugFlags().opencl.device_type = DebugFlags::OpenCL::DEVICE_NONE;
Py_RETURN_NONE;
}
static PyObject *opencl_compile_func(PyObject * /*self*/, PyObject *args)
{
PyObject *sequence = PySequence_Fast(args, "Arguments must be a sequence");
if (sequence == NULL) {
Py_RETURN_FALSE;
}
vector<string> parameters;
for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(sequence); i++) {
PyObject *item = PySequence_Fast_GET_ITEM(sequence, i);
PyObject *item_as_string = PyObject_Str(item);
const char *parameter_string = PyUnicode_AsUTF8(item_as_string);
parameters.push_back(parameter_string);
Py_DECREF(item_as_string);
}
Py_DECREF(sequence);
if (device_opencl_compile_kernel(parameters)) {
Py_RETURN_TRUE;
}
else {
Py_RETURN_FALSE;
}
}
#endif
static bool image_parse_filepaths(PyObject *pyfilepaths, vector<string> &filepaths)
{
if (PyUnicode_Check(pyfilepaths)) {
@@ -762,6 +737,10 @@ static bool image_parse_filepaths(PyObject *pyfilepaths, vector<string> &filepat
static PyObject *denoise_func(PyObject * /*self*/, PyObject *args, PyObject *keywords)
{
#if 1
(void)args;
(void)keywords;
#else
static const char *keyword_list[] = {
"preferences", "scene", "view_layer", "input", "output", "tile_size", "samples", NULL};
PyObject *pypreferences, *pyscene, *pyviewlayer;
@@ -835,7 +814,7 @@ static PyObject *denoise_func(PyObject * /*self*/, PyObject *args, PyObject *key
}
/* Create denoiser. */
Denoiser denoiser(device);
DenoiserPipeline denoiser(device);
denoiser.params = params;
denoiser.input = input;
denoiser.output = output;
@@ -852,6 +831,7 @@ static PyObject *denoise_func(PyObject * /*self*/, PyObject *args, PyObject *key
PyErr_SetString(PyExc_ValueError, denoiser.error.c_str());
return NULL;
}
#endif
Py_RETURN_NONE;
}
@@ -903,10 +883,7 @@ static PyObject *debug_flags_update_func(PyObject * /*self*/, PyObject *args)
RNA_id_pointer_create((ID *)PyLong_AsVoidPtr(pyscene), &sceneptr);
BL::Scene b_scene(sceneptr);
if (debug_flags_sync_from_scene(b_scene)) {
VLOG(2) << "Tagging device list for update.";
Device::tag_update();
}
debug_flags_sync_from_scene(b_scene);
VLOG(2) << "Debug flags set to:\n" << DebugFlags();
@@ -917,10 +894,7 @@ static PyObject *debug_flags_update_func(PyObject * /*self*/, PyObject *args)
static PyObject *debug_flags_reset_func(PyObject * /*self*/, PyObject * /*args*/)
{
if (debug_flags_reset()) {
VLOG(2) << "Tagging device list for update.";
Device::tag_update();
}
debug_flags_reset();
if (debug_flags_set) {
VLOG(2) << "Debug flags reset to:\n" << DebugFlags();
debug_flags_set = false;
@@ -928,84 +902,6 @@ static PyObject *debug_flags_reset_func(PyObject * /*self*/, PyObject * /*args*/
Py_RETURN_NONE;
}
static PyObject *set_resumable_chunk_func(PyObject * /*self*/, PyObject *args)
{
int num_resumable_chunks, current_resumable_chunk;
if (!PyArg_ParseTuple(args, "ii", &num_resumable_chunks, &current_resumable_chunk)) {
Py_RETURN_NONE;
}
if (num_resumable_chunks <= 0) {
fprintf(stderr, "Cycles: Bad value for number of resumable chunks.\n");
abort();
Py_RETURN_NONE;
}
if (current_resumable_chunk < 1 || current_resumable_chunk > num_resumable_chunks) {
fprintf(stderr, "Cycles: Bad value for current resumable chunk number.\n");
abort();
Py_RETURN_NONE;
}
VLOG(1) << "Initialized resumable render: "
<< "num_resumable_chunks=" << num_resumable_chunks << ", "
<< "current_resumable_chunk=" << current_resumable_chunk;
BlenderSession::num_resumable_chunks = num_resumable_chunks;
BlenderSession::current_resumable_chunk = current_resumable_chunk;
printf("Cycles: Will render chunk %d of %d\n", current_resumable_chunk, num_resumable_chunks);
Py_RETURN_NONE;
}
static PyObject *set_resumable_chunk_range_func(PyObject * /*self*/, PyObject *args)
{
int num_chunks, start_chunk, end_chunk;
if (!PyArg_ParseTuple(args, "iii", &num_chunks, &start_chunk, &end_chunk)) {
Py_RETURN_NONE;
}
if (num_chunks <= 0) {
fprintf(stderr, "Cycles: Bad value for number of resumable chunks.\n");
abort();
Py_RETURN_NONE;
}
if (start_chunk < 1 || start_chunk > num_chunks) {
fprintf(stderr, "Cycles: Bad value for start chunk number.\n");
abort();
Py_RETURN_NONE;
}
if (end_chunk < 1 || end_chunk > num_chunks) {
fprintf(stderr, "Cycles: Bad value for start chunk number.\n");
abort();
Py_RETURN_NONE;
}
if (start_chunk > end_chunk) {
fprintf(stderr, "Cycles: End chunk should be higher than start one.\n");
abort();
Py_RETURN_NONE;
}
VLOG(1) << "Initialized resumable render: "
<< "num_resumable_chunks=" << num_chunks << ", "
<< "start_resumable_chunk=" << start_chunk << "end_resumable_chunk=" << end_chunk;
BlenderSession::num_resumable_chunks = num_chunks;
BlenderSession::start_resumable_chunk = start_chunk;
BlenderSession::end_resumable_chunk = end_chunk;
printf("Cycles: Will render chunks %d to %d of %d\n", start_chunk, end_chunk, num_chunks);
Py_RETURN_NONE;
}
static PyObject *clear_resumable_chunk_func(PyObject * /*self*/, PyObject * /*value*/)
{
VLOG(1) << "Clear resumable render";
BlenderSession::num_resumable_chunks = 0;
BlenderSession::current_resumable_chunk = 0;
Py_RETURN_NONE;
}
static PyObject *enable_print_stats_func(PyObject * /*self*/, PyObject * /*args*/)
{
BlenderSession::print_render_stats = true;
@@ -1015,16 +911,16 @@ static PyObject *enable_print_stats_func(PyObject * /*self*/, PyObject * /*args*
static PyObject *get_device_types_func(PyObject * /*self*/, PyObject * /*args*/)
{
vector<DeviceType> device_types = Device::available_types();
bool has_cuda = false, has_optix = false, has_opencl = false;
bool has_cuda = false, has_optix = false, has_hip = false;
foreach (DeviceType device_type, device_types) {
has_cuda |= (device_type == DEVICE_CUDA);
has_optix |= (device_type == DEVICE_OPTIX);
has_opencl |= (device_type == DEVICE_OPENCL);
has_hip |= (device_type == DEVICE_HIP);
}
PyObject *list = PyTuple_New(3);
PyTuple_SET_ITEM(list, 0, PyBool_FromLong(has_cuda));
PyTuple_SET_ITEM(list, 1, PyBool_FromLong(has_optix));
PyTuple_SET_ITEM(list, 2, PyBool_FromLong(has_opencl));
PyTuple_SET_ITEM(list, 2, PyBool_FromLong(has_hip));
return list;
}
@@ -1044,15 +940,15 @@ static PyObject *set_device_override_func(PyObject * /*self*/, PyObject *arg)
if (override == "CPU") {
BlenderSession::device_override = DEVICE_MASK_CPU;
}
else if (override == "OPENCL") {
BlenderSession::device_override = DEVICE_MASK_OPENCL;
}
else if (override == "CUDA") {
BlenderSession::device_override = DEVICE_MASK_CUDA;
}
else if (override == "OPTIX") {
BlenderSession::device_override = DEVICE_MASK_OPTIX;
}
else if (override == "HIP") {
BlenderSession::device_override = DEVICE_MASK_HIP;
}
else {
printf("\nError: %s is not a valid Cycles device.\n", override.c_str());
Py_RETURN_FALSE;
@@ -1072,8 +968,10 @@ static PyMethodDef methods[] = {
{"create", create_func, METH_VARARGS, ""},
{"free", free_func, METH_O, ""},
{"render", render_func, METH_VARARGS, ""},
{"bake", bake_func, METH_VARARGS, ""},
{"render_frame_finish", render_frame_finish_func, METH_VARARGS, ""},
{"draw", draw_func, METH_VARARGS, ""},
{"bake", bake_func, METH_VARARGS, ""},
{"view_draw", view_draw_func, METH_VARARGS, ""},
{"sync", sync_func, METH_VARARGS, ""},
{"reset", reset_func, METH_VARARGS, ""},
#ifdef WITH_OSL
@@ -1082,10 +980,6 @@ static PyMethodDef methods[] = {
#endif
{"available_devices", available_devices_func, METH_VARARGS, ""},
{"system_info", system_info_func, METH_NOARGS, ""},
#ifdef WITH_OPENCL
{"opencl_disable", opencl_disable_func, METH_NOARGS, ""},
{"opencl_compile", opencl_compile_func, METH_VARARGS, ""},
#endif
/* Standalone denoising */
{"denoise", (PyCFunction)denoise_func, METH_VARARGS | METH_KEYWORDS, ""},
@@ -1098,11 +992,6 @@ static PyMethodDef methods[] = {
/* Statistics. */
{"enable_print_stats", enable_print_stats_func, METH_NOARGS, ""},
/* Resumable render */
{"set_resumable_chunk", set_resumable_chunk_func, METH_VARARGS, ""},
{"set_resumable_chunk_range", set_resumable_chunk_range_func, METH_VARARGS, ""},
{"clear_resumable_chunk", clear_resumable_chunk_func, METH_NOARGS, ""},
/* Compute Device selection */
{"get_device_types", get_device_types_func, METH_VARARGS, ""},
{"set_device_override", set_device_override_func, METH_O, ""},
@@ -1153,14 +1042,6 @@ void *CCL_python_module_init()
PyModule_AddStringConstant(mod, "osl_version_string", "unknown");
#endif
#ifdef WITH_NETWORK
PyModule_AddObject(mod, "with_network", Py_True);
Py_INCREF(Py_True);
#else /* WITH_NETWORK */
PyModule_AddObject(mod, "with_network", Py_False);
Py_INCREF(Py_False);
#endif /* WITH_NETWORK */
#ifdef WITH_EMBREE
PyModule_AddObject(mod, "with_embree", Py_True);
Py_INCREF(Py_True);

View File

@@ -38,9 +38,12 @@
#include "util/util_hash.h"
#include "util/util_logging.h"
#include "util/util_murmurhash.h"
#include "util/util_path.h"
#include "util/util_progress.h"
#include "util/util_time.h"
#include "blender/blender_display_driver.h"
#include "blender/blender_output_driver.h"
#include "blender/blender_session.h"
#include "blender/blender_sync.h"
#include "blender/blender_util.h"
@@ -49,10 +52,6 @@ CCL_NAMESPACE_BEGIN
DeviceTypeMask BlenderSession::device_override = DEVICE_MASK_ALL;
bool BlenderSession::headless = false;
int BlenderSession::num_resumable_chunks = 0;
int BlenderSession::current_resumable_chunk = 0;
int BlenderSession::start_resumable_chunk = 0;
int BlenderSession::end_resumable_chunk = 0;
bool BlenderSession::print_render_stats = false;
BlenderSession::BlenderSession(BL::RenderEngine &b_engine,
@@ -73,7 +72,8 @@ BlenderSession::BlenderSession(BL::RenderEngine &b_engine,
width(0),
height(0),
preview_osl(preview_osl),
python_thread_state(NULL)
python_thread_state(NULL),
use_developer_ui(false)
{
/* offline render */
background = true;
@@ -103,7 +103,9 @@ BlenderSession::BlenderSession(BL::RenderEngine &b_engine,
width(width),
height(height),
preview_osl(false),
python_thread_state(NULL)
python_thread_state(NULL),
use_developer_ui(b_userpref.experimental().use_cycles_debug() &&
b_userpref.view().show_developer_ui())
{
/* 3d view render */
background = false;
@@ -119,10 +121,10 @@ BlenderSession::~BlenderSession()
void BlenderSession::create_session()
{
SessionParams session_params = BlenderSync::get_session_params(
const SessionParams session_params = BlenderSync::get_session_params(
b_engine, b_userpref, b_scene, background);
SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
bool session_pause = BlenderSync::get_session_pause(b_scene, background);
const SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
const bool session_pause = BlenderSync::get_session_pause(b_scene, background);
/* reset status/progress */
last_status = "";
@@ -131,20 +133,18 @@ void BlenderSession::create_session()
start_resize_time = 0.0;
/* create session */
session = new Session(session_params);
session->scene = scene;
session = new Session(session_params, scene_params);
session->progress.set_update_callback(function_bind(&BlenderSession::tag_redraw, this));
session->progress.set_cancel_callback(function_bind(&BlenderSession::test_cancel, this));
session->set_pause(session_pause);
/* create scene */
scene = new Scene(scene_params, session->device);
scene = session->scene;
scene->name = b_scene.name();
session->scene = scene;
/* create sync */
sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
sync = new BlenderSync(
b_engine, b_data, b_scene, scene, !background, use_developer_ui, session->progress);
BL::Object b_camera_override(b_engine.camera_override());
if (b_v3d) {
sync->sync_view(b_v3d, b_rv3d, width, height);
@@ -154,13 +154,27 @@ void BlenderSession::create_session()
}
/* set buffer parameters */
BufferParams buffer_params = BlenderSync::get_buffer_params(
b_v3d, b_rv3d, scene->camera, width, height, session_params.denoising.use);
session->reset(buffer_params, session_params.samples);
const BufferParams buffer_params = BlenderSync::get_buffer_params(
b_v3d, b_rv3d, scene->camera, width, height);
session->reset(session_params, buffer_params);
b_engine.use_highlight_tiles(session_params.progressive_refine == false);
/* Create GPU display.
* TODO(sergey): Investigate whether DisplayDriver can be used for the preview as well. */
if (!b_engine.is_preview() && !headless) {
unique_ptr<BlenderDisplayDriver> display_driver = make_unique<BlenderDisplayDriver>(b_engine,
b_scene);
display_driver_ = display_driver.get();
session->set_display_driver(move(display_driver));
}
update_resumable_tile_manager(session_params.samples);
/* Viewport and preview (as in, material preview) does not do tiled rendering, so can inform
* engine that no tracking of the tiles state is needed.
* The offline rendering will make a decision when tile is being written. The penalty of asking
* the engine to keep track of tiles state is minimal, so there is nothing to worry about here
* about possible single-tiled final render. */
if (!b_engine.is_preview() && !b_v3d) {
b_engine.use_highlight_tiles(true);
}
}
void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsgraph)
@@ -202,9 +216,9 @@ void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsg
return;
}
SessionParams session_params = BlenderSync::get_session_params(
const SessionParams session_params = BlenderSync::get_session_params(
b_engine, b_userpref, b_scene, background);
SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
const SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
if (scene->params.modified(scene_params) || session->params.modified(session_params) ||
!this->b_render.use_persistent_data()) {
@@ -220,8 +234,6 @@ void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsg
session->progress.reset();
session->tile_manager.set_tile_order(session_params.tile_order);
/* peak memory usage should show current render peak, not peak for all renders
* made by this render session
*/
@@ -230,7 +242,8 @@ void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsg
if (is_new_session) {
/* Sync object should be re-created for new scene. */
delete sync;
sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
sync = new BlenderSync(
b_engine, b_data, b_scene, scene, !background, use_developer_ui, session->progress);
}
else {
/* Sync recalculations to do just the required updates. */
@@ -242,171 +255,35 @@ void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsg
BL::SpaceView3D b_null_space_view3d(PointerRNA_NULL);
BL::RegionView3D b_null_region_view3d(PointerRNA_NULL);
BufferParams buffer_params = BlenderSync::get_buffer_params(b_null_space_view3d,
b_null_region_view3d,
scene->camera,
width,
height,
session_params.denoising.use);
session->reset(buffer_params, session_params.samples);
b_engine.use_highlight_tiles(session_params.progressive_refine == false);
const BufferParams buffer_params = BlenderSync::get_buffer_params(
b_null_space_view3d, b_null_region_view3d, scene->camera, width, height);
session->reset(session_params, buffer_params);
/* reset time */
start_resize_time = 0.0;
{
thread_scoped_lock lock(draw_state_.mutex);
draw_state_.last_pass_index = -1;
}
}
void BlenderSession::free_session()
{
session->cancel();
if (session) {
session->cancel(true);
}
delete sync;
sync = nullptr;
delete session;
session = nullptr;
}
static ShaderEvalType get_shader_type(const string &pass_type)
void BlenderSession::full_buffer_written(string_view filename)
{
const char *shader_type = pass_type.c_str();
/* data passes */
if (strcmp(shader_type, "NORMAL") == 0)
return SHADER_EVAL_NORMAL;
else if (strcmp(shader_type, "UV") == 0)
return SHADER_EVAL_UV;
else if (strcmp(shader_type, "ROUGHNESS") == 0)
return SHADER_EVAL_ROUGHNESS;
else if (strcmp(shader_type, "DIFFUSE_COLOR") == 0)
return SHADER_EVAL_DIFFUSE_COLOR;
else if (strcmp(shader_type, "GLOSSY_COLOR") == 0)
return SHADER_EVAL_GLOSSY_COLOR;
else if (strcmp(shader_type, "TRANSMISSION_COLOR") == 0)
return SHADER_EVAL_TRANSMISSION_COLOR;
else if (strcmp(shader_type, "EMIT") == 0)
return SHADER_EVAL_EMISSION;
/* light passes */
else if (strcmp(shader_type, "AO") == 0)
return SHADER_EVAL_AO;
else if (strcmp(shader_type, "COMBINED") == 0)
return SHADER_EVAL_COMBINED;
else if (strcmp(shader_type, "SHADOW") == 0)
return SHADER_EVAL_SHADOW;
else if (strcmp(shader_type, "DIFFUSE") == 0)
return SHADER_EVAL_DIFFUSE;
else if (strcmp(shader_type, "GLOSSY") == 0)
return SHADER_EVAL_GLOSSY;
else if (strcmp(shader_type, "TRANSMISSION") == 0)
return SHADER_EVAL_TRANSMISSION;
/* extra */
else if (strcmp(shader_type, "ENVIRONMENT") == 0)
return SHADER_EVAL_ENVIRONMENT;
else
return SHADER_EVAL_BAKE;
}
static BL::RenderResult begin_render_result(BL::RenderEngine &b_engine,
int x,
int y,
int w,
int h,
const char *layername,
const char *viewname)
{
return b_engine.begin_result(x, y, w, h, layername, viewname);
}
static void end_render_result(BL::RenderEngine &b_engine,
BL::RenderResult &b_rr,
bool cancel,
bool highlight,
bool do_merge_results)
{
b_engine.end_result(b_rr, (int)cancel, (int)highlight, (int)do_merge_results);
}
void BlenderSession::do_write_update_render_tile(RenderTile &rtile,
bool do_update_only,
bool do_read_only,
bool highlight)
{
int x = rtile.x - session->tile_manager.params.full_x;
int y = rtile.y - session->tile_manager.params.full_y;
int w = rtile.w;
int h = rtile.h;
/* get render result */
BL::RenderResult b_rr = begin_render_result(
b_engine, x, y, w, h, b_rlay_name.c_str(), b_rview_name.c_str());
/* can happen if the intersected rectangle gives 0 width or height */
if (b_rr.ptr.data == NULL) {
return;
}
BL::RenderResult::layers_iterator b_single_rlay;
b_rr.layers.begin(b_single_rlay);
/* layer will be missing if it was disabled in the UI */
if (b_single_rlay == b_rr.layers.end())
return;
BL::RenderLayer b_rlay = *b_single_rlay;
if (do_read_only) {
/* copy each pass */
for (BL::RenderPass &b_pass : b_rlay.passes) {
/* find matching pass type */
PassType pass_type = BlenderSync::get_pass_type(b_pass);
int components = b_pass.channels();
rtile.buffers->set_pass_rect(
pass_type, components, (float *)b_pass.rect(), rtile.num_samples);
}
end_render_result(b_engine, b_rr, false, false, false);
}
else if (do_update_only) {
/* Sample would be zero at initial tile update, which is only needed
* to tag tile form blender side as IN PROGRESS for proper highlight
* no buffers should be sent to blender yet. For denoise we also
* keep showing the noisy buffers until denoise is done. */
bool merge = (rtile.sample != 0) && (rtile.task != RenderTile::DENOISE);
if (merge) {
update_render_result(b_rlay, rtile);
}
end_render_result(b_engine, b_rr, true, highlight, merge);
}
else {
/* Write final render result. */
write_render_result(b_rlay, rtile);
end_render_result(b_engine, b_rr, false, false, true);
}
}
void BlenderSession::read_render_tile(RenderTile &rtile)
{
do_write_update_render_tile(rtile, false, true, false);
}
void BlenderSession::write_render_tile(RenderTile &rtile)
{
do_write_update_render_tile(rtile, false, false, false);
}
void BlenderSession::update_render_tile(RenderTile &rtile, bool highlight)
{
/* use final write for preview renders, otherwise render result wouldn't be
* be updated in blender side
* would need to be investigated a bit further, but for now shall be fine
*/
if (!b_engine.is_preview())
do_write_update_render_tile(rtile, true, false, highlight);
else
do_write_update_render_tile(rtile, false, false, false);
full_buffer_files_.emplace_back(filename);
}
static void add_cryptomatte_layer(BL::RenderResult &b_rr, string name, string manifest)
@@ -430,12 +307,15 @@ void BlenderSession::stamp_view_layer_metadata(Scene *scene, const string &view_
to_string(session->params.samples).c_str());
/* Store ranged samples information. */
/* TODO(sergey): Need to bring this information back. */
#if 0
if (session->tile_manager.range_num_samples != -1) {
b_rr.stamp_data_add_field((prefix + "range_start_sample").c_str(),
to_string(session->tile_manager.range_start_sample).c_str());
b_rr.stamp_data_add_field((prefix + "range_num_samples").c_str(),
to_string(session->tile_manager.range_num_samples).c_str());
}
#endif
/* Write cryptomatte metadata. */
if (scene->film->get_cryptomatte_passes() & CRYPT_OBJECT) {
@@ -474,39 +354,35 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
return;
}
/* set callback to write out render results */
session->write_render_tile_cb = function_bind(&BlenderSession::write_render_tile, this, _1);
session->update_render_tile_cb = function_bind(
&BlenderSession::update_render_tile, this, _1, _2);
/* Create driver to write out render results. */
session->set_output_driver(make_unique<BlenderOutputDriver>(b_engine));
session->full_buffer_written_cb = [&](string_view filename) { full_buffer_written(filename); };
BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
/* get buffer parameters */
SessionParams session_params = BlenderSync::get_session_params(
b_engine, b_userpref, b_scene, background, b_view_layer);
const SessionParams session_params = BlenderSync::get_session_params(
b_engine, b_userpref, b_scene, background);
BufferParams buffer_params = BlenderSync::get_buffer_params(
b_v3d, b_rv3d, scene->camera, width, height, session_params.denoising.use);
b_v3d, b_rv3d, scene->camera, width, height);
/* temporary render result to find needed passes and views */
BL::RenderResult b_rr = begin_render_result(
b_engine, 0, 0, 1, 1, b_view_layer.name().c_str(), NULL);
BL::RenderResult b_rr = b_engine.begin_result(0, 0, 1, 1, b_view_layer.name().c_str(), NULL);
BL::RenderResult::layers_iterator b_single_rlay;
b_rr.layers.begin(b_single_rlay);
BL::RenderLayer b_rlay = *b_single_rlay;
b_rlay_name = b_view_layer.name();
/* Update denoising parameters. */
session->set_denoising(session_params.denoising);
{
thread_scoped_lock lock(draw_state_.mutex);
b_rlay_name = b_view_layer.name();
/* Signal that the display pass is to be updated. */
draw_state_.last_pass_index = -1;
}
/* Compute render passes and film settings. */
vector<Pass> passes = sync->sync_render_passes(
b_scene, b_rlay, b_view_layer, session_params.adaptive_sampling, session_params.denoising);
/* Set buffer params, using film settings from sync_render_passes. */
buffer_params.passes = passes;
buffer_params.denoising_data_pass = scene->film->get_denoising_data_pass();
buffer_params.denoising_clean_pass = scene->film->get_denoising_clean_pass();
buffer_params.denoising_prefiltered_pass = scene->film->get_denoising_prefiltered_pass();
sync->sync_render_passes(b_rlay, b_view_layer);
BL::RenderResult::views_iterator b_view_iter;
@@ -520,6 +396,9 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
++b_view_iter, ++view_index) {
b_rview_name = b_view_iter->name();
buffer_params.layer = b_view_layer.name();
buffer_params.view = b_rview_name;
/* set the current view */
b_engine.active_view_set(b_rview_name.c_str());
@@ -549,20 +428,16 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
}
/* Update number of samples per layer. */
int samples = sync->get_layer_samples();
bool bound_samples = sync->get_layer_bound_samples();
int effective_layer_samples;
const int samples = sync->get_layer_samples();
const bool bound_samples = sync->get_layer_bound_samples();
if (samples != 0 && (!bound_samples || (samples < session_params.samples)))
effective_layer_samples = samples;
else
effective_layer_samples = session_params.samples;
/* Update tile manager if we're doing resumable render. */
update_resumable_tile_manager(effective_layer_samples);
SessionParams effective_session_params = session_params;
if (samples != 0 && (!bound_samples || (samples < session_params.samples))) {
effective_session_params.samples = samples;
}
/* Update session itself. */
session->reset(buffer_params, effective_layer_samples);
session->reset(effective_session_params, buffer_params);
/* render */
if (!b_engine.is_preview() && background && print_render_stats) {
@@ -586,65 +461,155 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
stamp_view_layer_metadata(scene, b_rlay_name);
/* free result without merging */
end_render_result(b_engine, b_rr, true, true, false);
b_engine.end_result(b_rr, true, false, false);
/* When tiled rendering is used there will be no "write" done for the tile. Forcefully clear
* highlighted tiles now, so that the highlight will be removed while processing full frame from
* file. */
b_engine.tile_highlight_clear_all();
double total_time, render_time;
session->progress.get_time(total_time, render_time);
VLOG(1) << "Total render time: " << total_time;
VLOG(1) << "Render time (without synchronization): " << render_time;
/* clear callback */
session->write_render_tile_cb = function_null;
session->update_render_tile_cb = function_null;
}
static int bake_pass_filter_get(const int pass_filter)
void BlenderSession::render_frame_finish()
{
int flag = BAKE_FILTER_NONE;
/* Processing of all layers and views is done. Clear the strings so that we can communicate
* progress about reading files and denoising them. */
b_rlay_name = "";
b_rview_name = "";
if ((pass_filter & BL::BakeSettings::pass_filter_DIRECT) != 0)
flag |= BAKE_FILTER_DIRECT;
if ((pass_filter & BL::BakeSettings::pass_filter_INDIRECT) != 0)
flag |= BAKE_FILTER_INDIRECT;
if ((pass_filter & BL::BakeSettings::pass_filter_COLOR) != 0)
flag |= BAKE_FILTER_COLOR;
if (!b_render.use_persistent_data()) {
/* Free the sync object so that it can properly dereference nodes from the scene graph before
* the graph is freed. */
delete sync;
sync = nullptr;
if ((pass_filter & BL::BakeSettings::pass_filter_DIFFUSE) != 0)
flag |= BAKE_FILTER_DIFFUSE;
if ((pass_filter & BL::BakeSettings::pass_filter_GLOSSY) != 0)
flag |= BAKE_FILTER_GLOSSY;
if ((pass_filter & BL::BakeSettings::pass_filter_TRANSMISSION) != 0)
flag |= BAKE_FILTER_TRANSMISSION;
session->device_free();
}
if ((pass_filter & BL::BakeSettings::pass_filter_EMIT) != 0)
flag |= BAKE_FILTER_EMISSION;
if ((pass_filter & BL::BakeSettings::pass_filter_AO) != 0)
flag |= BAKE_FILTER_AO;
for (string_view filename : full_buffer_files_) {
session->process_full_buffer_from_disk(filename);
if (check_and_report_session_error()) {
break;
}
}
return flag;
for (string_view filename : full_buffer_files_) {
path_remove(filename);
}
/* Clear driver. */
session->set_output_driver(nullptr);
session->full_buffer_written_cb = function_null;
}
static PassType bake_type_to_pass(const string &bake_type_str, const int bake_filter)
{
const char *bake_type = bake_type_str.c_str();
/* data passes */
if (strcmp(bake_type, "POSITION") == 0) {
return PASS_POSITION;
}
else if (strcmp(bake_type, "NORMAL") == 0) {
return PASS_NORMAL;
}
else if (strcmp(bake_type, "UV") == 0) {
return PASS_UV;
}
else if (strcmp(bake_type, "ROUGHNESS") == 0) {
return PASS_ROUGHNESS;
}
else if (strcmp(bake_type, "EMIT") == 0) {
return PASS_EMISSION;
}
/* light passes */
else if (strcmp(bake_type, "AO") == 0) {
return PASS_AO;
}
else if (strcmp(bake_type, "COMBINED") == 0) {
return PASS_COMBINED;
}
else if (strcmp(bake_type, "SHADOW") == 0) {
return PASS_SHADOW;
}
else if (strcmp(bake_type, "DIFFUSE") == 0) {
if ((bake_filter & BL::BakeSettings::pass_filter_DIRECT) &&
bake_filter & BL::BakeSettings::pass_filter_INDIRECT) {
return PASS_DIFFUSE;
}
else if (bake_filter & BL::BakeSettings::pass_filter_DIRECT) {
return PASS_DIFFUSE_DIRECT;
}
else if (bake_filter & BL::BakeSettings::pass_filter_INDIRECT) {
return PASS_DIFFUSE_INDIRECT;
}
else {
return PASS_DIFFUSE_COLOR;
}
}
else if (strcmp(bake_type, "GLOSSY") == 0) {
if ((bake_filter & BL::BakeSettings::pass_filter_DIRECT) &&
bake_filter & BL::BakeSettings::pass_filter_INDIRECT) {
return PASS_GLOSSY;
}
else if (bake_filter & BL::BakeSettings::pass_filter_DIRECT) {
return PASS_GLOSSY_DIRECT;
}
else if (bake_filter & BL::BakeSettings::pass_filter_INDIRECT) {
return PASS_GLOSSY_INDIRECT;
}
else {
return PASS_GLOSSY_COLOR;
}
}
else if (strcmp(bake_type, "TRANSMISSION") == 0) {
if ((bake_filter & BL::BakeSettings::pass_filter_DIRECT) &&
bake_filter & BL::BakeSettings::pass_filter_INDIRECT) {
return PASS_TRANSMISSION;
}
else if (bake_filter & BL::BakeSettings::pass_filter_DIRECT) {
return PASS_TRANSMISSION_DIRECT;
}
else if (bake_filter & BL::BakeSettings::pass_filter_INDIRECT) {
return PASS_TRANSMISSION_INDIRECT;
}
else {
return PASS_TRANSMISSION_COLOR;
}
}
/* extra */
else if (strcmp(bake_type, "ENVIRONMENT") == 0) {
return PASS_BACKGROUND;
}
return PASS_COMBINED;
}
void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
BL::Object &b_object,
const string &pass_type,
const int pass_filter,
const string &bake_type,
const int bake_filter,
const int bake_width,
const int bake_height)
{
b_depsgraph = b_depsgraph_;
ShaderEvalType shader_type = get_shader_type(pass_type);
int bake_pass_filter = bake_pass_filter_get(pass_filter);
/* Initialize bake manager, before we load the baking kernels. */
scene->bake_manager->set(scene, b_object.name(), shader_type, bake_pass_filter);
scene->bake_manager->set(scene, b_object.name());
/* Passes are identified by name, so in order to return the combined pass we need to set the
* name. */
Pass::add(PASS_COMBINED, scene->passes, "Combined");
/* Add render pass that we want to bake, and name it Combined so that it is
* used as that on the Blender side. */
Pass *pass = scene->create_node<Pass>();
pass->set_name(ustring("Combined"));
pass->set_type(bake_type_to_pass(bake_type, bake_filter));
pass->set_include_albedo((bake_filter & BL::BakeSettings::pass_filter_COLOR));
session->read_bake_tile_cb = function_bind(&BlenderSession::read_render_tile, this, _1);
session->write_render_tile_cb = function_bind(&BlenderSession::write_render_tile, this, _1);
session->set_display_driver(nullptr);
session->set_output_driver(make_unique<BlenderOutputDriver>(b_engine));
if (!session->progress.get_cancel()) {
/* Sync scene. */
@@ -667,18 +632,15 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
if (object_found && !session->progress.get_cancel()) {
/* Get session and buffer parameters. */
SessionParams session_params = BlenderSync::get_session_params(
const SessionParams session_params = BlenderSync::get_session_params(
b_engine, b_userpref, b_scene, background);
session_params.progressive_refine = false;
BufferParams buffer_params;
buffer_params.width = bake_width;
buffer_params.height = bake_height;
buffer_params.passes = scene->passes;
/* Update session. */
session->tile_manager.set_samples(session_params.samples);
session->reset(buffer_params, session_params.samples);
session->reset(session_params, buffer_params);
session->progress.set_update_callback(
function_bind(&BlenderSession::update_bake_progress, this));
@@ -690,71 +652,7 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
session->wait();
}
session->read_bake_tile_cb = function_null;
session->write_render_tile_cb = function_null;
}
void BlenderSession::do_write_update_render_result(BL::RenderLayer &b_rlay,
RenderTile &rtile,
bool do_update_only)
{
RenderBuffers *buffers = rtile.buffers;
/* copy data from device */
if (!buffers->copy_from_device())
return;
float exposure = scene->film->get_exposure();
vector<float> pixels(rtile.w * rtile.h * 4);
/* Adjust absolute sample number to the range. */
int sample = rtile.sample;
const int range_start_sample = session->tile_manager.range_start_sample;
if (range_start_sample != -1) {
sample -= range_start_sample;
}
if (!do_update_only) {
/* copy each pass */
for (BL::RenderPass &b_pass : b_rlay.passes) {
int components = b_pass.channels();
/* Copy pixels from regular render passes. */
bool read = buffers->get_pass_rect(b_pass.name(), exposure, sample, components, &pixels[0]);
/* If denoising pass, */
if (!read) {
int denoising_offset = BlenderSync::get_denoising_pass(b_pass);
if (denoising_offset >= 0) {
read = buffers->get_denoising_pass_rect(
denoising_offset, exposure, sample, components, &pixels[0]);
}
}
if (!read) {
memset(&pixels[0], 0, pixels.size() * sizeof(float));
}
b_pass.rect(&pixels[0]);
}
}
else {
/* copy combined pass */
BL::RenderPass b_combined_pass(b_rlay.passes.find_by_name("Combined", b_rview_name.c_str()));
if (buffers->get_pass_rect("Combined", exposure, sample, 4, &pixels[0]))
b_combined_pass.rect(&pixels[0]);
}
}
void BlenderSession::write_render_result(BL::RenderLayer &b_rlay, RenderTile &rtile)
{
do_write_update_render_result(b_rlay, rtile, false);
}
void BlenderSession::update_render_result(BL::RenderLayer &b_rlay, RenderTile &rtile)
{
do_write_update_render_result(b_rlay, rtile, true);
session->set_output_driver(nullptr);
}
void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_)
@@ -764,19 +662,19 @@ void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_)
return;
/* on session/scene parameter changes, we recreate session entirely */
SessionParams session_params = BlenderSync::get_session_params(
const SessionParams session_params = BlenderSync::get_session_params(
b_engine, b_userpref, b_scene, background);
SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
bool session_pause = BlenderSync::get_session_pause(b_scene, background);
const SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
const bool session_pause = BlenderSync::get_session_pause(b_scene, background);
if (session->params.modified(session_params) || scene->params.modified(scene_params)) {
free_session();
create_session();
}
/* increase samples, but never decrease */
/* increase samples and render time, but never decrease */
session->set_samples(session_params.samples);
session->set_denoising_start_sample(session_params.denoising.start_sample);
session->set_time_limit(session_params.time_limit);
session->set_pause(session_pause);
/* copy recalc flags, outside of mutex so we can decide to do the real
@@ -808,21 +706,12 @@ void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_)
sync->sync_camera(b_render, b_camera_override, width, height, "");
/* get buffer parameters */
BufferParams buffer_params = BlenderSync::get_buffer_params(
b_v3d, b_rv3d, scene->camera, width, height, session_params.denoising.use);
if (!buffer_params.denoising_data_pass) {
session_params.denoising.use = false;
}
session->set_denoising(session_params.denoising);
/* Update film if denoising data was enabled or disabled. */
scene->film->set_denoising_data_pass(buffer_params.denoising_data_pass);
const BufferParams buffer_params = BlenderSync::get_buffer_params(
b_v3d, b_rv3d, scene->camera, width, height);
/* reset if needed */
if (scene->need_reset()) {
session->reset(buffer_params, session_params.samples);
session->reset(session_params, buffer_params);
/* After session reset, so device is not accessing image data anymore. */
builtin_images_load();
@@ -839,7 +728,44 @@ void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_)
session->start();
}
bool BlenderSession::draw(int w, int h)
void BlenderSession::draw(BL::SpaceImageEditor &space_image)
{
if (!session || !session->scene) {
/* Offline render drawing does not force the render engine update, which means it's possible
* that the Session is not created yet. */
return;
}
thread_scoped_lock lock(draw_state_.mutex);
const int pass_index = space_image.image_user().multilayer_pass();
if (pass_index != draw_state_.last_pass_index) {
BL::RenderPass b_display_pass(b_engine.pass_by_index_get(b_rlay_name.c_str(), pass_index));
if (!b_display_pass) {
return;
}
Scene *scene = session->scene;
thread_scoped_lock lock(scene->mutex);
const Pass *pass = Pass::find(scene->passes, b_display_pass.name());
if (!pass) {
return;
}
scene->film->set_display_pass(pass->get_type());
draw_state_.last_pass_index = pass_index;
}
BL::Array<float, 2> zoom = space_image.zoom();
display_driver_->set_zoom(zoom[0], zoom[1]);
session->draw();
}
void BlenderSession::view_draw(int w, int h)
{
/* pause in redraw in case update is not being called due to final render */
session->set_pause(BlenderSync::get_session_pause(b_scene, background));
@@ -885,14 +811,14 @@ bool BlenderSession::draw(int w, int h)
/* reset if requested */
if (reset) {
SessionParams session_params = BlenderSync::get_session_params(
const SessionParams session_params = BlenderSync::get_session_params(
b_engine, b_userpref, b_scene, background);
BufferParams buffer_params = BlenderSync::get_buffer_params(
b_v3d, b_rv3d, scene->camera, width, height, session_params.denoising.use);
bool session_pause = BlenderSync::get_session_pause(b_scene, background);
const BufferParams buffer_params = BlenderSync::get_buffer_params(
b_v3d, b_rv3d, scene->camera, width, height);
const bool session_pause = BlenderSync::get_session_pause(b_scene, background);
if (session_pause == false) {
session->reset(buffer_params, session_params.samples);
session->reset(session_params, buffer_params);
start_resize_time = 0.0;
}
}
@@ -905,18 +831,7 @@ bool BlenderSession::draw(int w, int h)
update_status_progress();
/* draw */
BufferParams buffer_params = BlenderSync::get_buffer_params(
b_v3d, b_rv3d, scene->camera, width, height, session->params.denoising.use);
DeviceDrawParams draw_params;
if (session->params.display_buffer_linear) {
draw_params.bind_display_space_shader_cb = function_bind(
&BL::RenderEngine::bind_display_space_shader, &b_engine, b_scene);
draw_params.unbind_display_space_shader_cb = function_bind(
&BL::RenderEngine::unbind_display_space_shader, &b_engine);
}
return !session->draw(buffer_params, draw_params);
session->draw();
}
void BlenderSession::get_status(string &status, string &substatus)
@@ -924,11 +839,6 @@ void BlenderSession::get_status(string &status, string &substatus)
session->progress.get_status(status, substatus);
}
void BlenderSession::get_kernel_status(string &kernel_status)
{
session->progress.get_kernel_status(kernel_status);
}
void BlenderSession::get_progress(float &progress, double &total_time, double &render_time)
{
session->progress.get_time(total_time, render_time);
@@ -947,7 +857,7 @@ void BlenderSession::update_bake_progress()
void BlenderSession::update_status_progress()
{
string timestatus, status, substatus, kernel_status;
string timestatus, status, substatus;
string scene_status = "";
float progress;
double total_time, remaining_time = 0, render_time;
@@ -955,11 +865,11 @@ void BlenderSession::update_status_progress()
float mem_peak = (float)session->stats.mem_peak / 1024.0f / 1024.0f;
get_status(status, substatus);
get_kernel_status(kernel_status);
get_progress(progress, total_time, render_time);
if (progress > 0)
remaining_time = (1.0 - (double)progress) * (render_time / (double)progress);
if (progress > 0) {
remaining_time = session->get_estimated_remaining_time();
}
if (background) {
if (scene)
@@ -980,14 +890,12 @@ void BlenderSession::update_status_progress()
status = " | " + status;
if (substatus.size() > 0)
status += " | " + substatus;
if (kernel_status.size() > 0)
status += " | " + kernel_status;
}
double current_time = time_dt();
/* When rendering in a window, redraw the status at least once per second to keep the elapsed and
* remaining time up-to-date. For headless rendering, only report when something significant
* changes to keep the console output readable. */
/* When rendering in a window, redraw the status at least once per second to keep the elapsed
* and remaining time up-to-date. For headless rendering, only report when something
* significant changes to keep the console output readable. */
if (status != last_status || (!headless && (current_time - last_status_time) > 1.0)) {
b_engine.update_stats("", (timestatus + scene_status + status).c_str());
b_engine.update_memory_stats(mem_used, mem_peak);
@@ -999,20 +907,27 @@ void BlenderSession::update_status_progress()
last_progress = progress;
}
if (session->progress.get_error()) {
string error = session->progress.get_error_message();
if (error != last_error) {
/* TODO(sergey): Currently C++ RNA API doesn't let us to
* use mnemonic name for the variable. Would be nice to
* have this figured out.
*
* For until then, 1 << 5 means RPT_ERROR.
*/
b_engine.report(1 << 5, error.c_str());
b_engine.error_set(error.c_str());
last_error = error;
}
check_and_report_session_error();
}
bool BlenderSession::check_and_report_session_error()
{
if (!session->progress.get_error()) {
return false;
}
const string error = session->progress.get_error_message();
if (error != last_error) {
/* TODO(sergey): Currently C++ RNA API doesn't let us to use mnemonic name for the variable.
* Would be nice to have this figured out.
*
* For until then, 1 << 5 means RPT_ERROR. */
b_engine.report(1 << 5, error.c_str());
b_engine.error_set(error.c_str());
last_error = error;
}
return true;
}
void BlenderSession::tag_update()
@@ -1048,56 +963,6 @@ void BlenderSession::test_cancel()
session->progress.set_cancel("Cancelled");
}
void BlenderSession::update_resumable_tile_manager(int num_samples)
{
const int num_resumable_chunks = BlenderSession::num_resumable_chunks,
current_resumable_chunk = BlenderSession::current_resumable_chunk;
if (num_resumable_chunks == 0) {
return;
}
if (num_resumable_chunks > num_samples) {
fprintf(stderr,
"Cycles warning: more sample chunks (%d) than samples (%d), "
"this will cause some samples to be included in multiple chunks.\n",
num_resumable_chunks,
num_samples);
}
const float num_samples_per_chunk = (float)num_samples / num_resumable_chunks;
float range_start_sample, range_num_samples;
if (current_resumable_chunk != 0) {
/* Single chunk rendering. */
range_start_sample = num_samples_per_chunk * (current_resumable_chunk - 1);
range_num_samples = num_samples_per_chunk;
}
else {
/* Ranged-chunks. */
const int num_chunks = end_resumable_chunk - start_resumable_chunk + 1;
range_start_sample = num_samples_per_chunk * (start_resumable_chunk - 1);
range_num_samples = num_chunks * num_samples_per_chunk;
}
/* Round after doing the multiplications with num_chunks and num_samples_per_chunk
* to allow for many small chunks. */
int rounded_range_start_sample = (int)floorf(range_start_sample + 0.5f);
int rounded_range_num_samples = max((int)floorf(range_num_samples + 0.5f), 1);
/* Make sure we don't overshoot. */
if (rounded_range_start_sample + rounded_range_num_samples > num_samples) {
rounded_range_num_samples = num_samples - rounded_range_num_samples;
}
VLOG(1) << "Samples range start is " << range_start_sample << ", "
<< "number of samples to render is " << range_num_samples;
scene->integrator->set_start_sample(rounded_range_start_sample);
session->tile_manager.range_start_sample = rounded_range_start_sample;
session->tile_manager.range_num_samples = rounded_range_num_samples;
}
void BlenderSession::free_blender_memory_if_possible()
{
if (!background) {

View File

@@ -29,12 +29,11 @@
CCL_NAMESPACE_BEGIN
class BlenderDisplayDriver;
class BlenderSync;
class ImageMetaData;
class Scene;
class Session;
class RenderBuffers;
class RenderTile;
class BlenderSession {
public:
@@ -62,6 +61,8 @@ class BlenderSession {
/* offline render */
void render(BL::Depsgraph &b_depsgraph);
void render_frame_finish();
void bake(BL::Depsgraph &b_depsgrah,
BL::Object &b_object,
const string &pass_type,
@@ -69,24 +70,16 @@ class BlenderSession {
const int bake_width,
const int bake_height);
void write_render_result(BL::RenderLayer &b_rlay, RenderTile &rtile);
void write_render_tile(RenderTile &rtile);
void read_render_tile(RenderTile &rtile);
/* update functions are used to update display buffer only after sample was rendered
* only needed for better visual feedback */
void update_render_result(BL::RenderLayer &b_rlay, RenderTile &rtile);
void update_render_tile(RenderTile &rtile, bool highlight);
void full_buffer_written(string_view filename);
/* interactive updates */
void synchronize(BL::Depsgraph &b_depsgraph);
/* drawing */
bool draw(int w, int h);
void draw(BL::SpaceImageEditor &space_image);
void view_draw(int w, int h);
void tag_redraw();
void tag_update();
void get_status(string &status, string &substatus);
void get_kernel_status(string &kernel_status);
void get_progress(float &progress, double &total_time, double &render_time);
void test_cancel();
void update_status_progress();
@@ -104,8 +97,7 @@ class BlenderSession {
BL::RenderSettings b_render;
BL::Depsgraph b_depsgraph;
/* NOTE: Blender's scene might become invalid after call
* free_blender_memory_if_possible().
*/
* #free_blender_memory_if_possible(). */
BL::Scene b_scene;
BL::SpaceView3D b_v3d;
BL::RegionView3D b_rv3d;
@@ -123,6 +115,8 @@ class BlenderSession {
void *python_thread_state;
bool use_developer_ui;
/* Global state which is common for all render sessions created from Blender.
* Usually denotes command line arguments.
*/
@@ -134,41 +128,33 @@ class BlenderSession {
*/
static bool headless;
/* ** Resumable render ** */
/* Overall number of chunks in which the sample range is to be divided. */
static int num_resumable_chunks;
/* Current resumable chunk index to render. */
static int current_resumable_chunk;
/* Alternative to single-chunk rendering to render a range of chunks. */
static int start_resumable_chunk;
static int end_resumable_chunk;
static bool print_render_stats;
protected:
void stamp_view_layer_metadata(Scene *scene, const string &view_layer_name);
void do_write_update_render_result(BL::RenderLayer &b_rlay,
RenderTile &rtile,
bool do_update_only);
void do_write_update_render_tile(RenderTile &rtile,
bool do_update_only,
bool do_read_only,
bool highlight);
/* Check whether session error happened.
* If so, it is reported to the render engine and true is returned.
* Otherwise false is returned. */
bool check_and_report_session_error();
void builtin_images_load();
/* Update tile manager to reflect resumable render settings. */
void update_resumable_tile_manager(int num_samples);
/* Is used after each render layer synchronization is done with the goal
* of freeing render engine data which is held from Blender side (for
* example, dependency graph).
*/
void free_blender_memory_if_possible();
struct {
thread_mutex mutex;
int last_pass_index = -1;
} draw_state_;
/* NOTE: The BlenderSession references the display driver. */
BlenderDisplayDriver *display_driver_ = nullptr;
vector<string> full_buffer_files_;
};
CCL_NAMESPACE_END

View File

@@ -17,6 +17,7 @@
#include "render/background.h"
#include "render/colorspace.h"
#include "render/graph.h"
#include "render/integrator.h"
#include "render/light.h"
#include "render/nodes.h"
#include "render/osl.h"
@@ -278,7 +279,7 @@ static ShaderNode *add_node(Scene *scene,
array<float3> curve_mapping_curves;
float min_x, max_x;
curvemapping_color_to_array(mapping, curve_mapping_curves, RAMP_TABLE_SIZE, true);
curvemapping_minmax(mapping, true, &min_x, &max_x);
curvemapping_minmax(mapping, 4, &min_x, &max_x);
curves->set_min_x(min_x);
curves->set_max_x(max_x);
curves->set_curves(curve_mapping_curves);
@@ -291,12 +292,25 @@ static ShaderNode *add_node(Scene *scene,
array<float3> curve_mapping_curves;
float min_x, max_x;
curvemapping_color_to_array(mapping, curve_mapping_curves, RAMP_TABLE_SIZE, false);
curvemapping_minmax(mapping, false, &min_x, &max_x);
curvemapping_minmax(mapping, 3, &min_x, &max_x);
curves->set_min_x(min_x);
curves->set_max_x(max_x);
curves->set_curves(curve_mapping_curves);
node = curves;
}
else if (b_node.is_a(&RNA_ShaderNodeFloatCurve)) {
BL::ShaderNodeFloatCurve b_curve_node(b_node);
BL::CurveMapping mapping(b_curve_node.mapping());
FloatCurveNode *curve = graph->create_node<FloatCurveNode>();
array<float> curve_mapping_curve;
float min_x, max_x;
curvemapping_float_to_array(mapping, curve_mapping_curve, RAMP_TABLE_SIZE);
curvemapping_minmax(mapping, 1, &min_x, &max_x);
curve->set_min_x(min_x);
curve->set_max_x(max_x);
curve->set_curve(curve_mapping_curve);
node = curve;
}
else if (b_node.is_a(&RNA_ShaderNodeValToRGB)) {
RGBRampNode *ramp = graph->create_node<RGBRampNode>();
BL::ShaderNodeValToRGB b_ramp_node(b_node);
@@ -475,17 +489,11 @@ static ShaderNode *add_node(Scene *scene,
SubsurfaceScatteringNode *subsurface = graph->create_node<SubsurfaceScatteringNode>();
switch (b_subsurface_node.falloff()) {
case BL::ShaderNodeSubsurfaceScattering::falloff_CUBIC:
subsurface->set_falloff(CLOSURE_BSSRDF_CUBIC_ID);
break;
case BL::ShaderNodeSubsurfaceScattering::falloff_GAUSSIAN:
subsurface->set_falloff(CLOSURE_BSSRDF_GAUSSIAN_ID);
break;
case BL::ShaderNodeSubsurfaceScattering::falloff_BURLEY:
subsurface->set_falloff(CLOSURE_BSSRDF_BURLEY_ID);
case BL::ShaderNodeSubsurfaceScattering::falloff_RANDOM_WALK_FIXED_RADIUS:
subsurface->set_method(CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID);
break;
case BL::ShaderNodeSubsurfaceScattering::falloff_RANDOM_WALK:
subsurface->set_falloff(CLOSURE_BSSRDF_RANDOM_WALK_ID);
subsurface->set_method(CLOSURE_BSSRDF_RANDOM_WALK_ID);
break;
}
@@ -597,11 +605,11 @@ static ShaderNode *add_node(Scene *scene,
break;
}
switch (b_principled_node.subsurface_method()) {
case BL::ShaderNodeBsdfPrincipled::subsurface_method_BURLEY:
principled->set_subsurface_method(CLOSURE_BSSRDF_PRINCIPLED_ID);
case BL::ShaderNodeBsdfPrincipled::subsurface_method_RANDOM_WALK_FIXED_RADIUS:
principled->set_subsurface_method(CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID);
break;
case BL::ShaderNodeBsdfPrincipled::subsurface_method_RANDOM_WALK:
principled->set_subsurface_method(CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID);
principled->set_subsurface_method(CLOSURE_BSSRDF_RANDOM_WALK_ID);
break;
}
node = principled;
@@ -1360,10 +1368,11 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, bool update_all)
{
Background *background = scene->background;
Integrator *integrator = scene->integrator;
BL::World b_world = b_scene.world();
BlenderViewportParameters new_viewport_parameters(b_v3d);
BlenderViewportParameters new_viewport_parameters(b_v3d, use_developer_ui);
if (world_recalc || update_all || b_world.ptr.data != world_map ||
viewport_parameters.shader_modified(new_viewport_parameters)) {
@@ -1455,9 +1464,8 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
/* AO */
BL::WorldLighting b_light = b_world.light_settings();
background->set_use_ao(b_light.use_ambient_occlusion());
background->set_ao_factor(b_light.ao_factor());
background->set_ao_distance(b_light.distance());
integrator->set_ao_factor(b_light.ao_factor());
integrator->set_ao_distance(b_light.distance());
/* visibility */
PointerRNA cvisibility = RNA_pointer_get(&b_world.ptr, "cycles_visibility");
@@ -1472,9 +1480,8 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
background->set_visibility(visibility);
}
else {
background->set_use_ao(false);
background->set_ao_factor(0.0f);
background->set_ao_distance(FLT_MAX);
integrator->set_ao_factor(1.0f);
integrator->set_ao_distance(10.0f);
}
shader->set_graph(graph);
@@ -1496,7 +1503,6 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
background->set_use_shader(view_layer.use_background_shader ||
viewport_parameters.use_custom_shader());
background->set_use_ao(background->get_use_ao() && view_layer.use_background_ao);
background->tag_update(scene);
}

View File

@@ -53,6 +53,7 @@ BlenderSync::BlenderSync(BL::RenderEngine &b_engine,
BL::Scene &b_scene,
Scene *scene,
bool preview,
bool use_developer_ui,
Progress &progress)
: b_engine(b_engine),
b_data(b_data),
@@ -68,6 +69,7 @@ BlenderSync::BlenderSync(BL::RenderEngine &b_engine,
scene(scene),
preview(preview),
experimental(false),
use_developer_ui(use_developer_ui),
dicing_rate(1.0f),
max_subdivisions(12),
progress(progress),
@@ -224,7 +226,7 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
}
if (b_v3d) {
BlenderViewportParameters new_viewport_parameters(b_v3d);
BlenderViewportParameters new_viewport_parameters(b_v3d, use_developer_ui);
if (viewport_parameters.shader_modified(new_viewport_parameters)) {
world_recalc = true;
@@ -251,9 +253,13 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render,
BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
/* TODO(sergey): This feels weak to pass view layer to the integrator, and even weaker to have an
* implicit check on whether it is a background render or not. What is the nicer thing here? */
const bool background = !b_v3d;
sync_view_layer(b_view_layer);
sync_integrator();
sync_film(b_v3d);
sync_integrator(b_view_layer, background);
sync_film(b_view_layer, b_v3d);
sync_shaders(b_depsgraph, b_v3d);
sync_images();
@@ -280,7 +286,7 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render,
/* Integrator */
void BlenderSync::sync_integrator()
void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background)
{
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
@@ -328,59 +334,24 @@ void BlenderSync::sync_integrator()
integrator->set_motion_blur(view_layer.use_motion_blur);
}
integrator->set_method((Integrator::Method)get_enum(
cscene, "progressive", Integrator::NUM_METHODS, Integrator::PATH));
integrator->set_sample_all_lights_direct(get_boolean(cscene, "sample_all_lights_direct"));
integrator->set_sample_all_lights_indirect(get_boolean(cscene, "sample_all_lights_indirect"));
integrator->set_light_sampling_threshold(get_float(cscene, "light_sampling_threshold"));
SamplingPattern sampling_pattern = (SamplingPattern)get_enum(
cscene, "sampling_pattern", SAMPLING_NUM_PATTERNS, SAMPLING_PATTERN_SOBOL);
int adaptive_min_samples = INT_MAX;
if (RNA_boolean_get(&cscene, "use_adaptive_sampling")) {
sampling_pattern = SAMPLING_PATTERN_PMJ;
adaptive_min_samples = get_int(cscene, "adaptive_min_samples");
integrator->set_adaptive_threshold(get_float(cscene, "adaptive_threshold"));
}
else {
integrator->set_adaptive_threshold(0.0f);
}
integrator->set_sampling_pattern(sampling_pattern);
int diffuse_samples = get_int(cscene, "diffuse_samples");
int glossy_samples = get_int(cscene, "glossy_samples");
int transmission_samples = get_int(cscene, "transmission_samples");
int ao_samples = get_int(cscene, "ao_samples");
int mesh_light_samples = get_int(cscene, "mesh_light_samples");
int subsurface_samples = get_int(cscene, "subsurface_samples");
int volume_samples = get_int(cscene, "volume_samples");
if (get_boolean(cscene, "use_square_samples")) {
integrator->set_diffuse_samples(diffuse_samples * diffuse_samples);
integrator->set_glossy_samples(glossy_samples * glossy_samples);
integrator->set_transmission_samples(transmission_samples * transmission_samples);
integrator->set_ao_samples(ao_samples * ao_samples);
integrator->set_mesh_light_samples(mesh_light_samples * mesh_light_samples);
integrator->set_subsurface_samples(subsurface_samples * subsurface_samples);
integrator->set_volume_samples(volume_samples * volume_samples);
adaptive_min_samples = min(adaptive_min_samples * adaptive_min_samples, INT_MAX);
if (preview) {
integrator->set_use_adaptive_sampling(
RNA_boolean_get(&cscene, "use_preview_adaptive_sampling"));
integrator->set_adaptive_threshold(get_float(cscene, "preview_adaptive_threshold"));
integrator->set_adaptive_min_samples(get_int(cscene, "preview_adaptive_min_samples"));
}
else {
integrator->set_diffuse_samples(diffuse_samples);
integrator->set_glossy_samples(glossy_samples);
integrator->set_transmission_samples(transmission_samples);
integrator->set_ao_samples(ao_samples);
integrator->set_mesh_light_samples(mesh_light_samples);
integrator->set_subsurface_samples(subsurface_samples);
integrator->set_volume_samples(volume_samples);
integrator->set_use_adaptive_sampling(RNA_boolean_get(&cscene, "use_adaptive_sampling"));
integrator->set_adaptive_threshold(get_float(cscene, "adaptive_threshold"));
integrator->set_adaptive_min_samples(get_int(cscene, "adaptive_min_samples"));
}
integrator->set_adaptive_min_samples(adaptive_min_samples);
if (get_boolean(cscene, "use_fast_gi")) {
if (preview) {
integrator->set_ao_bounces(get_int(cscene, "ao_bounces"));
@@ -393,20 +364,38 @@ void BlenderSync::sync_integrator()
integrator->set_ao_bounces(0);
}
/* UPDATE_NONE as we don't want to tag the integrator as modified, just tag dependent things */
const DenoiseParams denoise_params = get_denoise_params(b_scene, b_view_layer, background);
integrator->set_use_denoise(denoise_params.use);
/* Only update denoiser parameters if the denoiser is actually used. This allows to tweak
* denoiser parameters before enabling it without render resetting on every change. The downside
* is that the interface and the integrator are technically out of sync. */
if (denoise_params.use) {
integrator->set_denoiser_type(denoise_params.type);
integrator->set_denoise_start_sample(denoise_params.start_sample);
integrator->set_use_denoise_pass_albedo(denoise_params.use_pass_albedo);
integrator->set_use_denoise_pass_normal(denoise_params.use_pass_normal);
integrator->set_denoiser_prefilter(denoise_params.prefilter);
}
/* UPDATE_NONE as we don't want to tag the integrator as modified (this was done by the
* set calls above), but we need to make sure that the dependent things are tagged. */
integrator->tag_update(scene, Integrator::UPDATE_NONE);
}
/* Film */
void BlenderSync::sync_film(BL::SpaceView3D &b_v3d)
void BlenderSync::sync_film(BL::ViewLayer &b_view_layer, BL::SpaceView3D &b_v3d)
{
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
PointerRNA crl = RNA_pointer_get(&b_view_layer.ptr, "cycles");
Film *film = scene->film;
if (b_v3d) {
film->set_display_pass(update_viewport_display_passes(b_v3d, scene->passes));
const BlenderViewportParameters new_viewport_parameters(b_v3d, use_developer_ui);
film->set_display_pass(new_viewport_parameters.display_pass);
film->set_show_active_pixels(new_viewport_parameters.show_active_pixels);
}
film->set_exposure(get_float(cscene, "film_exposure"));
@@ -434,6 +423,15 @@ void BlenderSync::sync_film(BL::SpaceView3D &b_v3d)
break;
}
}
/* Blender viewport does not support proper shadow catcher compositing, so force an approximate
* mode to improve visual feedback. */
if (b_v3d) {
film->set_use_approximate_shadow_catcher(true);
}
else {
film->set_use_approximate_shadow_catcher(!get_boolean(crl, "use_pass_shadow_catcher"));
}
}
/* Render Layer */
@@ -444,7 +442,6 @@ void BlenderSync::sync_view_layer(BL::ViewLayer &b_view_layer)
/* Filter. */
view_layer.use_background_shader = b_view_layer.use_sky();
view_layer.use_background_ao = b_view_layer.use_ao();
/* Always enable surfaces for baking, otherwise there is nothing to bake to. */
view_layer.use_surfaces = b_view_layer.use_solid() || scene->bake_manager->get_baking();
view_layer.use_hair = b_view_layer.use_strand();
@@ -464,10 +461,7 @@ void BlenderSync::sync_view_layer(BL::ViewLayer &b_view_layer)
if (use_layer_samples != 2) {
int samples = b_view_layer.samples();
if (get_boolean(cscene, "use_square_samples"))
view_layer.samples = samples * samples;
else
view_layer.samples = samples;
view_layer.samples = samples;
}
}
@@ -499,7 +493,8 @@ void BlenderSync::sync_images()
}
/* Passes */
PassType BlenderSync::get_pass_type(BL::RenderPass &b_pass)
static PassType get_blender_pass_type(BL::RenderPass &b_pass)
{
string name = b_pass.name();
#define MAP_PASS(passname, passtype) \
@@ -507,10 +502,15 @@ PassType BlenderSync::get_pass_type(BL::RenderPass &b_pass)
return passtype; \
} \
((void)0)
/* NOTE: Keep in sync with defined names from DNA_scene_types.h */
MAP_PASS("Combined", PASS_COMBINED);
MAP_PASS("Noisy Image", PASS_COMBINED);
MAP_PASS("Depth", PASS_DEPTH);
MAP_PASS("Mist", PASS_MIST);
MAP_PASS("Position", PASS_POSITION);
MAP_PASS("Normal", PASS_NORMAL);
MAP_PASS("IndexOB", PASS_OBJECT_ID);
MAP_PASS("UV", PASS_UV);
@@ -539,118 +539,92 @@ PassType BlenderSync::get_pass_type(BL::RenderPass &b_pass)
MAP_PASS("BakePrimitive", PASS_BAKE_PRIMITIVE);
MAP_PASS("BakeDifferential", PASS_BAKE_DIFFERENTIAL);
MAP_PASS("Denoising Normal", PASS_DENOISING_NORMAL);
MAP_PASS("Denoising Albedo", PASS_DENOISING_ALBEDO);
MAP_PASS("Shadow Catcher", PASS_SHADOW_CATCHER);
MAP_PASS("Noisy Shadow Catcher", PASS_SHADOW_CATCHER);
MAP_PASS("Debug Render Time", PASS_RENDER_TIME);
MAP_PASS("AdaptiveAuxBuffer", PASS_ADAPTIVE_AUX_BUFFER);
MAP_PASS("Debug Sample Count", PASS_SAMPLE_COUNT);
if (string_startswith(name, cryptomatte_prefix)) {
return PASS_CRYPTOMATTE;
}
#undef MAP_PASS
return PASS_NONE;
}
int BlenderSync::get_denoising_pass(BL::RenderPass &b_pass)
static Pass *pass_add(Scene *scene,
PassType type,
const char *name,
PassMode mode = PassMode::DENOISED)
{
string name = b_pass.name();
Pass *pass = scene->create_node<Pass>();
if (name == "Noisy Image")
return DENOISING_PASS_PREFILTERED_COLOR;
pass->set_type(type);
pass->set_name(ustring(name));
pass->set_mode(mode);
if (name.substr(0, 10) != "Denoising ") {
return -1;
}
name = name.substr(10);
#define MAP_PASS(passname, offset) \
if (name == passname) { \
return offset; \
} \
((void)0)
MAP_PASS("Normal", DENOISING_PASS_PREFILTERED_NORMAL);
MAP_PASS("Albedo", DENOISING_PASS_PREFILTERED_ALBEDO);
MAP_PASS("Depth", DENOISING_PASS_PREFILTERED_DEPTH);
MAP_PASS("Shadowing", DENOISING_PASS_PREFILTERED_SHADOWING);
MAP_PASS("Variance", DENOISING_PASS_PREFILTERED_VARIANCE);
MAP_PASS("Intensity", DENOISING_PASS_PREFILTERED_INTENSITY);
MAP_PASS("Clean", DENOISING_PASS_CLEAN);
#undef MAP_PASS
return -1;
return pass;
}
vector<Pass> BlenderSync::sync_render_passes(BL::Scene &b_scene,
BL::RenderLayer &b_rlay,
BL::ViewLayer &b_view_layer,
bool adaptive_sampling,
const DenoiseParams &denoising)
void BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLayer &b_view_layer)
{
vector<Pass> passes;
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
/* loop over passes */
/* Delete all existing passes. */
set<Pass *> clear_passes(scene->passes.begin(), scene->passes.end());
scene->delete_nodes(clear_passes);
/* Always add combined pass. */
pass_add(scene, PASS_COMBINED, "Combined");
/* Blender built-in data and light passes. */
for (BL::RenderPass &b_pass : b_rlay.passes) {
PassType pass_type = get_pass_type(b_pass);
const PassType pass_type = get_blender_pass_type(b_pass);
if (pass_type == PASS_NONE) {
LOG(ERROR) << "Unknown pass " << b_pass.name();
continue;
}
if (pass_type == PASS_MOTION &&
(b_view_layer.use_motion_blur() && b_scene.render().use_motion_blur())) {
continue;
}
if (pass_type != PASS_NONE)
Pass::add(pass_type, passes, b_pass.name().c_str());
pass_add(scene, pass_type, b_pass.name().c_str());
}
PointerRNA crl = RNA_pointer_get(&b_view_layer.ptr, "cycles");
int denoising_flags = 0;
if (denoising.use || denoising.store_passes) {
if (denoising.type == DENOISER_NLM) {
#define MAP_OPTION(name, flag) \
if (!get_boolean(crl, name)) { \
denoising_flags |= flag; \
} \
((void)0)
MAP_OPTION("denoising_diffuse_direct", DENOISING_CLEAN_DIFFUSE_DIR);
MAP_OPTION("denoising_diffuse_indirect", DENOISING_CLEAN_DIFFUSE_IND);
MAP_OPTION("denoising_glossy_direct", DENOISING_CLEAN_GLOSSY_DIR);
MAP_OPTION("denoising_glossy_indirect", DENOISING_CLEAN_GLOSSY_IND);
MAP_OPTION("denoising_transmission_direct", DENOISING_CLEAN_TRANSMISSION_DIR);
MAP_OPTION("denoising_transmission_indirect", DENOISING_CLEAN_TRANSMISSION_IND);
#undef MAP_OPTION
}
b_engine.add_pass("Noisy Image", 4, "RGBA", b_view_layer.name().c_str());
}
scene->film->set_denoising_flags(denoising_flags);
if (denoising.store_passes) {
b_engine.add_pass("Denoising Normal", 3, "XYZ", b_view_layer.name().c_str());
b_engine.add_pass("Denoising Albedo", 3, "RGB", b_view_layer.name().c_str());
b_engine.add_pass("Denoising Depth", 1, "Z", b_view_layer.name().c_str());
if (denoising.type == DENOISER_NLM) {
b_engine.add_pass("Denoising Shadowing", 1, "X", b_view_layer.name().c_str());
b_engine.add_pass("Denoising Variance", 3, "RGB", b_view_layer.name().c_str());
b_engine.add_pass("Denoising Intensity", 1, "X", b_view_layer.name().c_str());
}
if (scene->film->get_denoising_flags() & DENOISING_CLEAN_ALL_PASSES) {
b_engine.add_pass("Denoising Clean", 3, "RGB", b_view_layer.name().c_str());
}
}
/* Debug passes. */
if (get_boolean(crl, "pass_debug_render_time")) {
b_engine.add_pass("Debug Render Time", 1, "X", b_view_layer.name().c_str());
Pass::add(PASS_RENDER_TIME, passes, "Debug Render Time");
pass_add(scene, PASS_RENDER_TIME, "Debug Render Time");
}
if (get_boolean(crl, "pass_debug_sample_count")) {
b_engine.add_pass("Debug Sample Count", 1, "X", b_view_layer.name().c_str());
Pass::add(PASS_SAMPLE_COUNT, passes, "Debug Sample Count");
pass_add(scene, PASS_SAMPLE_COUNT, "Debug Sample Count");
}
/* Cycles specific passes. */
if (get_boolean(crl, "use_pass_volume_direct")) {
b_engine.add_pass("VolumeDir", 3, "RGB", b_view_layer.name().c_str());
Pass::add(PASS_VOLUME_DIRECT, passes, "VolumeDir");
pass_add(scene, PASS_VOLUME_DIRECT, "VolumeDir");
}
if (get_boolean(crl, "use_pass_volume_indirect")) {
b_engine.add_pass("VolumeInd", 3, "RGB", b_view_layer.name().c_str());
Pass::add(PASS_VOLUME_INDIRECT, passes, "VolumeInd");
pass_add(scene, PASS_VOLUME_INDIRECT, "VolumeInd");
}
if (get_boolean(crl, "use_pass_shadow_catcher")) {
b_engine.add_pass("Shadow Catcher", 3, "RGB", b_view_layer.name().c_str());
pass_add(scene, PASS_SHADOW_CATCHER, "Shadow Catcher");
}
/* Cryptomatte stores two ID/weight pairs per RGBA layer.
@@ -662,7 +636,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::Scene &b_scene,
for (int i = 0; i < crypto_depth; i++) {
string passname = cryptomatte_prefix + string_printf("Object%02d", i);
b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str());
pass_add(scene, PASS_CRYPTOMATTE, passname.c_str());
}
cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_OBJECT);
}
@@ -670,7 +644,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::Scene &b_scene,
for (int i = 0; i < crypto_depth; i++) {
string passname = cryptomatte_prefix + string_printf("Material%02d", i);
b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str());
pass_add(scene, PASS_CRYPTOMATTE, passname.c_str());
}
cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_MATERIAL);
}
@@ -678,22 +652,33 @@ vector<Pass> BlenderSync::sync_render_passes(BL::Scene &b_scene,
for (int i = 0; i < crypto_depth; i++) {
string passname = cryptomatte_prefix + string_printf("Asset%02d", i);
b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str());
pass_add(scene, PASS_CRYPTOMATTE, passname.c_str());
}
cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_ASSET);
}
if (b_view_layer.use_pass_cryptomatte_accurate() && cryptomatte_passes != CRYPT_NONE) {
cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_ACCURATE);
}
scene->film->set_cryptomatte_passes(cryptomatte_passes);
if (adaptive_sampling) {
Pass::add(PASS_ADAPTIVE_AUX_BUFFER, passes);
if (!get_boolean(crl, "pass_debug_sample_count")) {
Pass::add(PASS_SAMPLE_COUNT, passes);
/* Denoising passes. */
const bool use_denoising = get_boolean(cscene, "use_denoising") &&
get_boolean(crl, "use_denoising");
const bool store_denoising_passes = get_boolean(crl, "denoising_store_passes");
if (use_denoising) {
b_engine.add_pass("Noisy Image", 4, "RGBA", b_view_layer.name().c_str());
pass_add(scene, PASS_COMBINED, "Noisy Image", PassMode::NOISY);
if (get_boolean(crl, "use_pass_shadow_catcher")) {
b_engine.add_pass("Noisy Shadow Catcher", 3, "RGB", b_view_layer.name().c_str());
pass_add(scene, PASS_SHADOW_CATCHER, "Noisy Shadow Catcher", PassMode::NOISY);
}
}
if (store_denoising_passes) {
b_engine.add_pass("Denoising Normal", 3, "XYZ", b_view_layer.name().c_str());
pass_add(scene, PASS_DENOISING_NORMAL, "Denoising Normal", PassMode::NOISY);
b_engine.add_pass("Denoising Albedo", 3, "RGB", b_view_layer.name().c_str());
pass_add(scene, PASS_DENOISING_ALBEDO, "Denoising Albedo", PassMode::NOISY);
}
/* Custom AOV passes. */
BL::ViewLayer::aovs_iterator b_aov_iter;
for (b_view_layer.aovs.begin(b_aov_iter); b_aov_iter != b_view_layer.aovs.end(); ++b_aov_iter) {
BL::AOV b_aov(*b_aov_iter);
@@ -706,28 +691,15 @@ vector<Pass> BlenderSync::sync_render_passes(BL::Scene &b_scene,
if (is_color) {
b_engine.add_pass(name.c_str(), 4, "RGBA", b_view_layer.name().c_str());
Pass::add(PASS_AOV_COLOR, passes, name.c_str());
pass_add(scene, PASS_AOV_COLOR, name.c_str());
}
else {
b_engine.add_pass(name.c_str(), 1, "X", b_view_layer.name().c_str());
Pass::add(PASS_AOV_VALUE, passes, name.c_str());
pass_add(scene, PASS_AOV_VALUE, name.c_str());
}
}
scene->film->set_denoising_data_pass(denoising.use || denoising.store_passes);
scene->film->set_denoising_clean_pass(scene->film->get_denoising_flags() &
DENOISING_CLEAN_ALL_PASSES);
scene->film->set_denoising_prefiltered_pass(denoising.store_passes &&
denoising.type == DENOISER_NLM);
scene->film->set_pass_alpha_threshold(b_view_layer.pass_alpha_threshold());
if (!Pass::equals(passes, scene->passes)) {
scene->film->tag_passes_update(scene, passes);
scene->film->tag_modified();
scene->integrator->tag_update(scene, Integrator::UPDATE_ALL);
}
return passes;
}
void BlenderSync::free_data_after_sync(BL::Depsgraph &b_depsgraph)
@@ -773,9 +745,9 @@ SceneParams BlenderSync::get_scene_params(BL::Scene &b_scene, bool background)
params.shadingsystem = SHADINGSYSTEM_OSL;
if (background || DebugFlags().viewport_static_bvh)
params.bvh_type = SceneParams::BVH_STATIC;
params.bvh_type = BVH_TYPE_STATIC;
else
params.bvh_type = SceneParams::BVH_DYNAMIC;
params.bvh_type = BVH_TYPE_DYNAMIC;
params.use_bvh_spatial_split = RNA_boolean_get(&cscene, "debug_use_spatial_splits");
params.use_bvh_unaligned_nodes = RNA_boolean_get(&cscene, "debug_use_hair_bvh");
@@ -818,8 +790,7 @@ bool BlenderSync::get_session_pause(BL::Scene &b_scene, bool background)
SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
BL::Preferences &b_preferences,
BL::Scene &b_scene,
bool background,
BL::ViewLayer b_view_layer)
bool background)
{
SessionParams params;
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
@@ -827,7 +798,8 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
/* feature set */
params.experimental = (get_enum(cscene, "feature_set") != 0);
/* Background */
/* Headless and background rendering. */
params.headless = BlenderSession::headless;
params.background = background;
/* Device */
@@ -836,111 +808,26 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
/* samples */
int samples = get_int(cscene, "samples");
int aa_samples = get_int(cscene, "aa_samples");
int preview_samples = get_int(cscene, "preview_samples");
int preview_aa_samples = get_int(cscene, "preview_aa_samples");
if (get_boolean(cscene, "use_square_samples")) {
aa_samples = aa_samples * aa_samples;
preview_aa_samples = preview_aa_samples * preview_aa_samples;
samples = samples * samples;
preview_samples = preview_samples * preview_samples;
}
if (get_enum(cscene, "progressive") == 0 && params.device.has_branched_path) {
if (background) {
params.samples = aa_samples;
}
else {
params.samples = preview_aa_samples;
if (params.samples == 0)
params.samples = INT_MAX;
}
if (background) {
params.samples = samples;
}
else {
if (background) {
params.samples = samples;
}
else {
params.samples = preview_samples;
if (params.samples == 0)
params.samples = INT_MAX;
}
params.samples = preview_samples;
if (params.samples == 0)
params.samples = INT_MAX;
}
/* Clamp samples. */
params.samples = min(params.samples, Integrator::MAX_SAMPLES);
/* Adaptive sampling. */
params.adaptive_sampling = RNA_boolean_get(&cscene, "use_adaptive_sampling");
/* tiles */
const bool is_cpu = (params.device.type == DEVICE_CPU);
if (!is_cpu && !background) {
/* currently GPU could be much slower than CPU when using tiles,
* still need to be investigated, but meanwhile make it possible
* to work in viewport smoothly
*/
int debug_tile_size = get_int(cscene, "debug_tile_size");
params.tile_size = make_int2(debug_tile_size, debug_tile_size);
}
else {
int tile_x = b_engine.tile_x();
int tile_y = b_engine.tile_y();
params.tile_size = make_int2(tile_x, tile_y);
}
if ((BlenderSession::headless == false) && background) {
params.tile_order = (TileOrder)get_enum(cscene, "tile_order");
}
else {
params.tile_order = TILE_BOTTOM_TO_TOP;
}
/* Denoising */
params.denoising = get_denoise_params(b_scene, b_view_layer, background);
if (params.denoising.use) {
/* Add additional denoising devices if we are rendering and denoising
* with different devices. */
params.device.add_denoising_devices(params.denoising.type);
/* Check if denoiser is supported by device. */
if (!(params.device.denoisers & params.denoising.type)) {
params.denoising.use = false;
}
}
/* Viewport Performance */
params.start_resolution = get_int(cscene, "preview_start_resolution");
params.pixel_size = b_engine.get_preview_pixel_size(b_scene);
/* other parameters */
params.cancel_timeout = (double)get_float(cscene, "debug_cancel_timeout");
params.reset_timeout = (double)get_float(cscene, "debug_reset_timeout");
params.text_timeout = (double)get_float(cscene, "debug_text_timeout");
/* progressive refine */
BL::RenderSettings b_r = b_scene.render();
params.progressive_refine = b_engine.is_preview() ||
get_boolean(cscene, "use_progressive_refine");
if (b_r.use_save_buffers() || params.adaptive_sampling)
params.progressive_refine = false;
if (background) {
if (params.progressive_refine)
params.progressive = true;
else
params.progressive = false;
params.start_resolution = INT_MAX;
params.pixel_size = 1;
}
else
params.progressive = true;
/* shading system - scene level needs full refresh */
const bool shadingsystem = RNA_boolean_get(&cscene, "shading_system");
@@ -950,19 +837,30 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
else if (shadingsystem == 1)
params.shadingsystem = SHADINGSYSTEM_OSL;
/* Color management. */
params.display_buffer_linear = b_engine.support_display_space_shader(b_scene);
if (b_engine.is_preview()) {
/* For preview rendering we're using same timeout as
* blender's job update.
*/
params.progressive_update_timeout = 0.1;
/* Time limit. */
if (background) {
params.time_limit = get_float(cscene, "time_limit");
}
else {
/* For the viewport it kind of makes more sense to think in terms of the noise floor, which is
* usually higher than acceptable level for the final frame. */
/* TODO: It might be useful to support time limit in the viewport as well, but needs some
* extra thoughts and input. */
params.time_limit = 0.0;
}
/* Profiling. */
params.use_profiling = params.device.has_profiling && !b_engine.is_preview() && background &&
BlenderSession::print_render_stats;
if (background) {
params.use_auto_tile = RNA_boolean_get(&cscene, "use_auto_tile");
params.tile_size = max(get_int(cscene, "tile_size"), 8);
}
else {
params.use_auto_tile = false;
}
return params;
}
@@ -970,33 +868,34 @@ DenoiseParams BlenderSync::get_denoise_params(BL::Scene &b_scene,
BL::ViewLayer &b_view_layer,
bool background)
{
enum DenoiserInput {
DENOISER_INPUT_RGB = 1,
DENOISER_INPUT_RGB_ALBEDO = 2,
DENOISER_INPUT_RGB_ALBEDO_NORMAL = 3,
DENOISER_INPUT_NUM,
};
DenoiseParams denoising;
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
int input_passes = -1;
if (background) {
/* Final Render Denoising */
denoising.use = get_boolean(cscene, "use_denoising");
denoising.type = (DenoiserType)get_enum(cscene, "denoiser", DENOISER_NUM, DENOISER_NONE);
denoising.prefilter = (DenoiserPrefilter)get_enum(
cscene, "denoising_prefilter", DENOISER_PREFILTER_NUM, DENOISER_PREFILTER_NONE);
input_passes = (DenoiserInput)get_enum(
cscene, "denoising_input_passes", DENOISER_INPUT_NUM, DENOISER_INPUT_RGB_ALBEDO_NORMAL);
if (b_view_layer) {
PointerRNA clayer = RNA_pointer_get(&b_view_layer.ptr, "cycles");
if (!get_boolean(clayer, "use_denoising")) {
denoising.use = false;
}
denoising.radius = get_int(clayer, "denoising_radius");
denoising.strength = get_float(clayer, "denoising_strength");
denoising.feature_strength = get_float(clayer, "denoising_feature_strength");
denoising.relative_pca = get_boolean(clayer, "denoising_relative_pca");
denoising.input_passes = (DenoiserInput)get_enum(
clayer,
(denoising.type == DENOISER_OPTIX) ? "denoising_optix_input_passes" :
"denoising_openimagedenoise_input_passes",
DENOISER_INPUT_NUM,
DENOISER_INPUT_RGB_ALBEDO_NORMAL);
denoising.store_passes = get_boolean(clayer, "denoising_store_passes");
}
}
else {
@@ -1004,10 +903,12 @@ DenoiseParams BlenderSync::get_denoise_params(BL::Scene &b_scene,
denoising.use = get_boolean(cscene, "use_preview_denoising");
denoising.type = (DenoiserType)get_enum(
cscene, "preview_denoiser", DENOISER_NUM, DENOISER_NONE);
denoising.prefilter = (DenoiserPrefilter)get_enum(
cscene, "preview_denoising_prefilter", DENOISER_PREFILTER_NUM, DENOISER_PREFILTER_FAST);
denoising.start_sample = get_int(cscene, "preview_denoising_start_sample");
denoising.input_passes = (DenoiserInput)get_enum(
cscene, "preview_denoising_input_passes", DENOISER_INPUT_NUM, (int)denoising.input_passes);
input_passes = (DenoiserInput)get_enum(
cscene, "preview_denoising_input_passes", DENOISER_INPUT_NUM, DENOISER_INPUT_RGB_ALBEDO);
/* Auto select fastest denoiser. */
if (denoising.type == DENOISER_NONE) {
@@ -1023,6 +924,27 @@ DenoiseParams BlenderSync::get_denoise_params(BL::Scene &b_scene,
}
}
switch (input_passes) {
case DENOISER_INPUT_RGB:
denoising.use_pass_albedo = false;
denoising.use_pass_normal = false;
break;
case DENOISER_INPUT_RGB_ALBEDO:
denoising.use_pass_albedo = true;
denoising.use_pass_normal = false;
break;
case DENOISER_INPUT_RGB_ALBEDO_NORMAL:
denoising.use_pass_albedo = true;
denoising.use_pass_normal = true;
break;
default:
LOG(ERROR) << "Unhandled input passes enum " << input_passes;
break;
}
return denoising;
}

View File

@@ -23,6 +23,7 @@
#include "RNA_types.h"
#include "blender/blender_id_map.h"
#include "blender/blender_util.h"
#include "blender/blender_viewport.h"
#include "render/scene.h"
@@ -59,6 +60,7 @@ class BlenderSync {
BL::Scene &b_scene,
Scene *scene,
bool preview,
bool use_developer_ui,
Progress &progress);
~BlenderSync();
@@ -74,12 +76,8 @@ class BlenderSync {
int height,
void **python_thread_state);
void sync_view_layer(BL::ViewLayer &b_view_layer);
vector<Pass> sync_render_passes(BL::Scene &b_scene,
BL::RenderLayer &b_render_layer,
BL::ViewLayer &b_view_layer,
bool adaptive_sampling,
const DenoiseParams &denoising);
void sync_integrator();
void sync_render_passes(BL::RenderLayer &b_render_layer, BL::ViewLayer &b_view_layer);
void sync_integrator(BL::ViewLayer &b_view_layer, bool background);
void sync_camera(BL::RenderSettings &b_render,
BL::Object &b_override,
int width,
@@ -97,22 +95,13 @@ class BlenderSync {
/* get parameters */
static SceneParams get_scene_params(BL::Scene &b_scene, bool background);
static SessionParams get_session_params(
BL::RenderEngine &b_engine,
BL::Preferences &b_userpref,
BL::Scene &b_scene,
bool background,
BL::ViewLayer b_view_layer = BL::ViewLayer(PointerRNA_NULL));
static SessionParams get_session_params(BL::RenderEngine &b_engine,
BL::Preferences &b_userpref,
BL::Scene &b_scene,
bool background);
static bool get_session_pause(BL::Scene &b_scene, bool background);
static BufferParams get_buffer_params(BL::SpaceView3D &b_v3d,
BL::RegionView3D &b_rv3d,
Camera *cam,
int width,
int height,
const bool use_denoiser);
static PassType get_pass_type(BL::RenderPass &b_pass);
static int get_denoising_pass(BL::RenderPass &b_pass);
static BufferParams get_buffer_params(
BL::SpaceView3D &b_v3d, BL::RegionView3D &b_rv3d, Camera *cam, int width, int height);
private:
static DenoiseParams get_denoise_params(BL::Scene &b_scene,
@@ -130,7 +119,7 @@ class BlenderSync {
int width,
int height,
void **python_thread_state);
void sync_film(BL::SpaceView3D &b_v3d);
void sync_film(BL::ViewLayer &b_view_layer, BL::SpaceView3D &b_v3d);
void sync_view();
/* Shader */
@@ -151,23 +140,31 @@ class BlenderSync {
TaskPool *geom_task_pool);
void sync_object_motion_init(BL::Object &b_parent, BL::Object &b_ob, Object *object);
void sync_procedural(BL::Object &b_ob, BL::MeshSequenceCacheModifier &b_mesh_cache);
void sync_procedural(BL::Object &b_ob,
BL::MeshSequenceCacheModifier &b_mesh_cache,
bool has_subdivision);
bool sync_object_attributes(BL::DepsgraphObjectInstance &b_instance, Object *object);
/* Volume */
void sync_volume(BL::Object &b_ob, Volume *volume);
void sync_volume(BObjectInfo &b_ob_info, Volume *volume);
/* Mesh */
void sync_mesh(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh);
void sync_mesh_motion(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh, int motion_step);
void sync_mesh(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, Mesh *mesh);
void sync_mesh_motion(BL::Depsgraph b_depsgraph,
BObjectInfo &b_ob_info,
Mesh *mesh,
int motion_step);
/* Hair */
void sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Hair *hair);
void sync_hair_motion(BL::Depsgraph b_depsgraph, BL::Object b_ob, Hair *hair, int motion_step);
void sync_hair(Hair *hair, BL::Object &b_ob, bool motion, int motion_step = 0);
void sync_hair(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, Hair *hair);
void sync_hair_motion(BL::Depsgraph b_depsgraph,
BObjectInfo &b_ob_info,
Hair *hair,
int motion_step);
void sync_hair(Hair *hair, BObjectInfo &b_ob_info, bool motion, int motion_step = 0);
void sync_particle_hair(
Hair *hair, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step = 0);
Hair *hair, BL::Mesh &b_mesh, BObjectInfo &b_ob_info, bool motion, int motion_step = 0);
bool object_has_particle_hair(BL::Object b_ob);
/* Camera */
@@ -176,14 +173,13 @@ class BlenderSync {
/* Geometry */
Geometry *sync_geometry(BL::Depsgraph &b_depsgrpah,
BL::Object &b_ob,
BL::Object &b_ob_instance,
BObjectInfo &b_ob_info,
bool object_updated,
bool use_particle_hair,
TaskPool *task_pool);
void sync_geometry_motion(BL::Depsgraph &b_depsgraph,
BL::Object &b_ob,
BObjectInfo &b_ob_info,
Object *object,
float motion_time,
bool use_particle_hair,
@@ -192,8 +188,7 @@ class BlenderSync {
/* Light */
void sync_light(BL::Object &b_parent,
int persistent_id[OBJECT_PERSISTENT_ID_SIZE],
BL::Object &b_ob,
BL::Object &b_ob_instance,
BObjectInfo &b_ob_info,
int random_id,
Transform &tfm,
bool *use_portal);
@@ -229,6 +224,7 @@ class BlenderSync {
id_map<ParticleSystemKey, ParticleSystem> particle_system_map;
set<Geometry *> geometry_synced;
set<Geometry *> geometry_motion_synced;
set<Geometry *> geometry_motion_attribute_synced;
set<float> motion_times;
void *world_map;
bool world_recalc;
@@ -237,6 +233,7 @@ class BlenderSync {
Scene *scene;
bool preview;
bool experimental;
bool use_developer_ui;
float dicing_rate;
int max_subdivisions;
@@ -245,7 +242,6 @@ class BlenderSync {
RenderLayerInfo()
: material_override(PointerRNA_NULL),
use_background_shader(true),
use_background_ao(true),
use_surfaces(true),
use_hair(true),
use_volumes(true),
@@ -258,7 +254,6 @@ class BlenderSync {
string name;
BL::Material material_override;
bool use_background_shader;
bool use_background_ao;
bool use_surfaces;
bool use_hair;
bool use_volumes;

View File

@@ -40,6 +40,28 @@ float *BKE_image_get_float_pixels_for_frame(void *image, int frame, int tile);
CCL_NAMESPACE_BEGIN
struct BObjectInfo {
/* Object directly provided by the depsgraph iterator. This object is only valid during one
* iteration and must not be accessed afterwards. Transforms and visibility should be checked on
* this object. */
BL::Object iter_object;
/* This object remains alive even after the object iterator is done. It corresponds to one
* original object. It is the object that owns the object data below. */
BL::Object real_object;
/* The object-data referenced by the iter object. This is still valid after the depsgraph
* iterator is done. It might have a different type compared to real_object.data(). */
BL::ID object_data;
/* True when the current geometry is the data of the referenced object. False when it is a
* geometry instance that does not have a 1-to-1 relationship with an object. */
bool is_real_object_data() const
{
return const_cast<BL::Object &>(real_object).data() == object_data;
}
};
typedef BL::ShaderNodeAttribute::attribute_type_enum BlenderAttributeType;
BlenderAttributeType blender_attribute_name_split_type(ustring name, string *r_real_name);
@@ -47,7 +69,7 @@ void python_thread_state_save(void **python_thread_state);
void python_thread_state_restore(void **python_thread_state);
static inline BL::Mesh object_to_mesh(BL::BlendData & /*data*/,
BL::Object &object,
BObjectInfo &b_ob_info,
BL::Depsgraph & /*depsgraph*/,
bool /*calc_undeformed*/,
Mesh::SubdivisionType subdivision_type)
@@ -68,23 +90,27 @@ static inline BL::Mesh object_to_mesh(BL::BlendData & /*data*/,
}
#endif
BL::Mesh mesh(PointerRNA_NULL);
if (object.type() == BL::Object::type_MESH) {
/* TODO: calc_undeformed is not used. */
mesh = BL::Mesh(object.data());
BL::Mesh mesh = (b_ob_info.object_data.is_a(&RNA_Mesh)) ? BL::Mesh(b_ob_info.object_data) :
BL::Mesh(PointerRNA_NULL);
/* Make a copy to split faces if we use autosmooth, otherwise not needed.
* Also in edit mode do we need to make a copy, to ensure data layers like
* UV are not empty. */
if (mesh.is_editmode() ||
(mesh.use_auto_smooth() && subdivision_type == Mesh::SUBDIVISION_NONE)) {
if (b_ob_info.is_real_object_data()) {
if (mesh) {
/* Make a copy to split faces if we use autosmooth, otherwise not needed.
* Also in edit mode do we need to make a copy, to ensure data layers like
* UV are not empty. */
if (mesh.is_editmode() ||
(mesh.use_auto_smooth() && subdivision_type == Mesh::SUBDIVISION_NONE)) {
BL::Depsgraph depsgraph(PointerRNA_NULL);
mesh = b_ob_info.real_object.to_mesh(false, depsgraph);
}
}
else {
BL::Depsgraph depsgraph(PointerRNA_NULL);
mesh = object.to_mesh(false, depsgraph);
mesh = b_ob_info.real_object.to_mesh(false, depsgraph);
}
}
else {
BL::Depsgraph depsgraph(PointerRNA_NULL);
mesh = object.to_mesh(false, depsgraph);
/* TODO: what to do about non-mesh geometry instances? */
}
#if 0
@@ -108,10 +134,14 @@ static inline BL::Mesh object_to_mesh(BL::BlendData & /*data*/,
}
static inline void free_object_to_mesh(BL::BlendData & /*data*/,
BL::Object &object,
BObjectInfo &b_ob_info,
BL::Mesh &mesh)
{
if (!b_ob_info.is_real_object_data()) {
return;
}
/* Free mesh if we didn't just use the existing one. */
BL::Object object = b_ob_info.real_object;
if (object.data().ptr.data != mesh.ptr.data) {
object.to_mesh_clear();
}
@@ -141,12 +171,11 @@ static inline void curvemap_minmax_curve(/*const*/ BL::CurveMap &curve, float *m
}
static inline void curvemapping_minmax(/*const*/ BL::CurveMapping &cumap,
bool rgb_curve,
int num_curves,
float *min_x,
float *max_x)
{
// const int num_curves = cumap.curves.length(); /* Gives linking error so far. */
const int num_curves = rgb_curve ? 4 : 3;
*min_x = FLT_MAX;
*max_x = -FLT_MAX;
for (int i = 0; i < num_curves; ++i) {
@@ -166,6 +195,28 @@ static inline void curvemapping_to_array(BL::CurveMapping &cumap, array<float> &
}
}
static inline void curvemapping_float_to_array(BL::CurveMapping &cumap,
array<float> &data,
int size)
{
float min = 0.0f, max = 1.0f;
curvemapping_minmax(cumap, 1, &min, &max);
const float range = max - min;
cumap.update();
BL::CurveMap map = cumap.curves[0];
data.resize(size);
for (int i = 0; i < size; i++) {
float t = min + (float)i / (float)(size - 1) * range;
data[i] = cumap.evaluate(map, t);
}
}
static inline void curvemapping_color_to_array(BL::CurveMapping &cumap,
array<float3> &data,
int size,
@@ -184,7 +235,8 @@ static inline void curvemapping_color_to_array(BL::CurveMapping &cumap,
*
* There might be some better estimations here tho.
*/
curvemapping_minmax(cumap, rgb_curve, &min_x, &max_x);
const int num_curves = rgb_curve ? 4 : 3;
curvemapping_minmax(cumap, num_curves, &min_x, &max_x);
const float range_x = max_x - min_x;
@@ -219,9 +271,13 @@ static inline bool BKE_object_is_modified(BL::Object &self, BL::Scene &scene, bo
return self.is_modified(scene, (preview) ? (1 << 0) : (1 << 1)) ? true : false;
}
static inline bool BKE_object_is_deform_modified(BL::Object &self, BL::Scene &scene, bool preview)
static inline bool BKE_object_is_deform_modified(BObjectInfo &self, BL::Scene &scene, bool preview)
{
return self.is_deform_modified(scene, (preview) ? (1 << 0) : (1 << 1)) ? true : false;
if (!self.is_real_object_data()) {
return false;
}
return self.real_object.is_deform_modified(scene, (preview) ? (1 << 0) : (1 << 1)) ? true :
false;
}
static inline int render_resolution_x(BL::RenderSettings &b_render)
@@ -424,7 +480,7 @@ static inline void set_enum(PointerRNA &ptr, const char *name, const string &ide
static inline string get_string(PointerRNA &ptr, const char *name)
{
char cstrbuf[1024];
char *cstr = RNA_string_get_alloc(&ptr, name, cstrbuf, sizeof(cstrbuf));
char *cstr = RNA_string_get_alloc(&ptr, name, cstrbuf, sizeof(cstrbuf), NULL);
string str(cstr);
if (cstr != cstrbuf)
MEM_freeN(cstr);
@@ -540,22 +596,6 @@ static inline bool object_use_deform_motion(BL::Object &b_parent, BL::Object &b_
return use_deform_motion;
}
static inline BL::FluidDomainSettings object_fluid_liquid_domain_find(BL::Object &b_ob)
{
for (BL::Modifier &b_mod : b_ob.modifiers) {
if (b_mod.is_a(&RNA_FluidModifier)) {
BL::FluidModifier b_mmd(b_mod);
if (b_mmd.fluid_type() == BL::FluidModifier::fluid_type_DOMAIN &&
b_mmd.domain_settings().domain_type() == BL::FluidDomainSettings::domain_type_LIQUID) {
return b_mmd.domain_settings();
}
}
}
return BL::FluidDomainSettings(PointerRNA_NULL);
}
static inline BL::FluidDomainSettings object_fluid_gas_domain_find(BL::Object &b_ob)
{
for (BL::Modifier &b_mod : b_ob.modifiers) {
@@ -573,20 +613,13 @@ static inline BL::FluidDomainSettings object_fluid_gas_domain_find(BL::Object &b
}
static inline BL::MeshSequenceCacheModifier object_mesh_cache_find(BL::Object &b_ob,
bool check_velocity)
bool *has_subdivision_modifier)
{
for (int i = b_ob.modifiers.length() - 1; i >= 0; --i) {
BL::Modifier b_mod = b_ob.modifiers[i];
if (b_mod.type() == BL::Modifier::type_MESH_SEQUENCE_CACHE) {
BL::MeshSequenceCacheModifier mesh_cache = BL::MeshSequenceCacheModifier(b_mod);
if (check_velocity) {
if (!MeshSequenceCacheModifier_has_velocity_get(&mesh_cache.ptr)) {
return BL::MeshSequenceCacheModifier(PointerRNA_NULL);
}
}
return mesh_cache;
}
@@ -595,6 +628,13 @@ static inline BL::MeshSequenceCacheModifier object_mesh_cache_find(BL::Object &b
continue;
}
if (b_mod.type() == BL::Modifier::type_SUBSURF) {
if (has_subdivision_modifier) {
*has_subdivision_modifier = true;
}
continue;
}
break;
}

View File

@@ -17,6 +17,8 @@
#include "blender_viewport.h"
#include "blender_util.h"
#include "render/pass.h"
#include "util/util_logging.h"
CCL_NAMESPACE_BEGIN
@@ -26,11 +28,12 @@ BlenderViewportParameters::BlenderViewportParameters()
studiolight_rotate_z(0.0f),
studiolight_intensity(1.0f),
studiolight_background_alpha(1.0f),
display_pass(PASS_COMBINED)
display_pass(PASS_COMBINED),
show_active_pixels(false)
{
}
BlenderViewportParameters::BlenderViewportParameters(BL::SpaceView3D &b_v3d)
BlenderViewportParameters::BlenderViewportParameters(BL::SpaceView3D &b_v3d, bool use_developer_ui)
: BlenderViewportParameters()
{
if (!b_v3d) {
@@ -55,7 +58,25 @@ BlenderViewportParameters::BlenderViewportParameters(BL::SpaceView3D &b_v3d)
}
/* Film. */
display_pass = (PassType)get_enum(cshading, "render_pass", -1, -1);
/* Lookup display pass based on the enum identifier.
* This is because integer values of python enum are not aligned with the passes definition in
* the kernel. */
display_pass = PASS_COMBINED;
const string display_pass_identifier = get_enum_identifier(cshading, "render_pass");
if (!display_pass_identifier.empty()) {
const ustring pass_type_identifier(string_to_lower(display_pass_identifier));
const NodeEnum *pass_type_enum = Pass::get_type_enum();
if (pass_type_enum->exists(pass_type_identifier)) {
display_pass = static_cast<PassType>((*pass_type_enum)[pass_type_identifier]);
}
}
if (use_developer_ui) {
show_active_pixels = get_boolean(cshading, "show_active_pixels");
}
}
bool BlenderViewportParameters::shader_modified(const BlenderViewportParameters &other) const
@@ -69,7 +90,7 @@ bool BlenderViewportParameters::shader_modified(const BlenderViewportParameters
bool BlenderViewportParameters::film_modified(const BlenderViewportParameters &other) const
{
return display_pass != other.display_pass;
return display_pass != other.display_pass || show_active_pixels != other.show_active_pixels;
}
bool BlenderViewportParameters::modified(const BlenderViewportParameters &other) const
@@ -82,18 +103,4 @@ bool BlenderViewportParameters::use_custom_shader() const
return !(use_scene_world && use_scene_lights);
}
PassType update_viewport_display_passes(BL::SpaceView3D &b_v3d, vector<Pass> &passes)
{
if (b_v3d) {
const BlenderViewportParameters viewport_parameters(b_v3d);
const PassType display_pass = viewport_parameters.display_pass;
passes.clear();
Pass::add(display_pass, passes);
return display_pass;
}
return PASS_NONE;
}
CCL_NAMESPACE_END

View File

@@ -39,9 +39,10 @@ class BlenderViewportParameters {
/* Film. */
PassType display_pass;
bool show_active_pixels;
BlenderViewportParameters();
explicit BlenderViewportParameters(BL::SpaceView3D &b_v3d);
BlenderViewportParameters(BL::SpaceView3D &b_v3d, bool use_developer_ui);
/* Check whether any of shading related settings are different from the given parameters. */
bool shader_modified(const BlenderViewportParameters &other) const;
@@ -57,8 +58,6 @@ class BlenderViewportParameters {
bool use_custom_shader() const;
};
PassType update_viewport_display_passes(BL::SpaceView3D &b_v3d, vector<Pass> &passes);
CCL_NAMESPACE_END
#endif

View File

@@ -181,9 +181,12 @@ class BlenderSmokeLoader : public ImageLoader {
AttributeStandard attribute;
};
static void sync_smoke_volume(Scene *scene, BL::Object &b_ob, Volume *volume, float frame)
static void sync_smoke_volume(Scene *scene, BObjectInfo &b_ob_info, Volume *volume, float frame)
{
BL::FluidDomainSettings b_domain = object_fluid_gas_domain_find(b_ob);
if (!b_ob_info.is_real_object_data()) {
return;
}
BL::FluidDomainSettings b_domain = object_fluid_gas_domain_find(b_ob_info.real_object);
if (!b_domain) {
return;
}
@@ -206,7 +209,7 @@ static void sync_smoke_volume(Scene *scene, BL::Object &b_ob, Volume *volume, fl
Attribute *attr = volume->attributes.add(std);
ImageLoader *loader = new BlenderSmokeLoader(b_ob, std);
ImageLoader *loader = new BlenderSmokeLoader(b_ob_info.real_object, std);
ImageParams params;
params.frame = frame;
@@ -244,11 +247,11 @@ class BlenderVolumeLoader : public VDBImageLoader {
};
static void sync_volume_object(BL::BlendData &b_data,
BL::Object &b_ob,
BObjectInfo &b_ob_info,
Scene *scene,
Volume *volume)
{
BL::Volume b_volume(b_ob.data());
BL::Volume b_volume(b_ob_info.object_data);
b_volume.grids.load(b_data.ptr.data);
BL::VolumeRender b_render(b_volume.render());
@@ -296,19 +299,19 @@ static void sync_volume_object(BL::BlendData &b_data,
}
}
void BlenderSync::sync_volume(BL::Object &b_ob, Volume *volume)
void BlenderSync::sync_volume(BObjectInfo &b_ob_info, Volume *volume)
{
volume->clear(true);
if (view_layer.use_volumes) {
if (b_ob.type() == BL::Object::type_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, scene, volume);
sync_volume_object(b_data, b_ob_info, scene, volume);
}
else {
/* Smoke domain. */
sync_smoke_volume(scene, b_ob, volume, b_scene.frame_current());
sync_smoke_volume(scene, b_ob_info, volume, b_scene.frame_current());
}
}

View File

@@ -832,18 +832,18 @@ BVHNode *BVHBuild::create_leaf_node(const BVHRange &range, const vector<BVHRefer
typedef StackAllocator<256, float2> LeafTimeStackAllocator;
typedef StackAllocator<256, BVHReference> LeafReferenceStackAllocator;
vector<int, LeafStackAllocator> p_type[PRIMITIVE_NUM_TOTAL];
vector<int, LeafStackAllocator> p_index[PRIMITIVE_NUM_TOTAL];
vector<int, LeafStackAllocator> p_object[PRIMITIVE_NUM_TOTAL];
vector<float2, LeafTimeStackAllocator> p_time[PRIMITIVE_NUM_TOTAL];
vector<BVHReference, LeafReferenceStackAllocator> p_ref[PRIMITIVE_NUM_TOTAL];
vector<int, LeafStackAllocator> p_type[PRIMITIVE_NUM];
vector<int, LeafStackAllocator> p_index[PRIMITIVE_NUM];
vector<int, LeafStackAllocator> p_object[PRIMITIVE_NUM];
vector<float2, LeafTimeStackAllocator> p_time[PRIMITIVE_NUM];
vector<BVHReference, LeafReferenceStackAllocator> p_ref[PRIMITIVE_NUM];
/* TODO(sergey): In theory we should be able to store references. */
vector<BVHReference, LeafReferenceStackAllocator> object_references;
uint visibility[PRIMITIVE_NUM_TOTAL] = {0};
uint visibility[PRIMITIVE_NUM] = {0};
/* NOTE: Keep initialization in sync with actual number of primitives. */
BoundBox bounds[PRIMITIVE_NUM_TOTAL] = {
BoundBox bounds[PRIMITIVE_NUM] = {
BoundBox::empty, BoundBox::empty, BoundBox::empty, BoundBox::empty};
int ob_num = 0;
int num_new_prims = 0;
@@ -877,7 +877,7 @@ BVHNode *BVHBuild::create_leaf_node(const BVHRange &range, const vector<BVHRefer
* TODO(sergey): With some pointer trickery we can write directly to the
* destination buffers for the non-spatial split BVH.
*/
BVHNode *leaves[PRIMITIVE_NUM_TOTAL + 1] = {NULL};
BVHNode *leaves[PRIMITIVE_NUM + 1] = {NULL};
int num_leaves = 0;
size_t start_index = 0;
vector<int, LeafStackAllocator> local_prim_type, local_prim_index, local_prim_object;
@@ -888,7 +888,7 @@ BVHNode *BVHBuild::create_leaf_node(const BVHRange &range, const vector<BVHRefer
if (need_prim_time) {
local_prim_time.resize(num_new_prims);
}
for (int i = 0; i < PRIMITIVE_NUM_TOTAL; ++i) {
for (int i = 0; i < PRIMITIVE_NUM; ++i) {
int num = (int)p_type[i].size();
if (num != 0) {
assert(p_type[i].size() == p_index[i].size());

View File

@@ -37,10 +37,10 @@
/* Kernel includes are necessary so that the filter function for Embree can access the packed BVH.
*/
# include "kernel/bvh/bvh_embree.h"
# include "kernel/kernel_compat_cpu.h"
# include "kernel/kernel_globals.h"
# include "kernel/bvh/bvh_util.h"
# include "kernel/device/cpu/compat.h"
# include "kernel/device/cpu/globals.h"
# include "kernel/kernel_random.h"
# include "kernel/split/kernel_split_data_types.h"
# include "render/hair.h"
# include "render/mesh.h"
@@ -73,46 +73,69 @@ static void rtc_filter_occluded_func(const RTCFilterFunctionNArguments *args)
const RTCRay *ray = (RTCRay *)args->ray;
RTCHit *hit = (RTCHit *)args->hit;
CCLIntersectContext *ctx = ((IntersectContext *)args->context)->userRayExt;
KernelGlobals *kg = ctx->kg;
const KernelGlobals *kg = ctx->kg;
switch (ctx->type) {
case CCLIntersectContext::RAY_SHADOW_ALL: {
/* Append the intersection to the end of the array. */
if (ctx->num_hits < ctx->max_hits) {
Intersection current_isect;
kernel_embree_convert_hit(kg, ray, hit, &current_isect);
for (size_t i = 0; i < ctx->max_hits; ++i) {
Intersection current_isect;
kernel_embree_convert_hit(kg, ray, hit, &current_isect);
/* If no transparent shadows, all light is blocked. */
const int flags = intersection_get_shader_flags(kg, &current_isect);
if (!(flags & (SD_HAS_TRANSPARENT_SHADOW)) || ctx->max_hits == 0) {
ctx->opaque_hit = true;
return;
}
/* Test if we need to record this transparent intersection. */
if (ctx->num_hits < ctx->max_hits || ray->tfar < ctx->max_t) {
/* Skip already recorded intersections. */
int num_recorded_hits = min(ctx->num_hits, ctx->max_hits);
for (int i = 0; i < num_recorded_hits; ++i) {
if (current_isect.object == ctx->isect_s[i].object &&
current_isect.prim == ctx->isect_s[i].prim && current_isect.t == ctx->isect_s[i].t) {
/* This intersection was already recorded, skip it. */
*args->valid = 0;
break;
return;
}
}
Intersection *isect = &ctx->isect_s[ctx->num_hits];
++ctx->num_hits;
*isect = current_isect;
int prim = kernel_tex_fetch(__prim_index, isect->prim);
int shader = 0;
if (kernel_tex_fetch(__prim_type, isect->prim) & PRIMITIVE_ALL_TRIANGLE) {
shader = kernel_tex_fetch(__tri_shader, prim);
}
else {
float4 str = kernel_tex_fetch(__curves, prim);
shader = __float_as_int(str.z);
}
int flag = kernel_tex_fetch(__shaders, shader & SHADER_MASK).flags;
/* If no transparent shadows, all light is blocked. */
if (flag & (SD_HAS_TRANSPARENT_SHADOW)) {
/* This tells Embree to continue tracing. */
*args->valid = 0;
/* If maximum number of hits was reached, replace the intersection with the
* highest distance. We want to find the N closest intersections. */
int isect_index = num_recorded_hits;
if (num_recorded_hits + 1 >= ctx->max_hits) {
float max_t = ctx->isect_s[0].t;
int max_recorded_hit = 0;
for (int i = 1; i < num_recorded_hits; ++i) {
if (ctx->isect_s[i].t > max_t) {
max_recorded_hit = i;
max_t = ctx->isect_s[i].t;
}
}
if (num_recorded_hits >= ctx->max_hits) {
isect_index = max_recorded_hit;
}
/* Limit the ray distance and stop counting hits beyond this.
* TODO: is there some way we can tell Embree to stop intersecting beyond
* this distance when max number of hits is reached?. Or maybe it will
* become irrelevant if we make max_hits a very high number on the CPU. */
ctx->max_t = max(current_isect.t, max_t);
}
ctx->isect_s[isect_index] = current_isect;
}
else {
/* Increase the number of hits beyond ray.max_hits
* so that the caller can detect this as opaque. */
++ctx->num_hits;
}
/* Always increase the number of hits, even beyond ray.max_hits so that
* the caller can detect this as and consider it opaque, or trace another
* ray. */
++ctx->num_hits;
/* This tells Embree to continue tracing. */
*args->valid = 0;
break;
}
case CCLIntersectContext::RAY_LOCAL:
@@ -190,7 +213,7 @@ static void rtc_filter_occluded_func(const RTCFilterFunctionNArguments *args)
if (ctx->num_hits < ctx->max_hits) {
Intersection current_isect;
kernel_embree_convert_hit(kg, ray, hit, &current_isect);
for (size_t i = 0; i < ctx->max_hits; ++i) {
for (size_t i = 0; i < ctx->num_hits; ++i) {
if (current_isect.object == ctx->isect_s[i].object &&
current_isect.prim == ctx->isect_s[i].prim && current_isect.t == ctx->isect_s[i].t) {
/* This intersection was already recorded, skip it. */
@@ -329,7 +352,7 @@ void BVHEmbree::build(Progress &progress, Stats *stats, RTCDevice rtc_device_)
scene = NULL;
}
const bool dynamic = params.bvh_type == SceneParams::BVH_DYNAMIC;
const bool dynamic = params.bvh_type == BVH_TYPE_DYNAMIC;
scene = rtcNewScene(rtc_device);
const RTCSceneFlags scene_flags = (dynamic ? RTC_SCENE_FLAG_DYNAMIC : RTC_SCENE_FLAG_NONE) |

View File

@@ -31,6 +31,27 @@ CCL_NAMESPACE_BEGIN
*/
typedef KernelBVHLayout BVHLayout;
/* Type of BVH, in terms whether it is supported dynamic updates of meshes
* or whether modifying geometry requires full BVH rebuild.
*/
enum BVHType {
/* BVH supports dynamic updates of geometry.
*
* Faster for updating BVH tree when doing modifications in viewport,
* but slower for rendering.
*/
BVH_TYPE_DYNAMIC = 0,
/* BVH tree is calculated for specific scene, updates in geometry
* requires full tree rebuild.
*
* Slower to update BVH tree when modifying objects in viewport, also
* slower to build final BVH tree but gives best possible render speed.
*/
BVH_TYPE_STATIC = 1,
BVH_NUM_TYPES,
};
/* Names bitflag type to denote which BVH layouts are supported by
* particular area.
*

View File

@@ -287,9 +287,6 @@ if(CYCLES_STANDALONE_REPOSITORY)
endif()
set(__boost_packages filesystem regex system thread date_time)
if(WITH_CYCLES_NETWORK)
list(APPEND __boost_packages serialization)
endif()
if(WITH_CYCLES_OSL)
list(APPEND __boost_packages wave)
endif()
@@ -535,4 +532,13 @@ if(WITH_CYCLES_CUDA_BINARIES OR NOT WITH_CUDA_DYNLOAD)
endif()
endif()
###########################################################################
# HIP
###########################################################################
if(NOT WITH_HIP_DYNLOAD)
set(WITH_HIP_DYNLOAD ON)
endif()
unset(_cycles_lib_dir)

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