Keyframe_points not set in right place #83051

Closed
opened 2020-11-26 14:01:31 +01:00 by burger@wiredworks.com · 12 comments

System Information
Operating system: Windows-7-6.1.7601-SP1 64 Bits
Graphics card: Quadro K2000/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 385.69

Blender Version
Broken: version: 2.83.4, branch: master, commit date: 2020-08-05 06:00, hash: c113af8288
Worked: (newest version of Blender that worked as expected)

Short description of error

Point not set at specified Coordinate

Exact steps for others to reproduce the error
Default startup with Cube

A simple script not setting the keyframe_points to the specified coordinates

import bpy

Dataobject = bpy.data.objects['Cube']
Dataobject['Jrk'] = 0

fcurve = Dataobject.driver_add('["Jrk"]')
- THX to Philipp Oeser (lichtwerk)
- to edit the driver fcurve with keyframes, you'll have to remove the fmodifier
try:
    fcurve.modifiers.remove(fcurve.modifiers[0])
except IndexError:
     pass
 
fcurve.keyframe_points.insert(0,0)
fcurve.keyframe_points.insert(0.01,1)
fcurve.keyframe_points.insert(0.02,1)
fcurve.keyframe_points.insert(0.03,0)

for i in range(0, len(fcurve.keyframe_points)):
    try:
        fcurve.keyframe_points[i].handle_left  = (fcurve.keyframe_points[i].co[0],fcurve.keyframe_points[i].co[1])
        fcurve.keyframe_points[i].handle_right = (fcurve.keyframe_points[i].co[0],fcurve.keyframe_points[i].co[1])  
    except IndexError:
        pass

keyframe3.png

With slightly larger values it works

import bpy

Dataobject = bpy.data.objects['Cube']
Dataobject['Jrk'] = 0

fcurve = Dataobject.driver_add('["Jrk"]')
- THX to Philipp Oeser (lichtwerk)
- to edit the driver fcurve with keyframes, you'll have to remove the fmodifier
try:
    fcurve.modifiers.remove(fcurve.modifiers[0])
except IndexError:
     pass
 
fcurve.keyframe_points.insert(0,0)
fcurve.keyframe_points.insert(0.1,0.1)
fcurve.keyframe_points.insert(0.15,0.1)
fcurve.keyframe_points.insert(0.2,0)

for i in range(0, len(fcurve.keyframe_points)):
    try:
        fcurve.keyframe_points[i].handle_left  = (fcurve.keyframe_points[i].co[0],fcurve.keyframe_points[i].co[1])
        fcurve.keyframe_points[i].handle_right = (fcurve.keyframe_points[i].co[0],fcurve.keyframe_points[i].co[1])  
    except IndexError:
        pass

keyframe4.png

**System Information** Operating system: Windows-7-6.1.7601-SP1 64 Bits Graphics card: Quadro K2000/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 385.69 **Blender Version** Broken: version: 2.83.4, branch: master, commit date: 2020-08-05 06:00, hash: `c113af8288` Worked: (newest version of Blender that worked as expected) **Short description of error** Point not set at specified Coordinate **Exact steps for others to reproduce the error** Default startup with Cube A simple script not setting the keyframe_points to the specified coordinates ``` import bpy Dataobject = bpy.data.objects['Cube'] Dataobject['Jrk'] = 0 fcurve = Dataobject.driver_add('["Jrk"]') - THX to Philipp Oeser (lichtwerk) - to edit the driver fcurve with keyframes, you'll have to remove the fmodifier try: fcurve.modifiers.remove(fcurve.modifiers[0]) except IndexError: pass fcurve.keyframe_points.insert(0,0) fcurve.keyframe_points.insert(0.01,1) fcurve.keyframe_points.insert(0.02,1) fcurve.keyframe_points.insert(0.03,0) for i in range(0, len(fcurve.keyframe_points)): try: fcurve.keyframe_points[i].handle_left = (fcurve.keyframe_points[i].co[0],fcurve.keyframe_points[i].co[1]) fcurve.keyframe_points[i].handle_right = (fcurve.keyframe_points[i].co[0],fcurve.keyframe_points[i].co[1]) except IndexError: pass ``` ![keyframe3.png](https://archive.blender.org/developer/F9380726/keyframe3.png) With slightly larger values it works ``` import bpy Dataobject = bpy.data.objects['Cube'] Dataobject['Jrk'] = 0 fcurve = Dataobject.driver_add('["Jrk"]') - THX to Philipp Oeser (lichtwerk) - to edit the driver fcurve with keyframes, you'll have to remove the fmodifier try: fcurve.modifiers.remove(fcurve.modifiers[0]) except IndexError: pass fcurve.keyframe_points.insert(0,0) fcurve.keyframe_points.insert(0.1,0.1) fcurve.keyframe_points.insert(0.15,0.1) fcurve.keyframe_points.insert(0.2,0) for i in range(0, len(fcurve.keyframe_points)): try: fcurve.keyframe_points[i].handle_left = (fcurve.keyframe_points[i].co[0],fcurve.keyframe_points[i].co[1]) fcurve.keyframe_points[i].handle_right = (fcurve.keyframe_points[i].co[0],fcurve.keyframe_points[i].co[1]) except IndexError: pass ``` ![keyframe4.png](https://archive.blender.org/developer/F9380780/keyframe4.png)

Added subscriber: @martburg

Added subscriber: @martburg

Added subscriber: @rjg

Added subscriber: @rjg

Is this a different issue to #83044?

Is this a different issue to #83044?

Yes, different issue !

More explanation: There seems to be some graininess along the timeline. The Time of Keyframes can not be set with high precision.

Yes, different issue ! More explanation: There seems to be some graininess along the timeline. The Time of Keyframes can not be set with high precision.

Running the script:

import bpy
import numpy as np

Dataobject = bpy.data.objects['Cube']
Dataobject['Jrk'] = 0

fcurve = Dataobject.driver_add('["Jrk"]')
- THX to Philipp Oeser (lichtwerk)
- to edit the driver fcurve with keyframes, you'll have to remove the fmodifier
try:
    fcurve.modifiers.remove(fcurve.modifiers[0])
except IndexError:
     pass

X  = np.linspace(0.001 , 1.001, num = 1000, retstep = False, dtype = np.double)
Y  = np.zeros(1000, dtype = np.double)
          
for i in range(0,len(X)):
    fcurve.keyframe_points.insert( X[i] ,Y[i]+0.001)
    
print(len(X))
print(len(fcurve.keyframe_points))

keyframe6.png

Confirms IMHO that keyframe points have to be spaced 0.01 units apart and have to start at 0, on the X (time axis) and the Y-axis is showing glitches as well

THX
Martin

Running the script: ``` import bpy import numpy as np Dataobject = bpy.data.objects['Cube'] Dataobject['Jrk'] = 0 fcurve = Dataobject.driver_add('["Jrk"]') - THX to Philipp Oeser (lichtwerk) - to edit the driver fcurve with keyframes, you'll have to remove the fmodifier try: fcurve.modifiers.remove(fcurve.modifiers[0]) except IndexError: pass X = np.linspace(0.001 , 1.001, num = 1000, retstep = False, dtype = np.double) Y = np.zeros(1000, dtype = np.double) for i in range(0,len(X)): fcurve.keyframe_points.insert( X[i] ,Y[i]+0.001) print(len(X)) print(len(fcurve.keyframe_points)) ``` ![keyframe6.png](https://archive.blender.org/developer/F9382000/keyframe6.png) Confirms IMHO that keyframe points have to be spaced 0.01 units apart and have to start at 0, on the X (time axis) and the Y-axis is showing glitches as well THX Martin

Added subscriber: @dr.sybren

Added subscriber: @dr.sybren

Changed status from 'Needs Triage' to: 'Needs User Info'

Changed status from 'Needs Triage' to: 'Needs User Info'

The bug report is incomplete, as there is no "Short description of error" filled out. What exactly is the problem?

        fcurve.keyframe_points[i].handle_left  = (fcurve.keyframe_points[i].co[0],fcurve.keyframe_points[i].co[1])
        fcurve.keyframe_points[i].handle_right = (fcurve.keyframe_points[i].co[0],fcurve.keyframe_points[i].co[1])

What is the use of this code? Placing the handles right on top of the keyframe points is not mathematically valid, as then there is no defined slope at that point.

Keyframes are stored with float precision, so there is a numerical limit. This in itself is not a bug.

The bug report is incomplete, as there is no "**Short description of error**" filled out. What exactly is the problem? ``` fcurve.keyframe_points[i].handle_left = (fcurve.keyframe_points[i].co[0],fcurve.keyframe_points[i].co[1]) fcurve.keyframe_points[i].handle_right = (fcurve.keyframe_points[i].co[0],fcurve.keyframe_points[i].co[1]) ``` What is the use of this code? Placing the handles right on top of the keyframe points is not mathematically valid, as then there is no defined slope at that point. Keyframes are stored with `float` precision, so there is a numerical limit. This in itself is not a bug.

OK, simpler script

import bpy

Dataobject = bpy.data.objects['Cube']
Dataobject['Jrk'] = 0

fcurve = Dataobject.driver_add('["Jrk"]')
- THX to Philipp Oeser (lichtwerk)
- to edit the driver fcurve with keyframes, you'll have to remove the fmodifier
try:
    fcurve.modifiers.remove(fcurve.modifiers[0])
except IndexError:
     pass
 
fcurve.keyframe_points.insert(0,0)
fcurve.keyframe_points.insert(0.01,1)
fcurve.keyframe_points.insert(0.02,1)
fcurve.keyframe_points.insert(0.03,0)

print(len(fcurve.keyframe_points))

Keyframe9.png

The Point at (0,0) is not set and the Point at (0.03, 0) is also not set. and (len(fcurve.keyframe_points)) = 2

OK, simpler script ``` import bpy Dataobject = bpy.data.objects['Cube'] Dataobject['Jrk'] = 0 fcurve = Dataobject.driver_add('["Jrk"]') - THX to Philipp Oeser (lichtwerk) - to edit the driver fcurve with keyframes, you'll have to remove the fmodifier try: fcurve.modifiers.remove(fcurve.modifiers[0]) except IndexError: pass fcurve.keyframe_points.insert(0,0) fcurve.keyframe_points.insert(0.01,1) fcurve.keyframe_points.insert(0.02,1) fcurve.keyframe_points.insert(0.03,0) print(len(fcurve.keyframe_points)) ``` ![Keyframe9.png](https://archive.blender.org/developer/F9390695/Keyframe9.png) The Point at (0,0) is not set and the Point at (0.03, 0) is also not set. and (len(fcurve.keyframe_points)) = 2

Changed status from 'Needs User Info' to: 'Archived'

Changed status from 'Needs User Info' to: 'Archived'

You have hit the minimal distance between keyframes. See BEZT_BINARYSEARCH_THRESH as defined in BKE_fcurve.h:

#define BEZT_BINARYSEARCH_THRESH 0.01f

This was introduced 7 years ago (76dd3db304), so it's quite safe to assume that this is how Blender behaves.

What do you need such small numbers for anyway? With this kind of curve, it's probably a better choice to set it for constant interpolation instead:

key = fcurve.keyframe_points.insert(-1, 1)
key.interpolation = 'CONSTANT'

key = fcurve.keyframe_points.insert(0, 0)
key.interpolation = 'CONSTANT'

This will give the same sharp dropoff as your code seems to intend:
image.png

You have hit the minimal distance between keyframes. See `BEZT_BINARYSEARCH_THRESH` as defined in `BKE_fcurve.h`: ``` #define BEZT_BINARYSEARCH_THRESH 0.01f ``` This was introduced 7 years ago (76dd3db304), so it's quite safe to assume that this is how Blender behaves. What do you need such small numbers for anyway? With this kind of curve, it's probably a better choice to set it for constant interpolation instead: ``` key = fcurve.keyframe_points.insert(-1, 1) key.interpolation = 'CONSTANT' key = fcurve.keyframe_points.insert(0, 0) key.interpolation = 'CONSTANT' ``` This will give the same sharp dropoff as your code seems to intend: ![image.png](https://archive.blender.org/developer/F9414061/image.png)

The curve I intend to generate is the Jerk Component of a move

Move1.png

Acceleration, Velocity, and Position are the respective Integrals of that Jerk so being able to use smaller values would be a nice to have.
THX, for looking into the Problem and providing the Location in the source.

I'm not sure about the mathematical validness --- If the fcurves are close to Beziers - setting the control handle points to the same value as the point is valid it just reduces the degree of the Bezier

and I'm also no sure about the formulation of "as then there is no defined slope at that point" we then have a left slope and a right slope and they are coincident with the graph of the linear interpolation

THX
Martin

The curve I intend to generate is the Jerk Component of a move ![Move1.png](https://archive.blender.org/developer/F9414174/Move1.png) Acceleration, Velocity, and Position are the respective Integrals of that Jerk so being able to use smaller values would be a nice to have. THX, for looking into the Problem and providing the Location in the source. I'm not sure about the mathematical validness --- If the fcurves are close to Beziers - setting the control handle points to the same value as the point is valid it just reduces the degree of the Bezier and I'm also no sure about the formulation of "as then there is no defined slope at that point" we then have a left slope and a right slope and they are coincident with the graph of the linear interpolation THX Martin
Sign in to join this conversation.
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
Interest: X11
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
3 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#83051
No description provided.