2024.4.0 crashes when setting key-values
-
Hello,
I'm just a bit stumped. In previous versions of C4D this approach, writing keys worked perfectly.
Normally the routine is executed by a plugin in the message method, but I was able to change the example into a script and that's where the error occurs.Here I have the script and the required scene with the object.
bake_test.zipThe script should simply write keys with values โโinto the user data, usually the user datas are animated and they are a lot more, so in the plugin it has to filter the right ones
After detailed debugging, I'm sure the error happens in the third last line with key.SetValue(curve, value)import c4d doc: c4d.documents.BaseDocument # The currently active document. op: c4d.BaseObject | None # The primary selected opect in `doc`. Can be `None`. def bake(): strength_list = { "AA": 1, "EE": 1, "IY": 1, "OW": 1, "UW": 1, "F": 1, "W": 1, "SH": 1, "T": 1, "M": 1 } after_list = [] # ================================================= user_list = ["AA", "EE", "IY", "OW", "UW", "F", "W", "SH", "T", "M"] parameter_list = [] for ide, bc in op.GetUserDataContainer(): if bc[c4d.DESC_NAME] in user_list: parameter_list.append(ide) after_list.append(bc[c4d.DESC_NAME]) if not parameter_list: # if no userdatas added c4d.gui.MessageDialog("Missing User Datas!\n\nClick 'Add User-Data'") return True doc.AddUndo(c4d.UNDOTYPE_CHANGE, op) c4d.StatusSetSpin() # start = node[PY_BAKE_START] # end = node[PY_BAKE_END] for frame in range(0, 90): time = c4d.BaseTime(frame, doc.GetFps()) doc.SetTime(time) doc.ExecutePasses(None, True, True, True, c4d.BUILDFLAGS_NONE) # False True False for ide in parameter_list: track = op.FindCTrack(ide) if track is None: track = c4d.CTrack(op, ide) op.InsertTrackSorted(track) curve = track.GetCurve() keyData = curve.AddKey(time) if keyData is None: raise RuntimeError("Could not add key frame.") key = keyData["key"] key.SetValue(curve, op[ide]) key[c4d.ID_CKEY_PRESET] = 2 # c4d.ID_CKEY_PRESET_AUTO_OVERSHOOTWEIGHTED c4d.StatusClear() def main() -> None: """Called by Cinema 4D when the script is being executed. """ bake() if __name__ == '__main__': main()
Cheers
-
-
Hey @ThomasB,
Thank you for reaching out to us and reporting this. There is something going wrong with accessing scene nodes related data on an object while a key is being parsed. I first I thought, a simple
op.Message(maxon.neutron.MSG_CREATE_IF_REQUIRED)
would fix that, because it is failing on your null, but the problem goes deeper than that. It already fails when trying to access if your null is nodes based. There is currently no workarround for you as far as I can see.Submitted as
ITEM#513432 [Python] Accessing key data causes Cinema 4D to crash
.Cheers,
Ferdinand -
@ferdinand
this is really odd, because I have a Button in my plugin which simply creates keyframes for specific description parameters of the plugin, similar as it is in the PoseMorph Tag when you create keyframes for all sliders at once. And here it works without crashing:
Maybe this helps you.
The code of writing the keyframes is pretty the same, the only difference is that I set here keyframes for the description Id's instead of the user-datas...hmthis is just a snippet:
PY_STRENGTH_A_MANUAL = 10051 PY_STRENGTH_E_MANUAL = 10052 PY_STRENGTH_I_MANUAL = 10053 PY_STRENGTH_O_MANUAL = 10054 PY_STRENGTH_U_MANUAL = 10055 PY_STRENGTH_F_MANUAL = 10056 PY_STRENGTH_W_MANUAL = 10057 PY_STRENGTH_SH_MANUAL = 10058 PY_STRENGTH_OTHERS_MANUAL = 10059 PY_STRENGTH_CLOSED_MANUAL = 10060 id_list = [PY_STRENGTH_A_MANUAL, PY_STRENGTH_E_MANUAL, PY_STRENGTH_I_MANUAL, PY_STRENGTH_O_MANUAL, PY_STRENGTH_U_MANUAL, PY_STRENGTH_F_MANUAL, PY_STRENGTH_W_MANUAL, PY_STRENGTH_SH_MANUAL, PY_STRENGTH_OTHERS_MANUAL, PY_STRENGTH_CLOSED_MANUAL ] #========Plugin==================== def Message(self, node, type, data): if data["id"][0].id == PY_RECORD_MANUAL: time = node.GetObject().GetDocument().GetTime() node.GetDocument().AddUndo(c4d.UNDOTYPE_CHANGE, node) if c4d.threading.GeIsMainThread(): for ide in id_list: track = node.FindCTrack(ide) if not track: track = c4d.CTrack(node, ide) node.InsertTrackSorted(track) curve = track.GetCurve(c4d.CCURVE_CURVE, True) keydata = curve.AddKey(time) if keydata is None: raise RuntimeError("Could not add key frame.") key = keydata["key"] key.SetValue(curve, node[ide]) key[c4d.ID_CKEY_PRESET] = 2 # c4d.ID_CKEY_PRESET_AUTO_OVERSHOOTWEIGHTED c4d.EventAdd()
-
Hey @Thomas,
thank you for your reply. When we move a topic to the bug section, this means we have confirmed something as a bug, which usually means that we have at least some idea of what is going wrong. I simply ran your code against a Cinema 4D instance with a debugger attached to see where it is crashing. As I wrote above, this is node related, the crash happened in
BaseList2D::IsNodeBased
whenCKey
data of aBaseList2D
(your null) was about to be set.Before I left, Maxime sent me a screen of what he thought was the issue, so this problem is likely already fixed. It at least made your crash go away, according to Maxime. Thank your for your help, but do not waste your time, we got this
Cheers,
FerdinandPS: Final say on how and if this is fixed has Maxime, he will announce it here once he is done with the issue.
-
Hi @ThomasB, sorry for the issue.
This is going to be fixed in the next version of Cinema 4D. With that's said you can workaround the issue by using directly SetParameter like so:
# key[c4d.ID_CKEY_PRESET] = 2 key.SetParameter(c4d.DescID(c4d.ID_CKEY_PRESET), 2, c4d.DESCFLAGS_SET_NONE)
Thanks for the report !
Cheers,
Maxime.