0

I have a draw function inspired from this answer:

def draw():
    print(gpu.state.viewport_get())
    framebuffer = gpu.state.active_framebuffer_get()
viewport_info = gpu.state.viewport_get()
width = viewport_info[2]
height = viewport_info[3]

framebuffer_image.scale(width, height)

pixelBuffer = framebuffer.read_color(0, 0, width, height, 4, 0, 'FLOAT')

pixelBuffer.dimensions = width * height * 4
framebuffer_image.pixels.foreach_set(pixelBuffer)

and I'm trying to force redraw it once

_handle_3d = bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'PRE_VIEW')

#some code here to force invoke

bpy.types.SpaceView3D.draw_handler_remove(_handle_3d, 'WINDOW')

The reason I'm doing this is because when I use draw_handler_add it gives:

enter image description here

but when I directly use draw() it gives the entire window:

enter image description here

cak3_lover
  • 477
  • 3
  • 11

1 Answers1

2

A tag_redraw() on all 3D Viewport areas should do the trick. That invokes a redraw.

_handle_3d = bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'PRE_VIEW')

for area in bpy.context.screen.areas: if area.type == 'VIEW_3D': area.tag_redraw()

def remove_handler(): bpy.types.SpaceView3D.draw_handler_remove(_handle_3d, 'WINDOW')

When we remove the handler immediately, Blender had no time

to invoke the redraw. So we remove the handler with a tiny delay.

bpy.app.timers.register(remove_handler, first_interval = 0.01)

When it is just code for your self, no official support needed, you could also use this trick in the Blender documentation:

# Redraw window
bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)
Sietse Brouwer
  • 1,265
  • 4
  • 9