Можем ли мы напрямую. т.е. не заботясь о текущем выбранном объекте, режиме поворота преобразования, настройках видового экрана и т. д., доступе к этой точке, т.е. источнику вращения текущего данного видового экрана 3d в мировом пространстве (или даже в экранном пространстве)?
Я пытался спросить GPT об этом, и он придумал следующее решение:
Код: Выделить всё
import bpy
bl_info = {
"name": "Viewport Rotation Point Debugger",
"author": "Your Name",
"version": (1, 0),
"blender": (3, 0, 0),
"location": "Search > Viewport Rotation Point Debugger",
"description": "Prints the 3D rotation point of the viewport camera when rotation starts and a message when it stops.",
"category": "3D View",
}
class ViewportRotationPointDebugger(bpy.types.Operator):
"""Detects viewport camera rotation and prints the rotation point"""
bl_idname = "view3d.rotation_point_debugger"
bl_label = "Viewport Rotation Point Debugger"
bl_options = {'REGISTER'}
is_rotating = False # Track whether the camera is rotating
last_rotation = None # Store the last rotation quaternion
rotation_pivot = None # Store the calculated rotation pivot
def get_rotation_pivot_world(self, context):
"""Returns the rotation pivot point in world space"""
area = next(area for area in bpy.context.screen.areas if area.type == 'VIEW_3D')
region_3d = area.spaces[0].region_3d
# The location of the camera (view location)
view_location = region_3d.view_location
# The rotation of the view (view rotation)
view_rotation = region_3d.view_rotation
# This is the pivot point in world space (directly from the view_location)
# No need for complex matrix calculations as we are already getting it directly.
return view_location
def modal(self, context, event):
# Detect when rotation starts
if event.type == 'MOUSEMOVE' and event.alt:
if not self.is_rotating:
self.is_rotating = True
# Calculate and print the rotation point once (in world space)
self.rotation_pivot = self.get_rotation_pivot_world(context)
print(f"Viewport Rotation Started. Pivot Point: {self.rotation_pivot}")
# Detect when rotation stops (mouse release or ESC)
elif self.is_rotating and event.type in {'LEFTMOUSE', 'RIGHTMOUSE', 'ESC'}:
self.is_rotating = False
print("Viewport Rotation Stopped.")
return {'PASS_THROUGH'}
def execute(self, context):
self.is_rotating = False
self.rotation_pivot = None # Reset the pivot point when starting the operator
context.window_manager.modal_handler_add(self)
return {'RUNNING_MODAL'}
def cancel(self, context):
self.is_rotating = False
self.rotation_pivot = None
print("Stopped tracking viewport rotation.")
def menu_func(self, context):
self.layout.operator(ViewportRotationPointDebugger.bl_idname)
def register():
bpy.utils.register_class(ViewportRotationPointDebugger)
bpy.types.VIEW3D_MT_view.append(menu_func)
def unregister():
bpy.utils.unregister_class(ViewportRotationPointDebugger)
bpy.types.VIEW3D_MT_view.remove(menu_func)
if __name__ == "__main__":
register()
Подробнее здесь: https://stackoverflow.com/questions/792 ... via-python