Animation: Graph Editor - Don't draw curve points if they are too close to each other #110788
No reviewers
Labels
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
4 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#110788
Loading…
Reference in New Issue
No description provided.
Delete Branch "ChrisLend/blender:graph_reduced_key_drawing"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
When viewing a curve with a lot of keys totally zoomed out,
the keys might be closer to each other than a pixel.
The code would still draw a line between them,
costing time in the draw code.
This PR skips any keys that are too close to each other in screen space.
Performance
The setup: 62 bones with 6000f of animation keyed on every frame. No keys displayed, just the curves.
So a small performance penalty when zoomed in in exchange for a big gain when zoomed out.
Visuals
There is a small change in visuals when zoomed out a lot. Because this change averages keys that are too close together, it results in a small loss of high frequency detail. If you look closely in the video you can see the detail appearing when the view is zoomed in.
The logic
If
prevbezt
andbezt
are too close it will not draw, but extend a bounding box withprevbezt
andbezt
including handles if needed.Eventually the keys will be far enough apart to draw. At this point, draw the center of the bounding box and reset it.
Now because there could be the case where
bezt
in the current loop is super far out (e.g 5 keys with 1f spacing and the 6th key is at f1000) we need to recalculate the bounding box again. In case the keys are far away, just draw normally. If it is close still, the same process repeats.I think that such an optimization should be carried out and for dopesheet. it seems to me that in the simplest test by baking keys up to 4000 frames, it will help
@sanek122005 yes the dope sheet needs to be optimized, but it's not the drawing that is the issue. I ran a profiler on it and the bottleneck (95% the time spent) is the building of keylists. That is the datastructure that is used to draw and select keys. That is a bit harder to optimize though.
WIP: Animation: Graph Editor - Don't draw keys if they are too close to each otherto Animation: Graph Editor - Don't draw keys if they are too close to each otherThe idea here is great, but I think to make it reliable it needs to work a little differently. Details in my comment below.
@ -1023,0 +1024,4 @@
static float calculate_pixel_distance(BezTriple *a, BezTriple *b, blender::float2 pixels_per_unit)
{
return ((b->vec[1][0] - a->vec[1][0]) * pixels_per_unit[0]) +
I think this is another case where we're going to want to take into account the handles. Because although the keys may be within a pixel, their handles can potentially extend high up or high down, making the curve between those two keys something we would want to make sure to draw.
Or in other words, the units of data we should be working with here aren't keys, but the curve segments formed by two keys:
I think the over-all algorithm we want here is to maintain a bounding box that gets grown with each segment, and then just before the bounding box exceeds the size threshold in either dimension, we draw a curve formed from the first and last keys that went into that bounding box. And then we start again, beginning with the segment that was going to make the bounding box exceed the threshold.
@nathanvegdahl I changed the code to include the handles of bezier keys
I need to rerun the performance test though since this added a few calculations that need to run on every key.
good news
the change only cost about 2μs
@ -1065,0 +1089,4 @@
first_key->vec[1][0], first_key->vec[1][1], first_key->vec[1][0], first_key->vec[1][1]};
/* Used when skipping keys. */
bool has_skipped_keys = false;
const float min_pixel_distance = 3.0f;
What is the rationale for this constant? Intuitively I would expect it to be something like 1.0 or 1.5, to only merge sub-pixel details.
This basically looks ready to land to me. Just curious about that one constant.
I found this to be a reasonable value during testing. It's a tradeoff between accuracy and performance, but if you look at the video and compare the pictures there is almost no difference at a value of 3
In a future patch I plan to move a few constants to user preferences, this is one of them. It gives the user control over performance/fidelity
Looks good to me!
Animation: Graph Editor - Don't draw keys if they are too close to each otherto Animation: Graph Editor - Don't draw curve points if they are too close to each otherrenamed the PR because I realized it is a bit confusing
it's not about keyframes but curve points
LGTM, just tiny remarks that can be handled when landing.
@ -1022,6 +1022,28 @@ static blender::float2 calculate_pixels_per_unit(View2D *v2d)
return pixels_per_unit;
}
static float calculate_pixel_distance(rctf &bounds, blender::float2 pixels_per_unit)
The parameters aren't modified, so can be
const
.@ -1025,0 +1028,4 @@
BLI_rctf_size_y(&bounds) * pixels_per_unit[1];
}
static void expand_key_bounds(BezTriple *left_key, BezTriple *right_key, rctf &bounds)
The input beztriples aren't modified, so should be
const
.