1

I'm trying to add a pointer property to the FCurve type, which has to point to a specific GPencilLayer type.

So far, here's what i tried without success :

i firstly tried to add a single attribute to the FCurve type :

bpy.types.FCurve.layer = bpy.props.PointerProperty(type = bpy.types.GPencilLayer

but while assigning a GPencilLayer to it i have :

AttributeError: 'FCurve' object attribute 'layer2' is read-only

So i tried to use a property group :

class DS_TARGET(PropertyGroup):
    bl_label = "gp dopesheet targets"
    bl_idname = "ds.target"   
    layer : bpy.props.PointerProperty(type = bpy.types.GPencilLayer)

but this classe won't register because of the "layer" property so i think i will use list then append / pop the GPLayer in it :

class DS_TARGET(PropertyGroup):
    bl_label = "gp dopesheet targets"
    bl_idname = "ds.target"   
    layer = []

While trying to add the target attribute to my FCurve type i tried :

bpy.types.FCurve.target = bpy.props.PointerProperty(type=DS_TARGET)

But this will result in a read-only thing and i can't even access my .layer attribute :

<_PropertyDeferred, <built-in function PointerProperty>, {'type': <class 'GP_Dopesheets.DS_TARGET'>}> 

This logic used to work with other types like Scene or Object, but not for Fcurves ? Thanks for your help !

Tomreggae
  • 326
  • 1
  • 9
  • 2
    Hello ! Don't quote me on that : Only classes deriving from type ID, bones and armatures can accept custom properties. Fcurve doesn't so you can't add custom properties to it globally. – Gorgious Jun 21 '21 at 12:05
  • Thanks, that's what i was afraid of... i should try something else.. – Tomreggae Jun 21 '21 at 12:11
  • 1
    ... one workaround could be to add a collection property to the action, which is an ID type. Related https://blender.stackexchange.com/a/127500/15543 – batFINGER Jun 21 '21 at 12:12

1 Answers1

2

Emulate the fcurves collection.

Can only assign bpy.props to ID types and bones. Related https://blender.stackexchange.com/a/127500/15543

As a workaround could add a collection property to the action, which is an ID type.

A simple setup, with a propertygroup having a data_path and array_index property just like an fcurve. The matching fcurve is returned via a regular python property.

import bpy

from bpy.props import CollectionProperty, StringProperty, IntProperty from bpy.types import PropertyGroup, Action

class GPFcurve(PropertyGroup): data_path: StringProperty() array_index: IntProperty() @property def fcurve(self): return self.id_data.fcurves.find(self.data_path, index=self.array_index) bpy.utils.register_class(GPFcurve) Action.gpfcurves = CollectionProperty(type=GPFcurve)

Test and populate in the python console.

>>> action = D.actions['CubeAction']
>>> gpfcurves = action.gpfcurves
>>> for fc in action.fcurves:
...     gpfc = gpfcurves.add()
...     gpfc.data_path = fc.data_path
...     gpfc.array_index = fc.array_index
...     gpfc.fcurve
...     
bpy.data.actions['CubeAction']...FCurve
bpy.data.actions['CubeAction']...FCurve
bpy.data.actions['CubeAction']...FCurve
bpy.data.actions['CubeAction']...FCurve
bpy.data.actions['CubeAction']...FCurve

Ok now have a collection that "somewhat mirrors" the fcurve collection for this action. Add other properties to group to point the item to the grease pencil type.

batFINGER
  • 84,216
  • 10
  • 108
  • 233