How do I instantiate objects in Blender 3?
I am trying to programmatically draw on a mesh's texture. According to the docs, the function to call is bpy.ops.paint.image_paint()
, which takes a bpy_prop_collection
of OperatorStrokeElement
. I tried various ways to instantiate the object, the errors were 'is not a type of PropertyGroup'
, 'an id was expected'
.
Also, do I need to select area or context before drawing? Which coordinate system is used for the strokes' position, do I specify offset in pixels from top-left corder of the window?
EDIT After the first answer, here is the code that I am running in the console (after making sure that the texture (or, rather, material) can be painted on (manually):
def context_override():
for window in bpy.context.window_manager.windows:
screen = window.screen
for area in screen.areas:
if area.type == 'VIEW_3D':
for region in area.regions:
if region.type == 'WINDOW':
return {'area': area, 'region': region}
strokes = [
{"name":"stroke", "mouse": (0,0), "mouse_event": (0,0), "x_tilt": 0, "y_tilt": 0, "pen_flip" : False, "is_start": True, "location": (0,0,0), "size": 10, "pressure": 1,"time": float(1)}
,{"name":"stroke", "mouse": (0,0), "mouse_event": (0,0), "x_tilt": 0, "y_tilt": 0, "pen_flip" : False, "is_start": False, "location": (0,0,1), "size": 10, "pressure": 1,"time": float(2)}
,{"name":"stroke", "mouse": (0,0), "mouse_event": (0,0), "x_tilt": 0, "y_tilt": 0, "pen_flip" : False, "is_start": False, "location": (0,1,0), "size": 10, "pressure": 1,"time": float(3)}
,{"name":"stroke", "mouse": (0,0), "mouse_event": (0,0), "x_tilt": 0, "y_tilt": 0, "pen_flip" : False, "is_start": False, "location": (0,1,1), "size": 10, "pressure": 1,"time": float(4)}
]
bpy.context.scene.tool_settings.image_paint.use_clone_layer = True
bpy.context.scene.tool_settings.image_paint.mode = "MATERIAL"
bpy.ops.paint.image_paint(context_override(), stroke=strokes)
It returns "{'Finished'}", and no effect takes place. Screenshot (the stroke you see is by hand):
EDIT Found it. After a number of random experiments, it is the 'mouse' -- the offset in pixels from lower-left corner of the window (region). 'Location' value seems to have no effect, same for 'mouse_event', 'is_start', 'time'. I could not get a continuous stroke (not that I spent much time on it). Also, the documentation says there are default values, but you still have to specify all of them when instantiating stroke objects.
Code:
def stroke_def(mouse, start, time):
return {"name":"stroke","mouse":mouse,"mouse_event": (0,0),"x_tilt":0,"y_tilt":0,"pen_flip":False,"is_start":start,"location":(0,0,0),"size":100,"pressure":1,"time":time}
bpy.ops.paint.image_paint(context_override("VIEW_3D"), stroke=[stroke_def((400, 400), True, 1.0), stroke_def((500, 500), False, 2.0)])