A RegionView3D is actually a space, the access path is bpy.context.screen.areas[#].spaces.active.region_3d
(area being of type VIEW_3D
), or in case of quadview mode, ... spaces.active.region_quadviews[#]
.
There are no direct references from a region to a RegionView3D.
It's possible to find the right quadview region and its space, here's a (modal timer) example:
import bpy
import math
def get_view_orientation(space, quadview):
if quadview.view_perspective == 'CAMERA':
view_orientation = "Camera Persp"
else:
r = lambda x: round(x, 2)
view_rot = quadview.view_matrix.to_euler()
orientation_dict = {(0.0, 0.0, 0.0) : 'TOP',
(r(math.pi), 0.0, 0.0) : 'BOTTOM',
(r(-math.pi/2), 0.0, 0.0) : 'FRONT',
(r(math.pi/2), 0.0, r(-math.pi)) : 'BACK',
(r(-math.pi/2), r(math.pi/2), 0.0) : 'LEFT',
(r(-math.pi/2), r(-math.pi/2), 0.0) : 'RIGHT'}
view_orientation = orientation_dict.get(tuple(map(r, view_rot)), 'USER').capitalize()
view_orientation += " " + quadview.view_perspective.capitalize()
if space.local_view is not None:
view_orientation += " (Local)"
return view_orientation
def get_quadview_index(context, x, y):
for area in context.screen.areas:
if area.type != 'VIEW_3D':
continue
if len(area.spaces.active.region_quadviews) == 0:
return
i = -1
for region in area.regions:
if region.type == 'WINDOW':
i += 1
if (x >= region.x and
y >= region.y and
x < region.width + region.x and
y < region.height + region.y):
return (area.spaces.active, i)
return (None, None)
class ModalTimerOperator(bpy.types.Operator):
"""Operator which runs its self from a timer"""
bl_idname = "wm.modal_timer_operator"
bl_label = "Modal Timer Operator"
_timer = None
def modal(self, context, event):
if event.type in {'RIGHTMOUSE', 'ESC'}:
return self.cancel(context)
if event.type == 'TIMER':
space, i = get_quadview_index(context, event.mouse_x, event.mouse_y)
if space is not None:
quadview = space.region_quadviews[i]
print(get_view_orientation(space, quadview))
return {'PASS_THROUGH'}
def execute(self, context):
wm = context.window_manager
self._timer = wm.event_timer_add(0.5, context.window)
wm.modal_handler_add(self)
return {'RUNNING_MODAL'}
def cancel(self, context):
wm = context.window_manager
wm.event_timer_remove(self._timer)
return {'FINISHED'}
def register():
bpy.utils.register_class(ModalTimerOperator)
def unregister():
bpy.utils.unregister_class(ModalTimerOperator)
if __name__ == "__main__":
register()
# test call
bpy.ops.wm.modal_timer_operator()