1
$\begingroup$

I have a list of GPencilStrokes in a GPencilFrame that I would like to move (and to rotate) via code.

I've noticed in the console the operator that is triggered when I move a stroke in the interface:

bpy.ops.transform.translate(value=(0.154536, 1.05378e-08, -0.241074), orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', mirror=False, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', proportional_size=1.331, use_proportional_connected=False, use_proportional_projected=False, snap=False, snap_elements={'INCREMENT'}, use_snap_project=False, snap_target='CLOSEST', use_snap_self=True, use_snap_edit=True, use_snap_nonedit=True, use_snap_selectable=False)

(Despite how big is, I think the most important thing is the value property).

I tried:

import bpy
from mathutils import Vector

gpd = bpy.context.active_object.data

active_layer = gpd.layers.active
active_frame = active_layer.active_frame
strokes_in_frame = active_frame.strokes

# Deselect everything just in case (?)
bpy.ops.gpencil.select_all(action='DESELECT')

# Direction will change for every stroke but for the example, lets make a constant value
my_direction = Vector((1.0, 0.0, 0.0))

# Moving all the stroke
for stroke in strokes_in_frame:
    stroke.select = True
    bpy.ops.transform.translate(value=my_direction, orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', mirror=False, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', proportional_size=1.331, use_proportional_connected=False, use_proportional_projected=False, snap=False, snap_elements={'INCREMENT'}, use_snap_project=False, snap_target='CLOSEST', use_snap_self=True, use_snap_edit=True, use_snap_nonedit=True, use_snap_selectable=False)
    stroke.select = False

But the strokes do not move.

EDIT: I executed Blender with cmd and after executing the script, I saw the message:

edit type not implemented!

Not sure what it means. I will guess that it says that (translate) editing is not supported via code (?).

The other option I can think of, is to iterate the points in every GPencilStroke and move/change their co property. But this seems killer in terms of performance (and will also complicate the rotating).

So, not sure if Im missing something.

In case is meant to translate by editing the points, does blender provide any function to rotate a list of points?

Thank you so much for the help.

$\endgroup$

1 Answer 1

2
$\begingroup$

Worrying preemptively about performance is one of the very best ways to waste time and energy. Unless you have tens of thousands of points I don't think you should notice a big impact with using point.co. In Blender the bottlenecks are often not where you would think, for example bpy.ops.object.select_all(action='DESELECT') might take a few seconds if you have a few thousands objects to deselect.

You can use a simple solution if you only want a translation.

import bpy
from mathutils import Vector

gpd = bpy.context.active_object.data

active_layer = gpd.layers.active
active_frame = active_layer.active_frame
strokes_in_frame = active_frame.strokes

# For a simple translation you can use
my_direction = Vector((1.0, 0.0, 0.0))

for stroke in strokes_in_frame:
    for point in stroke.points:
        point.co += my_direction

If you want to have a more complex transform, like a rotation, a scale, or any combination, use a matrix.

import bpy
from mathutils import Vector, Matrix
from math import pi

gpd = bpy.context.active_object.data

active_layer = gpd.layers.active
active_frame = active_layer.active_frame
strokes_in_frame = active_frame.strokes

# For a rotation, scale or a combination of any transform you can use a Matrix
my_rotation = Matrix.Rotation(pi/2, 3, "Z")

for stroke in strokes_in_frame:
    for point in stroke.points:
        point.co = my_rotation @ point.co

Further reading about mathutils.Matrix

$\endgroup$
2
  • $\begingroup$ Perfect as always Gorgious, thank you so much, much appreciated! And thank you so for discovering me mathutils.Matrix, so useful! PS: Totally right about your performance thoughs. Im an expert at falling in the trap of premature optimization D: $\endgroup$
    – Ommadawn
    Commented Oct 31, 2023 at 7:55
  • 1
    $\begingroup$ @Ommadawn Glad it helped :) And thank you for taking the time to form a well-thought out and structured question. Cheers $\endgroup$
    – Gorgious
    Commented Oct 31, 2023 at 8:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .