# How to store the selected points of a Mask

I am trying to store the selected points of a Mask in the ClipEditor in a list, in order to retrieve it later, so to say as a temporary selection-set of mask controlpoints.

Here's what I have so far:

import bpy
pointlist = []
for p in layer.splines.active.points:
if p.select == True:
pointlist.append(p)


That works so far. If I print that list it has all the selected points in it, such as:

<bpy_struct, MaskSplinePoint at 0x7f7f2fbb4d88>


However, when I continue to do this:

bpy.context.scene["mask_storage"] = pointlist


I get an error:

TypeError: object of type 'MaskSplinePoint' has no len() The above exception was the direct cause of the following exception: SystemError: PyEval_EvalFrameEx returned a result with an error set

At first I tried to append the points directly to the "mask_storage" list directly, but that didn't work, it gave the error

AttributeError: 'IDPropertyArray' object has no attribute 'append'

That's why I tried to work around that by first appending to the "pointlist" and then assigning that to "mask_storage". But that obviously does not work.

I did do some googling already, and it seems I might need to do something with bpy.props.CollectionProperties, but I simply couldn't figure out how to do that exactly.

• When you say you want to retrieve the data later, how much later? When the blend file has been closed and re-opened, later on in the script or later on in the same blender session? – Ray Mairlot Nov 26 '17 at 17:07
• @RayMairlot the most basic use would be during a blender session (same file), that would be probably enough. It’s to make rotoscoping easier. – sebastian_k Nov 26 '17 at 17:32
• You can do setattr(bpy, 'mask_storage', pointlist) to save them, then do bpy.mask_storage to access them later. – Omar Emara Nov 26 '17 at 19:31
• Wow, that actually does work! And much simpler than I thought. Thank you so much! – sebastian_k Nov 26 '17 at 19:39

So, with @OmarAhmad's help I figured out a way to achieve what I want. Just for the sake of completeness I want to post the entire code here. On Twitter I got told that storing the points the way I did was dangerous, because if the masks got deleted and I try to access them anyway it would lead to a segfault. So far I did not notice any problems like that. Anyway, here's the script. I think it can make Rotoscoping a bit easier:

import bpy

pointlist = []
# if the storage doesnt exist, create it, otherwise, reference it
try:
except:
mydict = {}

# if there is an active spline, list all selected points
if layer.splines.active:
for p in layer.splines.active.points:
if p.select == True:
pointlist.append(p)
# assign the pointlist to the layer
mydict[layer] = pointlist
# write the dictionary to the mask_storage
# (I would rather write this list as an attribute of the masklayer,
# but appartently I can only do that on bpy)

# if there is an active layer and
# if that layer is stored in mask_storage, select the points in it
try:
for p in layer.splines.active.points:
p.select = False
p.select = True
except:

''' Store the points of a the active spline as Selection Set'''

@classmethod
def poll(cls, context):
space = context.space_data
return (space.type == "CLIP_EDITOR") and space.clip and mask

def execute(self, context):
return {'FINISHED'}

''' Select the Selection Set of the MaskPoints'''

@classmethod
def poll(cls, context):
space = context.space_data
return (space.type == "CLIP_EDITOR") and space.clip and mask

def execute(self, context):
return {'FINISHED'}

def register():

wm = bpy.context.window_manager