Page MenuHome

Python curve hook operators mess with selection (Probably only on Windows)
Closed, ArchivedPublic

Description

System Information
Operating system: Windows-10-10.0.18362-SP0 64 Bits
Graphics card: GeForce GTX 1070/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 441.20

Blender Version
Broken: version: 2.83 (sub 9), branch: master, commit date: 2020-03-15 22:43, hash: rBf06a6e92bc5e
Worked: I tried an older version which I know to have worked on my Linux machine at work a few days ago, and it still didn't work, so I suspect this issue is only present on Windows, or only on my computer. Let me know if you can reproduce.

Exact steps for others to reproduce the error

  • Run the python script curve_select_fail.py.
  • Hook modifiers get added. According to the code, the modifiers should correspond to each curve point. Instead, the result is random - most of the time, but not always, only the first point is hooked with all of the modifiers.
  • Run the python script why_index_error.py
  • It index errors. If you remove the last line of code, it works. The last line of code shouldn't affect the curve's indicies, so this can't be right.

I could really use a workaround until this is fixed.

Event Timeline

Germano Cavalcante (mano-wii) changed the task status from Needs Triage to Confirmed.EditedMar 19 2020, 11:00 PM
Germano Cavalcante (mano-wii) changed the subtype of this task from "Report" to "Bug".

The problem is quite complex.

The operator OBJECT_OT_hook_add_selob calls ED_curve_editnurb_load which creates another cu->nurb and free the old one.
But the old cu->nurb is already referenced by a PyObject of type pyrna_prop_collection_Type with pointer inited in rna_Curve_splines_begin.
The ideal would be, when freeing the pointer, to call RNA_POINTER_INVALIDATE(nu_ptr) for the original PointerRNA.
But the question is, how to find this PointerRNA in the operator?

@Campbell Barton (campbellbarton), we need an RNA/CPython expert here.

Or maybe we don't even need free cu->nurb

Thanks for looking into it! Were you able to reproduce it on Linux as well? I could swear that this worked on my work computer just a few days ago... I will check if I get the chance, but working from home atm >.>.

In the meanwhile, based on your description of the issue, I managed to work around it by re-grabbing my reference to the object, spline and curve points after running the Add Hook operator.

Germano Cavalcante (mano-wii) changed the subtype of this task from "Bug" to "Known Issue".Apr 29 2020, 1:17 PM

As far as I can see, there is no simple solution to this.
I don't think it will be resolved anytime soon.

No worries. For anyone else running into this, some elaboration on the workaround:

This will (or might) fail:

curve_ob = bpy.context.object
for s in curve_ob.data.splines:
    for p in s.bezier_points:
        p.select_control_point = True

        bpy.ops.object.hook_add_selob()

Whereas this should work:

curve_ob = bpy.context.object
for i in range(0, len(curve_ob.data.splines)):
    for p in curve_ob.data.splines[i].bezier_points:
        p.select_control_point = True

        bpy.ops.object.hook_add_selob()
        curve_ob = bpy.context.object

Just refresh your reference to curve_ob(and therefore curve_ob.data) after using the operator.

Demeter Dzadik (Mets) triaged this task as Low priority.EditedJul 24 2020, 12:28 PM

I have since found out that there is no need to use bpy.ops here, thanks to rB3f788eacee5ad075680a. Hook modifiers can be assigned vertices with my_hook_modifier.vertex_indices_set([0, 1, 2]). A much better workaround than what I posted previously, although it does involve reshuffling code a bit more.

I feel like there's no reason to have to call bpy.ops.object.hook_add_selob() from Python anymore. With that in mind I bumped down the priority, but maybe this could even be closed, not sure.

Closing since I don't think it's reasonable to consider operators re-allocation of data a bug in the Python API (although from the users perspective I realize it's not very nice).

Campbell Barton (campbellbarton) changed the subtype of this task from "Known Issue" to "Report".Sep 18 2020, 1:05 PM