How to access the view 3d camera?

I try to find my way into Python at the moment, and try to start with a very primitive addon. I want to set the view3d camera back to its original position and rotation. A Reset view feature. For the case that you have navigated yourself away. It’s one of those small things that i really miss in Blender.

I got so far that i can set a scene camera to position and location. Looks like this at the moment:

import bpy

scene = bpy.context.scene

scene.camera.location = (8, -8, 6)
scene.camera.rotation_euler = (0.15, 0, 0.1)

But i cannot find a way to access the view3d camera. The one that displays the workspace, and is not in the outliner. Most probably because of my lack of knowledge of the right term i hope. Is there even a way to access the view3d camera? All examples that i find are just for the scene cameras.

And while at it. The above code sets just the first camera in the outliner to its position and rotation. But not the second one, no matter if it is selected or not.

Well, there is scene.objects.active. And by using this code i can do the operation at the selected object only. But it works at any selected object then. How can i tell this code that it has to be a camera? So that it doesn’t work at every selected object? bpy.context.scene.camera.active doesn’t do the trick.

object = bpy.context.scene.objects.active

object.location = (8, -8, 6)
object.rotation_euler = (0.15, 0, 0.1)

Assuming sp is the space of a View3D area. (search in screen -> screen.areas -> area.spaces -> space)


cam_info = sp.region_3d.view_matrix.inverted()
cam_info.translation()
cam_info.rotation()

Should give the location and rotation. In view space the world is moved not the camera thus its view_matrix.inverted()See #1 .#2

I’ve taken the default’s scene view_matrix and apply it to every currently visible 3D View which isn’t in quadview mode:

import bpy

view_matrix = ((0.41, -0.4017, 0.8188, 0.0),
               (0.912, 0.1936, -0.3617, 0.0),
               (-0.0133, 0.8959, 0.4458, 0.0),
               (0.0, 0.0, -14.9892, 1.0))
               
for area in bpy.context.screen.areas:
    if area.type == 'VIEW_3D':
        rv3d = area.spaces[0].region_3d
        if rv3d is not None:
            # could also test for SpaceView3D.localview
            rv3d.view_perspective = 'PERSP'
            rv3d.view_matrix = view_matrix

It doesn’t switch off localview mode, but it could:

import bpy

view_matrix = ((0.41, -0.4017, 0.8188, 0.0),
               (0.912, 0.1936, -0.3617, 0.0),
               (-0.0133, 0.8959, 0.4458, 0.0),
               (0.0, 0.0, -14.9892, 1.0))
               
for area in bpy.context.screen.areas:
    if area.type == 'VIEW_3D':
        rv3d = area.spaces[0].region_3d
        if rv3d is not None:
            if area.spaces[0].local_view is not None:
                bpy.ops.view3d.localview({'area': area})
            rv3d.view_perspective = 'PERSP'
            rv3d.view_matrix = view_matrix

You could turn that into an operator very easily and append it to View > Align View menu.

3 Likes

Phew, that’s pretty overwhelming for a beginner in Python. I guess i will need a few moments to sort the informations ^^

Vital part is: it is possible to acess the view camera. Which is a good thing. Now on with understanding your code snippets …

Many thanks :slight_smile:

Many thanks again. I got it working and made a plugin out of it. And i even understand it partially :smiley:

But there is a flaw. And i have no idea how to fix it. When you have zoomed the view, then the Ortho view does not reset to where it was before. The rotation resets. But not the zoom. Means, the perspectivic view is where it was before. But the orthographic view not. And this can add until you are completely offset and the ortho view is out of sight. Which makes the reset view feature very dangerous as it is at the moment.

The curious thing is the matrix is the same, no matter how i zoom. I have tested it by printing the matrix to the console.

    
for vector in rv3d.view_matrix :
        print(view_matrix)

What i need is a command to reset the zoom it seems. All i have found in the api is this: bpy.ops.view3d.zoom(delta=0,mx=0,my=0) : But it throws me an error in the console. "… expected a view3d region … " . Close but not close enough. Seems that i use it wrong. Beginner …

I have shortened the code and removed the PERSP bit. The code looks like this at the moment:

import bpy

view_matrix = ((0.41, -0.4017, 0.8188, 0.0),
               (0.912, 0.1936, -0.3617, 0.0),
               (-0.0133, 0.8959, 0.4458, 0.0),
               (0.0, 0.0, -14.9892, 1.0))
               
for area in bpy.context.screen.areas:
    if area.type == 'VIEW_3D':
        rv3d = area.spaces[0].region_3d
        if rv3d is not None:
            rv3d.view_matrix = view_matrix
            #bpy.ops.view3d.zoom(delta=0,mx=0,my=0)


Have i even the right method here? And how should the #bpy.ops.view3d.zoom(delta=0,mx=0,my=0) bit look like so that it works?


In orthographic view you can change the “zoom” by changing region_3d.view_distance. Does not make sense since orthographic view is independent from distance.

You can probably multiply the view matrix with a matrix scaling the world to achieve a “zoom”.

region_3d.view_distance, region_3d.view_location (view target) and region_3d.view_rotation might be used to setup a LookAt configuration.

Thanks pink vertex, view_distance seems to do the trick :slight_smile:

import bpy

view_matrix = ((0.41, -0.4017, 0.8188, 0.0),
               (0.912, 0.1936, -0.3617, 0.0),
               (-0.0133, 0.8959, 0.4458, 0.0),
               (0.0, 0.0, -14.9892, 1.0))
               
for area in bpy.context.screen.areas:
    if area.type == 'VIEW_3D':
        rv3d = area.spaces[0].region_3d
        if rv3d is not None:
            
            rv3d.view_distance = 10
            rv3d.view_matrix = view_matrix

Let me do some more tests, and i will post the complete plugin then when there are no more flaws :slight_smile:

There wasn’t only a problem with ortho view, but also persp. The view_distance needs to be reset to ~15, or you’ll end up in vast space after reset if you rotate view.

import bpy

view_matrix = ((0.41, -0.4017, 0.8188, 0.0),
               (0.912, 0.1936, -0.3617, 0.0),
               (-0.0133, 0.8959, 0.4458, 0.0),
               (0.0, 0.0, -14.9892, 1.0))
               
for area in bpy.context.screen.areas:
    if area.type == 'VIEW_3D':
        rv3d = area.spaces[0].region_3d
        if rv3d is not None:
            if area.spaces[0].local_view is not None:
                bpy.ops.view3d.localview({'area': area})
            rv3d.view_perspective = 'PERSP'
            rv3d.view_distance = 14.99
            rv3d.view_matrix = view_matrix

If you want to use the zoom operator, make sure to give it right context.

import bpy

view_matrix = ((0.41, -0.4017, 0.8188, 0.0),
               (0.912, 0.1936, -0.3617, 0.0),
               (-0.0133, 0.8959, 0.4458, 0.0),
               (0.0, 0.0, -14.9892, 1.0))
               
for area in bpy.context.screen.areas:
    if area.type == 'VIEW_3D':
        rv3d = area.spaces[0].region_3d
        if rv3d is not None:
            rv3d.view_matrix = view_matrix
            bpy.ops.view3d.zoom({'area': area, 'region': area.regions[-1]}, delta=0,mx=0,my=0)

http://www.blender.org/documentation/blender_python_api_2_69_10/bpy.ops.html#overriding-context

Post your final script when it’s ready, I’ll wait with mine, so you really learn something :wink:

Just another example. Sets the view camera to the camera named “Camera”.

The user will rotate around region3d.view_location unless he locks his view to the cursor/selection.


import bpy

cam = bpy.data.objects["Camera"]
cam.rotation_mode = "QUATERNION"
mat = cam.rotation_quaternion.to_matrix().to_4x4()
mat.translation = cam.location

for area in bpy.context.screen.areas:
    if area.type == "VIEW_3D":
        break

r3d = area.spaces[0].region_3d
r3d.view_matrix = mat.inverted()

if False:
    cursor_location = area.spaces[0].cursor_location
    r3d.view_distance = \
        (cam.location - cursor_location).length
    r3d.view_location = cursor_location

1 Like

Great example pink vertex. I already wondered if it is possible to go the reverse way to the “set camera to view” command :slight_smile:

There wasn’t only a problem with ortho view, but also persp. The view_distance needs to be reset to ~15, or you’ll end up in vast space after reset if you rotate view. The view_distance needs to be reset to ~15, or you’ll end up in vast space after reset if you rotate view.

Yup, that was what happened to me. The rv3d.view_distance = 10 line did the trick. And yes, it’s around 15 as i just found out ^^

Here’s the script to check the current matrix and distance:

import bpy


view_matrix = ((0.41, -0.4017, 0.8188, 0.0),
               (0.912, 0.1936, -0.3617, 0.0),
               (-0.0133, 0.8959, 0.4458, 0.0),
               (0.0, 0.0, -14.9892, 1.0))
               
for area in bpy.context.screen.areas:
    if area.type == 'VIEW_3D':
        rv3d = area.spaces[0].region_3d
        if rv3d is not None: 
            
            for vector in rv3d.view_matrix :
                print(view_matrix)
            distance = area.spaces[0].region_3d.view_distance
            print(distance)

Post your final script when it’s ready, I’ll wait with mine, so you really learn something :wink:

Will do. And i have learnt lots in the last three days since i touched Blender Python. My head already explodes, heh. But i still have a very long way to go as i just noticed.

I just stumbled across the next problem. The ortho views. We need other view_matrices here. One for every ortho view it seems. Work for tomorrow ^^

This is the current state of the whole script at the moment. Any tips at the menu stuff and all the things around? Did i miss something?

I have one problem at the keymap code. This line here gives me an error:

kmi.properties.total = 4

What does this line do? And why does it give an error? What did i overlook? It works fine in the example code from the addon tutorial that can be found here: http://www.blender.org/documentation/blender_python_api_2_65_5/info_tutorial_addon.html

The error message in the console is: AttributeError: 'View_OT_reset_view has no attribute ‘total’

#Big Thanks for the help with the code goes to pink vertex and CoDEmanX at the Blenderartists forum
#I have basically just copied their code. And made a plugin out of it.

bl_info = {
    "name": "Reset View",
    "description": "Resets the views of all 3D windows to standard view",
    "author": "Reiner 'Tiles' Prokein",
    "version": (0, 5),
    "blender": (2, 69, 0),
    "location": "View3D > View",
    "warning": "", # used for warning icon and text in addons panel
    ## not yet ...
#    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"
#                "Scripts/My_Script",
    "category": "View"}


import bpy


class ResetView(bpy.types.Operator):
    """Reset View"""
    bl_idname = "view.reset_view"
    bl_label = "Reset View"
    bl_options = {'REGISTER', 'UNDO'}

    def execute(self, context):
        view_matrix = ((0.41, -0.4017, 0.8188, 0.0), # This is the view matrix from Factory settings
               (0.912, 0.1936, -0.3617, 0.0),
               (-0.0133, 0.8959, 0.4458, 0.0),
               (0.0, 0.0, -14.9892, 1.0))
               
        for area in bpy.context.screen.areas:
            if area.type == 'VIEW_3D':
                rv3d = area.spaces[0].region_3d
                if rv3d is not None:
            # Here happens the magic. Distance and Location and Rotation gets reset
                    rv3d.view_distance = 15 # This is the original distance to the zero point from Factory settings.
                    rv3d.view_matrix = view_matrix # This resets the location and rotation back to the initial view matrix values

        return {'FINISHED'}
    
def menu_func(self, context):
    self.layout.operator(ResetView.bl_idname)
    
# store keymaps here to access after registration
addon_keymaps = []
   

def register():
    bpy.utils.register_class(ResetView)
    bpy.types.VIEW3D_MT_view.append(menu_func)
    
    # handle the keymap
    wm = bpy.context.window_manager
    km = wm.keyconfigs.addon.keymaps.new(name='View Mode', space_type='EMPTY')
    kmi = km.keymap_items.new(ResetView.bl_idname, 'ONE', 'PRESS', ctrl=False, shift=True)
   # kmi.properties.total = 4 # spits an error, and i have no idea why ...
    addon_keymaps.append(km)

def unregister():
    bpy.utils.unregister_class(ResetView)
    bpy.types.VIEW3D_MT_view.remove(menu_func)
    
    # handle the keymap
    wm = bpy.context.window_manager
    for km in addon_keymaps:
        wm.keyconfigs.addon.keymaps.remove(km)
    # clear the list
    del addon_keymaps[:]


if __name__ == "__main__":
    register()
            

kmi.properties.total = 4

You can set operator properties at will for keymap items, you would always run them with default settings otherwise. You don’t need this particular line as your operator doesn’t have this property (is has none at all actually).

Here’s my version:

bl_info = {
    "name": "Reset 3D View",
    "author": "CoDEmanX",
    "version": (1, 0),
    "blender": (2, 65, 0),
    "location": "View3D > View > Align View > Reset View",
    "description": "Reset 3D View to default perspective",
    "warning": "",
    "wiki_url": "",
    "tracker_url": "",
    "category": "3D View"}


import bpy

addon_keymaps = []

view_matrix = ((0.41, -0.4017, 0.8188, 0.0),
               (0.912, 0.1936, -0.3617, 0.0),
               (-0.0133, 0.8959, 0.4458, 0.0),
               (0.0, 0.0, -14.9892, 1.0))


class VIEW3D_OT_view_reset(bpy.types.Operator):
    """Reset 3D View to default perspective"""
    bl_idname = "view3d.view_reset"
    bl_label = "Reset View"

    @classmethod
    def poll(cls, context):
        return context.area.type == 'VIEW_3D'

    def execute(self, context):
        rv = context.space_data.region_3d
        if rv is None:
            rv = context.space_data.region_quadview
            
        if context.space_data.local_view is not None:
            bpy.ops.view3d.localview()
            
        rv.view_perspective = 'PERSP'
        rv.view_distance = -view_matrix[3][2]
        rv.view_matrix = view_matrix
        return {'FINISHED'}


def draw_func(self, context):
    layout = self.layout
    layout.separator()
    layout.operator(VIEW3D_OT_view_reset.bl_idname)


def register():
    bpy.utils.register_class(VIEW3D_OT_view_reset)
    bpy.types.VIEW3D_MT_view_align.append(draw_func)

    # handle the keymap
    wm = bpy.context.window_manager
    km = wm.keyconfigs.addon.keymaps.new(name='3D View', space_type='VIEW_3D')
    kmi = km.keymap_items.new(VIEW3D_OT_view_reset.bl_idname, 'NUMPAD_ASTERIX', 'PRESS')
    addon_keymaps.append((km, kmi))


def unregister():
    bpy.utils.unregister_class(VIEW3D_OT_view_reset)
    bpy.types.VIEW3D_MT_view_align.remove(draw_func)

    # handle the keymap
    for km, kmi in addon_keymaps:
        km.keymap_items.remove(kmi)
    addon_keymaps.clear()


if __name__ == "__main__":
    register()

Numpad * seemed like a good hotkey to me.

The art of finding a free hotkey, heh. Numpad asterisk sounds really neat. Didn’t know that there is a single key hotkey that is not already occupied :slight_smile:

Phew. I am already in trouble to follow your script. Quite a few terms that i don’t know yet. @classmethod for example. I have to do a google search here i guess.

But first let’s get the baby to work. I told about the problem with the different views. Top view resets to a twisted view, that is still displaying the Top view grid in the background. And tried to solve it. No luck. My knowledge is too weak.

I got it sorted to separate perspective and orthographic view. But that is not what i need. I need the view methods like top, left right, etc. . Plus the method that is not mentioned in the list. The perspectivic view in perspective and orthographic. My current problem with that is to find out what kind of view is set for the 3D Window. So i hovered with the mouse over the menu point for top. The python code there says:
Python: bpy.ops.view3D.viewnumpad(type=‘TOP’)

When i use this line as is in the code with an if in front of it, then i get of course a warning. So i tried
if bpy.ops.view3D.viewnumpad ==‘TOP’:

This gives no warning at all. But is disfunctional. It does simply nothing. Seems that i have not the right connection here.

How do i get the current view of the current 3D window here?

Current code:

import bpy

view_matrix = ((0.41, -0.4017, 0.8188, 0.0),
               (0.912, 0.1936, -0.3617, 0.0),
               (-0.0133, 0.8959, 0.4458, 0.0),
               (0.0, 0.0, -14.9892, 1.0))
               
for area in bpy.context.screen.areas:
    if area.type == 'VIEW_3D':
        rv3d = area.spaces[0].region_3d
        if rv3d is not None:
            
            if rv3d.view_perspective == 'PERSP':
                
                if bpy.ops.view3D.viewnumpad =='TOP':
                #if bpy.ops.view3D.viewnumpad(type='TOP')
            
                    rv3d.view_distance = 15
                    rv3d.view_matrix = view_matrix
                    
            if rv3d.view_perspective == 'ORTHO':
                rv3d.view_distance = 15
                rv3d.view_matrix = view_matrix

Attachments


Now it’s getting odd. I checked how the view matrix looks like in top view. And it’s the very same as from the angled view O_O

One more step and i still hang :frowning:

I tried to get the views by reading the quaternions. But Blender doesn’t accept the very same values that it writes to the console. What is going on here? A precision problem?

import bpy


viewmode = "none"

view_matrix = ((0.41, -0.4017, 0.8188, 0.0),
               (0.912, 0.1936, -0.3617, 0.0),
               (-0.0133, 0.8959, 0.4458, 0.0),
               (0.0, 0.0, -14.9892, 1.0))
               
for area in bpy.context.screen.areas:
    if area.type == 'VIEW_3D':
        rv3d = area.spaces[0].region_3d
        if rv3d is not None:
                 
            viewrot = area.spaces[0].region_3d.view_rotation
            print (viewrot)
            if viewrot == (1.0000,-0.0000,-0.0000,-0.0000):
                viewmode = "TOP"
                print (viewmode)

Operators can only be called with properties, you can’t query information or get objects returned:

http://www.blender.org/documentation/blender_python_api_2_69_10/info_quickstart.html#operators-tools
http://www.blender.org/documentation/blender_python_api_2_69_10/bpy.ops.html

What is shown in the 3D View top-left corner is not a property we could read with python. Here’s a workaround:

A classmethod gets the class passed on call, not the class instance (object), that’s why it reads (cls, context) and not (self, context).
This is needed to make methods callable from outside, they can only act on the class however. poll() is a classmethod so that you can test if the operator can be run before you call it (an operator instance is created on call, so you couldn’t call a regular method, as you wouldn’t have an object yet).

Thank you :slight_smile:

Does this belong to the try to read Top directly? Or to the quaternion problem? Honestly i am miles away from understanding what you want me to tell here. Even after reading the linked pages. I am by no means a programmer. I have just used scripting languages so far. I fear i need a simple example :slight_smile:

At least i know now that there is no direct way to read the top view. I have found the linked stackexchange page before, a bit earlier this morning. But i am unsure how to incorporate it into my code. It gave me errors all the time. That’s why i tried the quaternion way then. Which should also work, at least with my limited understanding.

But as told above, it doesn not compare correct. The values are the ones from the console. It’s in fact the same quaternion that gets printed to the console. Yet it does not say they are equal when i use code to compare them. Why?

Does this belong to the try to read Top directly?

Yes!

Quaternion: You’re comparing a quat with a tuple of floats, these two different types will never be equal


>>> C.screen.areas[2].spaces[0].region_3d.view_rotation = 1,1,1,1 # is doesn't assign a tuple, it's rather cast to a Quaternion

>>> C.screen.areas[2].spaces[0].region_3d.view_rotation
Quaternion((1.0, 1.0, 1.0, 1.0))

>>> C.screen.areas[2].spaces[0].region_3d.view_rotation == (1.0,1.0,1.0,1.0)
False

>>> C.screen.areas[2].spaces[0].region_3d.view_rotation == Quaternion((1.0,1.0,1.0,1.0))
True

It gave me errors all the time

What errors?
The one I posted works there works fine in 2.69, but you can’t copy&paste it directly into your script of course (you would end up with multiple register() functions etc.)

You should use an approach similar to what is shown there, as you won’t run into floating point precision problems.

Every time i tried to get a result i got an error. But i cannot remember what it was. I couldn’t get it to work.

Tobain from the german forum has meanwhile shown me where my errors were with the quaternion. And you name it too. I compared a quat with a tuple of values. Plus i had no mathutils imported. Plus i had to name it with double set of brackets and with mathutils.Quaternion:

if viewrot == mathutils.Quaternion((1.0000,-0.0000,-0.0000,-0.0000)):

I would’ve never known this by myself. Now it works and compares fine. This code here prints me Top at the console now when i am in top view:

import bpy
import mathutils
q = mathutils.Quaternion((1,0,0,0))


viewmode = "none"

view_matrix = ((0.41, -0.4017, 0.8188, 0.0),
               (0.912, 0.1936, -0.3617, 0.0),
               (-0.0133, 0.8959, 0.4458, 0.0),
               (0.0, 0.0, -14.9892, 1.0))
               
for area in bpy.context.screen.areas:
    if area.type == 'VIEW_3D':
        rv3d = area.spaces[0].region_3d
        if rv3d is not None:
            
            viewrot = area.spaces[0].region_3d.view_rotation
            print (viewrot)
            if viewrot == mathutils.Quaternion((1.0000,-0.0000,-0.0000,-0.0000)):
                viewmode = "TOP"
                print (viewmode)

Now i have a way to check if i am in top, right, front view, and can change the view according to that. Let’s have a look to get it to work now :slight_smile:

Many thanks for your help and patience. I know that i ask for alot here :slight_smile:

Nearly done. The code works with the top, etc. views now too. Here it does not reset the matrix anymore, but just resets the view_distance. The camera orientation is already fitting anyways.

I have renamed the plugin to reset 3D view, since there is already a feature called reset view in the 2D.view somewhere. Stumbled across when i was in hunt for the hotkey.

Version is 0.9 now. Hotkey works too. I have borrowed your asterisk key when you don’t mind :slight_smile:

Mh, the view resets to world center with localview too. I dunno if we really need a reset to localview feature since look at selection or two times hit localview hotkey does the same here.

Currently there are still my debugging print tags in the code. Will remove them for version 1.0 then. But first let me test the plugin a bit. You never know what side effects or new quirks appears. Maybe you have the one or another idea for code improvements or cleanups here too.

Since it was a learning project for me, and most of the code is from you guys, am i allowed to put it to the wiki under my name? Shall we share the names in the credits? Do you want to put it to the wiki? Basically i don’t really mind here. All i am interested in is to have it in the Wiki and in Blender at one point. It’s one of those small things that i think that makes Blender better. For me it would be a learning experience to put the Script into the wiki too. Never did that before …

At that point again many thanks for all the help and the patience with me :slight_smile:

Version 0.9:

# Big Thanks for the help with the code goes to pink vertex and CoDEmanX at the Blenderartists forum, and to Tobain at the german Blendpolis forum

bl_info = {
    "name": "Reset 3D View",
    "description": "Resets the views of all 3D windows to standard view",
    "author": "Reiner 'Tiles' Prokein",
    "version": (0, 9),
    "blender": (2, 69, 0),
    "location": "View3D > View",
    "warning": "", # used for warning icon and text in addons panel
    ## not yet ...
#    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"
#                "Scripts/My_Script",
    "category": "View"}


import bpy
import mathutils



class Reset3dView(bpy.types.Operator):
    """Reset 3D View"""
    bl_idname = "view.reset_view"
    bl_label = "Reset 3D View"
    bl_options = {'REGISTER', 'UNDO'}

    def execute(self, context):
        
        viewmode = "none"
        
        view_matrix = ((0.41, -0.4017, 0.8188, 0.0), # This is the view matrix from Factory settings
               (0.912, 0.1936, -0.3617, 0.0),
               (-0.0133, 0.8959, 0.4458, 0.0),
               (0.0, 0.0, -14.9892, 1.0))
               
        for area in bpy.context.screen.areas:
            if area.type == 'VIEW_3D':
                rv3d = area.spaces[0].region_3d
                if rv3d is not None:
                    # --------------------------- check for views -----------------------------------------------------------
                    # We check if the view is in top, left, etc. by comparing the quaternion of the region3d.view_rotation                    
                    viewrot = area.spaces[0].region_3d.view_rotation
                    print (viewrot)

                    if viewrot == mathutils.Quaternion((1.0000,-0.0000,-0.0000,-0.0000)):
                        viewmode = "TOP"
                        print (viewmode)
                    if viewrot == mathutils.Quaternion((0.7071, 0.7071,-0.0000,-0.0000)):
                        viewmode = "FRONT"
                        print (viewmode)
                    if viewrot == mathutils.Quaternion((0.5000, 0.5000, 0.5000, 0.5000)):
                        viewmode = "RIGHT"
                        print (viewmode)
                    if viewrot == mathutils.Quaternion((0.0000, 1.0000,-0.0000,-0.0000)):
                        viewmode = "BOTTOM"
                        print (viewmode)
                    if viewrot == mathutils.Quaternion((0.0000,-0.0000, 0.7071, 0.7071)):
                        viewmode = "BACK"
                        print (viewmode)
                    if viewrot == mathutils.Quaternion((0.5000, 0.5000,-0.5000,-0.5000)):
                        viewmode = "LEFT"
                        print (viewmode)
                                
                    #------------------------------set the views -----------------------------------------------------------
                    # When it is top, front etc. then just the distance gets resettet The rotation already fits.
                    if viewmode == "TOP":
                        print ("successwithtop")
                        rv3d.view_distance = 15 # This is the original distance to the zero point from Factory settings.
                    if viewmode == "FRONT":
                        print ("successwithfront")
                        rv3d.view_distance = 15 # This is the original distance to the zero point from Factory settings.
                    if viewmode == "RIGHT":
                        print ("successwithright")
                        rv3d.view_distance = 15 # This is the original distance to the zero point from Factory settings.
                    if viewmode == "BOTTOM":
                        print ("successwithbottom")
                        rv3d.view_distance = 15 # This is the original distance to the zero point from Factory settings.
                    if viewmode == "BACK":
                        print ("successwithback")
                        rv3d.view_distance = 15 # This is the original distance to the zero point from Factory settings.
                    if viewmode == "LEFT":
                        print ("successwithleft")
                        rv3d.view_distance = 15 # This is the original distance to the zero point from Factory settings.
                    if viewmode == "none":
                        print ("successwithuserview")
                        rv3d.view_distance = 15 # This is the original distance to the zero point from Factory settings.
                        rv3d.view_matrix = view_matrix # This resets the location and rotation back to the initial view matrix values
                        
                    # ----------- final bit, reset the viewmode variable for the next try
                    viewmode = "none"

        return {'FINISHED'}
    
def menu_func(self, context):
    self.layout.operator(Reset3dView.bl_idname)
    
# store keymaps here to access after registration
addon_keymaps = []
   

def register():
    bpy.utils.register_class(Reset3dView)
    bpy.types.VIEW3D_MT_view.append(menu_func)
    
    # handle the keymap
    wm = bpy.context.window_manager
    km = wm.keyconfigs.addon.keymaps.new(name='3D View', space_type='VIEW_3D')
    kmi = km.keymap_items.new(Reset3dView.bl_idname, 'NUMPAD_ASTERIX', 'PRESS', ctrl=False, shift=False)
    addon_keymaps.append((km, kmi))

def unregister():
    bpy.utils.unregister_class(Reset3dView)
    bpy.types.VIEW3D_MT_view.remove(menu_func)
    
    # handle the keymap
    wm = bpy.context.window_manager
    for km in addon_keymaps:
        wm.keyconfigs.addon.keymaps.remove(km)
    # clear the list
    del addon_keymaps[:]


if __name__ == "__main__":
    register()
            
            
            

And again i hang. It works for five out of six views. But front and back view refuses to trigger. The quaternion values are correct. I have triple checked them. They print to console with every try for debugging reasons. And the code is the same. I am clueless :frowning:

Corecode to check:

import bpy
import mathutils

viewmode = "none"

view_matrix = ((0.41, -0.4017, 0.8188, 0.0), # This is the view matrix from Factory settings
               (0.912, 0.1936, -0.3617, 0.0),
               (-0.0133, 0.8959, 0.4458, 0.0),
               (0.0, 0.0, -14.9892, 1.0))
               
for area in bpy.context.screen.areas:
    if area.type == 'VIEW_3D':
        rv3d = area.spaces[0].region_3d
        if rv3d is not None:
            
            # --------------------------- check for views -----------------------------------------------------------
            # We check if the view is in top, left, etc. by comparing the quaternion of the region3d.view_rotation                    
            viewrot = area.spaces[0].region_3d.view_rotation
            print (viewrot)

            if viewrot == mathutils.Quaternion((1.0000,-0.0000,-0.0000,-0.0000)):
                viewmode = "TOP"
                print (viewmode)
            if viewrot == mathutils.Quaternion((0.7071, 0.7071,-0.0000,-0.0000)):
                viewmode = "FRONT"
                print (viewmode)
            if viewrot == mathutils.Quaternion((0.5000, 0.5000, 0.5000, 0.5000)):
                viewmode = "RIGHT"
                print (viewmode)
            if viewrot == mathutils.Quaternion((0.0000, 1.0000,-0.0000,-0.0000)):
                viewmode = "BOTTOM"
                print (viewmode)
            if viewrot == mathutils.Quaternion((0.0000,-0.0000, 0.7071, 0.7071)):
                viewmode = "BACK"
                print (viewmode)
            if viewrot == mathutils.Quaternion((0.5000, 0.5000,-0.5000,-0.5000)):
                viewmode = "LEFT"
                print (viewmode)
                        
            #------------------------------set the views -----------------------------------------------------------
            # When it is top, front etc. then just the distance gets resettet The rotation already fits.
            if viewmode == "TOP":
                print ("successwithtop")
                rv3d.view_distance = 15 # This is the original distance to the zero point from Factory settings.
                #rv3d.view_matrix = view_matrix # This resets the location and rotation back to the initial view matrix values
            if viewmode == "FRONT":
                print ("successwithfront")
                rv3d.view_distance = 15 # This is the original distance to the zero point from Factory settings.
                #rv3d.view_matrix = view_matrix # This resets the location and rotation back to the initial view matrix values
            if viewmode == "RIGHT":
                print ("successwithright")
                rv3d.view_distance = 15 # This is the original distance to the zero point from Factory settings.
                #rv3d.view_matrix = view_matrix # This resets the location and rotation back to the initial view matrix values
            if viewmode == "BOTTOM":
                print ("successwithbottom")
                rv3d.view_distance = 15 # This is the original distance to the zero point from Factory settings.
                #rv3d.view_matrix = view_matrix # This resets the location and rotation back to the initial view matrix values
            if viewmode == "BACK":
                print ("successwithback")
                rv3d.view_distance = 15 # This is the original distance to the zero point from Factory settings.
                #rv3d.view_matrix = view_matrix # This resets the location and rotation back to the initial view matrix values
            if viewmode == "LEFT":
                print ("successwithleft")
                rv3d.view_distance = 15 # This is the original distance to the zero point from Factory settings.
                #rv3d.view_matrix = view_matrix # This resets the location and rotation back to the initial view matrix values
            if viewmode == "none":
                print ("successwithnone")
                rv3d.view_distance = 15 # This is the original distance to the zero point from Factory settings.
                rv3d.view_matrix = view_matrix # This resets the location and rotation back to the initial view matrix values
                
            # ----------- final bit, reset the viewmode variable for the next try
            viewmode = "none"