Should help finding regressions in modifier related UI operations and UI
drawing.
This test:
1. Creates test objects of different types (Mesh, Curve, Grease Pencil,
Lattice, Volume, Armature).
2. Adds all available modifiers to the objects dynamically.
3. Switches the Properties editor to the Modifiers tab for each object
type and redraws.
4. Adds all available constraints to the objects and bones.
5. Switches the Properties editor to the Constraints tab and redraws.
Pull Request: https://projects.blender.org/blender/blender/pulls/161642
This adds functionality to store world space data in a temporary file
on disk and paste it on other objects.
(technically `AnimTransformable`s, which is objects or bones, but for
simplicity I will be talking about "objects" here)
Compared to the existing functionality this can also copy a
range of frames. Because the data is stored on disk, it is possible
to copy and paste between files.
**Matching Logic**
* When 1 object copied and 1 selected -> paste no matter the naming
* When 1 object copied and 2:n selected -> paste the same data to
all selected
* When 2:n objects copied and 1:n selected -> paste based on naming.
It is possible to paste between objects and bones as long
as the name matches.
**Depsgraph**
* Introduces a new API function `DEG_foreach_dependent_component`
* this function iterates the outgoing links starting at a given ID
* it is used to find the order in which to paste world space transforms
since we have to paste in order of dependency -> dependent
for it to work correctly.
**UI**
Adding a new panel because the new operators are not compatible
with the existing ones. I cannot remove the existing operators because
they provide functionality that I don't yet provide.
To make it clear that they don't work together, they get their own panel.
**Limitations**
* objects with constraints may not end up at the correct world space.
That is expected for limit constraints, but additive constraints would
need to be inverse solved which is a job for another day.
* when the rotation mode is animated, pasting world space animation
will override all keys in the baked range to be the value at the
start of the range.
**Performance**
Testing in a file with 10.000 frames of dense keyframe data.
Copying a single bone:
* Copying ~1.6 seconds
* Pasting ~1.6 seconds
Copying 3 bones of the same armature
* Copying ~1.6 seconds
* Pasting ~4.8 seconds
The extra evaluation required when pasting makes this scale with the
amount of bones we are pasting.
Part of #156579
Pull Request: https://projects.blender.org/blender/blender/pulls/159390
Command line overrides now define the default "Trusted Source"
for drop and the file-selector.
This is done so the default matches the behavior of opening
files in contexts where the option to trust source isn't shown.
"Recover Last Session" run without setting "use_scripts"
(from Python for e.g.) now disables auto-execution
unless a command line override is passed in,
as the path being recovered isn't known until the file is read.
This includes a refactor & tests.
Details:
- `bpy.path.is_autoexec(..., skip_overrides=False)`:
Can be used to check if the current environment would trust a file.
- Expose: `bpy.app.autoexec_override`,
set when `--enable-autoexec` & `--disable-autoexec` are passed in.
- `BKE_autoexec_default_trust_source`:
new function to more conveniently access the default trust for a file.
- Show when "Auto Run Python Scripts" preference is overridden.
- Add tests for the file selector, dropping & the command line.
Ref !163894
This adds UI tests for the Info Editor report functionality to improve
automated coverage of report-related operators and settings.
Tests cover report selection/deselection, deletion and operator polling
to ensure Info Editor operators are available in the expected context.
Pull Request: https://projects.blender.org/blender/blender/pulls/161091
Based on the "Stochastic ray tracing of transparent 3D Gaussians" paper
by Xin Sun et. al. The basic idea: perform stochastic intersection with
the Gaussian splat based on its transparency.
Gaussian splats are implemented as a dedicated primitive type, but it
shares the same layout for position and radius as points, so a lot of
existing functions (positions, attributes, etc) work for both points
and splats.
For the Embree and hardware intersection it is implemented as a custom
primitive type.
The choice of using bounding spheres mainly comes from a balance between
performance and memory usage. More ideal would be to use OBB, but it is
not supported for custom primitive types in Embree and GPU HW-RT on all
backends.
There is a known limitation that comes from the fact that the datasets
are trained in sRGB space and Cycles work in Linear space: areas with
low opacity and high radiance render noticeably differently from the
ground-truth implementation.
Ref #159470
Pull Request: https://projects.blender.org/blender/blender/pulls/163103
Open a blend file from a trusted & an excluded directory using the file
selector & the popup shown when dropping a file, checking
bpy.app.autoexec once the file is open.
Dropping can't be simulated yet, so bind the drop operator to a key.
Ref !163785
Command line tests use the arguments overriding the preference, with
relative paths, paths stepping into an excluded directory & globs.
Also tests the code-path for opening blend files from file-associations
on UNIX/WIN32, but macOS's event: GHOST_kEventOpenMainFile.
Ref !163781
test_open_editor_types opens many areas, each requiring its own
GLContext. The maximum number of available contexts is driver
implementation and cannot be queried. We disable the test on OpenGL
platforms.
It is safe to use on Vulkan/Metal as they don't have a context.
Pull Request: https://projects.blender.org/blender/blender/pulls/163736
Adds `context.markers` and `context.selected_markers` to simplify
accessing the markers relevant for the current animcontext.
Uses the context's scene to retrieve the relevant markers,
taking into account the possibility that we're in an Action Editor
with pose markers visible.
Updates the F2 rename operator to use this (although it might later
be updated to operate on the active marker instead).
The new properties intentionally don't query the sequencer scene,
since that might be unexpected or undesired in some situations.
If needed, a context override can be used to access (selected) markers
from another scene:
```py
with context.temp_override(scene=context.sequencer_scene):
return context.markers
```
Adds python tests to retrieve markers from various sources using these
new context properties.
Pull Request: https://projects.blender.org/blender/blender/pulls/162157
The test opens the Preferences window, switches through every value of
``preferences.active_section``, expands dynamic sections like Add-ons,
and yields after each change so the UI can redraw.
This lets us find UI errors in the many navigation sections of the
Preferences.
Pull Request: https://projects.blender.org/blender/blender/pulls/161693
---------
Co-authored-by: Pratik Borhade <25420+pratikpb2123@noreply.localhost>
Tests for Blender's drop handler system across the 3D Viewport, UI,
Scene, Window, and File Browser.
Does not cover OS-level drag and drop. Blender's `EVT_DROP` events are
generated internally by the window manager and cannot be produced
through `event_simulate`. As a result, these tests do not simulate the
complete physical workflow of dragging data from an external application
or the operating system into Blender.
Instead, the tests invoke the registered drop operators directly through
their `exec` or `invoke`-related paths and provide the context and drop
properties that Blender's internal drop handlers would normally supply.
This allows the tests to validate the drop-handler behavior and
resulting state changes while remaining deterministic and independent of
OS-level drag-and-drop support. Where an operator requires
cursor-position information from the actual drop event, the tests are
limited to verifying registration or poll behavior rather than
reproducing the complete interaction.
Pull Request: https://projects.blender.org/blender/blender/pulls/162949
- Add a regression test verifying operator search respects poll() and
only exposes an operator when its poll condition is satisfied.
- Add a poll sweep test that checks registered operators across
supported editor types and verifies poll() always returns a `bool`
without raising exceptions.
- Add a `poll_sweep()` helper that reuses a single area while switching
editor types and runs each operator's `poll()` under the
appropriate window, area, and region context.
Pull Request: https://projects.blender.org/blender/blender/pulls/162764
Editor initialization by dynamically constructing a grid layout,
iterating through all settable editor variants, applying editor-specific
modes/subtypes, and validating successful initialization of each editor
instance.
These tests already proved themselves useful, we already found and fixed
a number of issues during development.
Pull Request: https://projects.blender.org/blender/blender/pulls/158780
The compute-shader based function `update_mipmaps` can generate broken
mipmaps for Intel Arc Windows OpenGL. A workaround for falling back to
`generate_mipmap` is added to mitigate the issue. Furthermore, a render
test is added that catches the issue.
Pull Request: https://projects.blender.org/blender/blender/pulls/162524
Address a long standing limitation with undo: where edit-mode often
prevented edits in other areas from being tracked by undo.
Allows properties in the object/scene to be adjusted while in edit-mode
supporting undo for both edit-mode and global undo steps to co-exist.
Details:
- This works by encoding undo with a "hint"
that the change includes MEMFILE undo changes.
- This hint can be created from property edits -
where we know which kind of property is being edited.
- It can also be calculated before adding a generic undo step,
to check if other data needs a global undo step
(editing a scene or object while in edit-mode for e.g.).
- The undo system checks for this hint and adds a hidden "pre"
MEMFILE undo step in these cases
(the initial MEMFILE undo step is already done at times,
we make use of that).
- Eventually the mode-specific undo step creation can be skipped,
this has been left out as it's a larger change which impacts
each undo system.
- Added tests to support mixing edit-mode mesh and 3d text
with MEMFILE undo.
- When pushing undo steps a check for changes outside
the mode is performed (in parallel, per ID type),
in my own tests the ID scanning overhead is negligible,
even on heavy files.
Resolves: #50423, #75013, #153282.
Ref !161566
Reuse AUDASPACE readers between uncached Sample Sound Frequencies windows
instead of creating a new reader for every window.
Readers are acquired through a small cache associated with the current
`bSound` runtime generation. An RAII lease automatically returns readers after
use, while failed seek or read operations discard potentially invalid readers.
The cache retains at most two idle readers. When all cached readers are in use,
a new reader is created outside the cache lock instead of making concurrent
evaluations wait.
Cached samplers and their reader cache remain alive for evaluations already in
progress when a sound is reloaded or freed.
Entering Edit Mode on a mesh with shape keys could copy the final
mesh component after it had already been shared with the edit cage.
The generic component copy did not preserve all
runtime state required by the Edit Mode BMesh wrapper.
The copied final result was subsequently handled by
`MeshRenderData` through the regular `MeshExtractType::Mesh` path,
as though it were an array-backed mesh.
Viewport extraction then attempted to access mesh arrays that
were not available and asserted in `Mesh::faces()`.
Assign the evaluated shape key before sharing the final mesh
component with either the explicit or fallback cage. In Object Mode,
retrieve the final mesh pointer after potential writable
access so copy-on-write cannot leave a stale pointer.
Also add an undo test that would have caught this regression.
Ref !161986
The Sequencer Compositor modifier UI checked whether the node group had
at least one interface input before accessing the second input used for
the optional mask.
A node group with exactly one input therefore caused an out-of-bounds
access when an ID mask was assigned and the Strip Modifiers panel was
redrawn.
Require at least two interface inputs before validating the mask input.
Pull Request: https://projects.blender.org/blender/blender/pulls/162031
Activates all tools in the 3D view, sequencer, node editor and image
editor. This can help finding regressions in tool activation, drawing
code or other related code.
Note that the sequencer test fails on Windows AMD64 Intel buildbot
workers. This same failure is already present in another test and seems
related to either a driver issue or the GPU module.
Pull Request: https://projects.blender.org/blender/blender/pulls/161585
Add an initial set of Collection import tests, validating what's there
today and leaving room for what will soon be added/fixed.
Of note, the `test_link_after_import` test is disabled since the
recently committed bb67052433 is causing
asserts. Still debugging the root of the problem.
And the `test_import_multi` test is disabled because I'll need to rework
the Library handling to properly account for this case.
Pull Request: https://projects.blender.org/blender/blender/pulls/162252
This adds a `WindowManager::try_activate_rna_button` method for
activating RNA buttons with an specific state (only `Highlight`,
`WaitKeyEvent`,`NumEditing`, `TextEditing` are support by now) and
returns the center point of the button in window coordinates when
successfully activated (or just highlighted). Any other active button
would be deactivated when activating a button.
This also adds tests for text buttons interactions.
Note: `Ctrl + mouse wheel up/down` string value cycling was not tested
since is not supported in side panels.
Pull Request: https://projects.blender.org/blender/blender/pulls/152910
Two simple tests for the dynamics assets. Also replace the specific
simulation test Python code with a test for a specific custom property
on the scene which tells the test code to run through the frame range
before applying modifiers.
Pull Request: https://projects.blender.org/blender/blender/pulls/159118
Particle Edit undo restored its mode by calling
`ED_object_particle_edit_mode_enter_ex()` directly.
When the undo step was decoded while Texture Paint was active, the
previous mode was not exited first. Since Particle Edit mode entry adds
its mode bit with `|=`, the object ended up with the invalid combined
mode `48` (`TEXTURE_PAINT | PARTICLE_EDIT`).
Exit the current mode through its normal lifecycle before restoring
Particle Edit, following the same pattern used by sculpt undo.
Files that were already saved with mode `48` crashed during editor
initialization because `object_mode_op_string()` returned `nullptr`.
Unsupported saved modes are now rejected safely, leaving the object in
Object Mode while preserving its particle and hair data so the file can
be resaved.
Pull Request: https://projects.blender.org/blender/blender/pulls/161542
This adds code to convert animation from one rotation mode to another.
There are multiple ways to do the conversion:
* Using Ctrl+R in pose mode
* In the 3D viewport, open the "Object" or "Pose" menu, under
"Animation" there is a new entry "Convert Rotation Mode"
* Using the python API `convert_rotation_mode()` either on bones or
objects
**Important Behavior**
* The result of the operation is always a fully keyed rotation, even
if previously only a single channel was keyed. This is the only way
to ensure that the rotations line up.
* Interpolation may not match. In fact it is expected not to.
This is desired for animators for when they are running into gimbal
lock and they just want to try if a different rotation mode works better.
* In case interpolation *has to* match, there is an option to insert
keys on every frame before the conversion.
* key types are somewhat preserved. We assume that for any given
frame, all rotation keys are the same type.
* keys on all related actions are converted, that includes the NLA
Even though the animation data conversion could be triggered
automatically by changes to the rotation_mode RNA property, I chose not
to do that for a reason.
This may be set directly via python in an addon and we shouldn't
include the costly (and maybe unexpected) side effect of converting
animation.
This adds a new operator `anim.rotation_mode_convert` instead of
modifying the existing `pose.rotation_mode_set`.
Since the operator now works with objects as well, it's probably better
to move it out of the `pose` category.
`pose.rotation_mode_set` and `pose.convert_rotation` from rigify are
deprecated with a warning that pops up every time you execute them.
**Implementation**
The core of the changes are in `anim_convert.cc`.
* `convert_to_rotation_mode` is a high level function that converts
the rotation for a single transformable.
* `build_rotation_fcurve_map` and `convert_rotation_keys` are two
functions that work in concert. The first builds the data structure
to quickly find FCurves by their RNA path and the second consumes
that data to do the conversion.
* `bake_rotation_fcurves` utility function to bake FCurves before
converting their rotation.
This uses the `AnimTransformable` class to make this functionality
available to objects and bones at the same time.
When dealing with multiple transformables, we would need to iterate
the action for each to find the FCurves for it.
To avoid that I added `ChannelbagFCurveMap` which is created by
`build_rotation_fcurve_map`.
With that we can easily iterate iterate the FCurves of each Channelbag
sorted by RNA path.
`KeyframeIterator`
Is a new helper class to iterate all frames with keys of N FCurves.
**Deprecates** the existing `POSE_OT_convert_rotation` operator and
removes it from the pose menu.
Resolves#149607Resolves#159131
Design: #137281
UI improvements will be handled in a separate PR: !159981
Pull Request: https://projects.blender.org/blender/blender/pulls/154309
Legacy texture evaluation falls back to the active tessface UV layer
when no UV map is explicitly specified.
After active and default UV map state moved to `Mesh`, legacy tessface
conversion still tried to copy the corresponding indices from corner
`CustomData`. This left the generated `CD_MTFACE` layers using index 0,
so textures with an empty UV map name could sample the wrong UV map.
Resolve the active and default UV map names from the mesh when
generating legacy tessface data, restoring the previous implicit
active-UV fallback.
Pull Request: https://projects.blender.org/blender/blender/pulls/161347
When a liquid mesh cache file was missing or failed to load,
`MANTA::readMesh()` returned without clearing mesh data from the
previously loaded frame.
The stale mesh nodes, triangles, and velocities could then be reused as
valid geometry. This made direct frame jumps inconsistently show either
an older liquid surface or the fluid domain bounds, depending on the
previous evaluation state.
Clear the previous mesh data when the requested cache is unavailable or
fails to load, allowing evaluation to correctly fall back to the domain
geometry.
Pull Request: https://projects.blender.org/blender/blender/pulls/161305
These tests validate pie menu interactions triggered through simulated
keyboard + cursor drag events across several editors and modes.
This should help find plenty of regressions as it covers a lot of cases
touching many modules.
Covers pies in the 3D View, Graph Editor, Dope Sheet, Sequencer, NLA,
Image Editor, File Browser, Node Editor and Clip Editor.
Pull Request: https://projects.blender.org/blender/blender/pulls/160761
Unregistered classes could be still referenced in active popups and as
soon they get focused they will likely crash after trying to access
freed data.
This avoid any crash by refreshing any active popup when a class
is unregistered, if the popup can't be refreshed and is referencing
the class to be unregistered it will be closed instead.
Pull Request: https://projects.blender.org/blender/blender/pulls/157524
When strip names were colliding, and the name already had "." in there,
everything after it was stripped and replaced with a number. This does
not follow the behavior of other parts of blender; treat
it as "this is a numeric suffix" if it actually contains a number only.
Pull Request: https://projects.blender.org/blender/blender/pulls/160155
This is for a Bevel Geometry node. The code is a kind of port of the BMesh bevel code in bmesh_bevel.cc, but it needs substantial changes to use Mesh data structures instead of BMesh ones. And therefore, it needs to deal with the fact the the Mesh is not efficiently mutable. The approach is to make an "ExtendibleMesh" that holds data about the original Mesh but also deltas to that mesh to be applied at new Mesh construction time. Many other changes in the code were needed to use ints for Vert, Edge, Face, and Corner instead of pointers to BMesh elements.
In designing the Geometry Node, we made some decisions about some changes to the interface as compared to the BMesh interface to bevel. These were discussed in issue #98674. Some of the bigger decisions:
- Offsets are given per edge (4 of them, one for each side of each end) or per vertex (only the first slot is used) depending on whether we are edge beveling or vertex beveling. There is no "offset kind" spec -- you can achieve kinds other than "offset" by calculating outside the node.
- Miters are both simplfied and expanded. There is a boolean per corner called "miter". If it is true, and the given corner is just past a beveled edge, then the gap between that beveled edge and the next will be mitered. It will be in "patch" miter if the angle is reflect and an "arc" miter otherwise.
- So far there is no "clamp" and "loop slide" option. I remain undecided about what to do here. The eventual hope is that "clamp" will go away because I will use a "straight skeleton" algorithm to "eat away" geometry when it starts to overlap. But this won't happen in time for the intitial release. For now, I may implement clamp as "always on", but this isn't yet implemented. Loop slide can be done by calculation of offsets outside the node, but this could be tedious. I may or may not decide to implement loop slide inside the node; if I do, maybe it will be "always on" -- not sure.
- There is an "effect Faces" option in the UI but it isn't hooked up to anything yet. I'll probably disable that for the first release. Eventually I want to have it, as kind of inset operator.
- There is a "profile" input, meant to take a curve, that will be used for custom profiles, but that is not hooked up to anything yet.
- There are output fields, not yet hooked up, which will give selections of various parts of the new beveled mesh, to be used for things like special materials or normal handling. (As a consequence, there will be no hardening code native to this node.)
The state of the code as of this initial WIP is that many things work (with the exceptions noted above re clamping and loop slide and custom profiles). There are about 70 regression tests, ported from the bevel_operator.py tests (with more UV maps). They all "pass" right now but that's just because I made the expected_object match the current code output. I still have to go through them carefully one-by-one to see that they match the current BMesh behavior.
I added reviewers but this isn't really in a state to review yet, unless you are interested.
One thing I intend to do: update all the "old-style" math functions (that use raw float arrays) to "new-style" math functions.
This code was heavily assisted using Claude Sonnet 4.6 in Antigravity. But I have carefully read the output and will continue to do so, and will stand by the code as if it were totally my own (and, since I wrote the original BMesh code, it is in that sense mostly mine anyway).
Co-authored-by: Hans Goudey <hans@blender.org>
Pull Request: https://projects.blender.org/blender/blender/pulls/158151
This PR adds Geometry Nodes modifier support for empties.
One of the motivations of this is to be able to create simulation
effectors (like wind, turbulence, etc.) using Geometry Nodes modifiers.
But this is also useful for fully procedural effects where original
geometry is not needed.
When creating a new node group for the first modifier in the stack,
the input geometry socket is omitted.
The `Object` > `Convert To` and `Visual Geometry to Mesh` operators have
been updated to also work for empty objects.
The overlay for the empty is not drawn when there's a modifier that
outputs geometry.
The python API `GeometrySet.from_evaluated_object` also has been updated
to work with empty objects.
Co-authored-by: Jacques Lucke <jacques@blender.org>
Pull Request: https://projects.blender.org/blender/blender/pulls/157804
Add a unit test to verify that when bones are renamed while joining
armatures, that the channels of corresponding action constraints are
remapped properly.
This is a follow-up to #153391 and #153449, which were tested with
this, but landed before this.
Pull Request: https://projects.blender.org/blender/blender/pulls/153745
After fixing a bunch of issues over the years,
the render tests failure threshold it too high and
let valid errors become undetected.
Divide the fail threshold by 10 in most cases
and by 2 in worst cases.
This reduces the threshold to a very low number since
most EEVEE renders have a low amount of noise.
Some tests are updated to reduce platform differences.
This unveiled quite a few issues that will be fixed
in main later on (see blocklist edits).
Test refinement:
- 🟩 NVidia Opengl (reference)
- 🟩 AMD Opengl
- 🟩 AMD Vulkan
- 🟩 Intel Opengl
- 🟩 Metal
Pull Request: https://projects.blender.org/blender/blender/pulls/158810
This commit adds support to the autosave functionality to handle images
and allows autosave to work in Texture paint.
This requires two main changes:
* Packing all edited & editable images.
* Allow autosave to function when the most recent step is an image undo
step.
The majority of this PR addresses the first change.
For all images that are to be autosaved, we pack to a new field on the
`Image`, `autosave_packedfiles` and mark the datablock with a new flag,
`IMA_AUTOSAVE_TEMPPACK`.
This field is used to prepopulate the `Image` datablock runtime cache
on file load, which then marks the ImBuf as dirty, so the user will be
informed to either save or discard changes.
If an image is saved, packed, or reloaded, the autosave information
(both the flag and the autosave packed file list) is cleared.
Additionally, the autosave information is cleared when the cache is
populated when loading the file.
As a similar area of concern, we also do this when creating the recovery
file, `quit.blend`
Part of #134518
Pull Request: https://projects.blender.org/blender/blender/pulls/152453
Compile time here can be long, run bake tests that require shader
ray-tracing separately so that these heavy kernels are compiled
separate from the others and each category fits within the timeout.
Pull Request: https://projects.blender.org/blender/blender/pulls/158770
This adds back lightprobe plane support for Blended Material
and Shader to RGB evaluation.
This adds a parallax property on the Lightprobe Planes to tweak
the amount of (non-physical) distortion caused by normals.
Unlike legacy EEVEE (4.1) this implementation does not do any
raytracing even if raytracing is enabled in the render options.
Instead, it uses the same heuristic when raytracing was disabled
in 4.1. However, it now uses the new parallax amount from the
planar lightprobe property.
The heuristic fades out reflections if the normal differs from
the reflection direction or if roughness is not small.
To avoid big regression in compile time, the sampling of the
planar probe is done only once for all the BSDFs and using the
average normal.
Fix#135198
Pull Request: https://projects.blender.org/blender/blender/pulls/158483
Run the doc generator and stub generator with stub validation.
This helps ensure the doc-strings follow stricter conventions,
and should help avoid errors in the future.
Ref !158397
This patch adds support for Rotation sockets as well as existing nodes
from Geometry Nodes. This includes the Rotate Vector, Invert Rotation,
Rotation to Euler, Euler to Rotation, Rotate Rotation, Rotation to Axis
Angle, Axis Angle to Rotation, Mix Rotation, Rotation to Quaternion,
Quaternion to Rotation, Align Rotation to Vector, and Axes to Rotation
nodes.
Pull Request: https://projects.blender.org/blender/blender/pulls/154845