Creating a Keyframe similar to Ctrl-Clicking the Curve
-
Hello,
When in the Timeline, if I hold Ctrl/Cmd and click on the curve, Cinema 4D adds a keyframe that matches the contour of the curve perfectly.
The tangents of the new key and neighboring keys are properly weighted.
When I try to do this with the code below, I get a keyframe whose angles do not match the curve and where the Left & Right times of the neighboring keys are not adjusted.
keyDict = keyCurve.AddKey(keyTime) keyIndex = keyDict["nidx"] key = keyDict["key"] key.SetValue(keyCurve,value) key[c4d.ID_CKEY_PRESET] = c4d.ID_CKEY_PRESET_NEWAUTOWEIGHTED
Result:
The tangents of the key seem to be weighted properly using
ID_CKEY_PRESET_NEWAUTOWEIGHTED
, but how can I get the angle of the tangents to match the curve and the Left & Right Time of the neighboring keys to adjust so the curve's contour doesn't change as in the Ctrl-Click key creation scenario?Thank you!
-
Hi @blastframe,
thank you for reaching out to us. One built in solution you could use is
CCurve.AddKeyAdaptTangent()
instead ofCCurve.AddKey()
. It will allow you to insert a smoothly interpolated key between two other keys and the result will look something like the attached image. I also attached a modified githubctrack_create_keys_r13.py
example at the end. You only have to read the snip parts, everything else is unchanged.I hope this helps, if not, I would have to ask you to restate your goals.
Cheers,
Ferdinand""" Copyright: MAXON Computer GmbH Author: Manuel MAGALHAES Description: - Creates position Y tracks. - Adds two keyframes. - Sets their value and interpolation. Class/method highlighted: - CKey.SetInterpolation() - CKey.SetKeyDefault() Compatible: - Win / Mac - R13, R14 R15, R16, R17, R18, R19, R20, R21, S22, R23 """ import c4d def CreateKey(curve, time, value, interpolation): """ Creates a Key on the given curve at the given time with a given value and with the given interpolation. :param curve: The Curve where to add the keyframe. :type curve: c4d.CCurve :param time: The time of the keyframe. :type time: c4d.BaseTime :param value: The value of the keyframe. :type value: float :param interpolation: The interpolation of the key along the curve. :type interpolation: c4d.CINTERPOLATION_XXX :return: They key and the index of the key in the CCurve. :rtype: tuple(c4d.Ckey, int) :raise MemoryError: If for some reason, it was not possible to create the key. """ # Adds the key keyDict = curve.AddKey(time) # Checks if the key have been added if keyDict is None: raise MemoryError("Failed to create a key") # Retrieves the inserted key key = keyDict["key"] keyIndex = keyDict["nidx"] # Sets the value of the key key.SetValue(curve, value) # Mandatory: Fill the key with default settings curve.SetKeyDefault(doc, keyIndex) # Changes it's interpolation key.SetInterpolation(curve, interpolation) return key, keyIndex def main(): # Creates the object in memory obj = c4d.BaseObject(c4d.Ocube) # Creates the track in memory. Defined by it's DescID trackY = c4d.CTrack(obj, c4d.DescID(c4d.DescLevel(c4d.ID_BASEOBJECT_POSITION, c4d.DTYPE_VECTOR, 0), c4d.DescLevel(c4d.VECTOR_Y, c4d.DTYPE_REAL, 0))) # Gets curves for the track curveY = trackY.GetCurve() # Creates a key in the Y curve with value 0 at 0 frame with a spline interpolation keyA, keyAIndex = CreateKey(curveY, c4d.BaseTime(0), value=0, interpolation=c4d.CINTERPOLATION_SPLINE) # Retrieves time at frame 10 keyBTime = c4d.BaseTime(10, doc.GetFps()) # Creates another key in the Y curve with value 100 at 10 frame with a spline interpolation keyB, keyBIndex = CreateKey(curveY, keyBTime, value=100, interpolation=c4d.CINTERPOLATION_SPLINE) # --- snip --- # Add key in between the keys A and B. bt = c4d.BaseTime(5, doc.GetFps()) curveY.AddKeyAdaptTangent(bt, True, True) # --- snip --- # Inserts the track containing the Y curve to the object obj.InsertTrackSorted(trackY) # Inserts the object in document doc.InsertObject(obj) # Pushes an update event to Cinema 4D c4d.EventAdd() # Execute main() if __name__ == '__main__': main()
-
@ferdinand That was exactly what I was seeking, thank you, Ferdinand!