How can I tell the difference between two of the same area types?

I have two VIEW_3D area types open. Is there a way to differentiate between the two in Python, or possibly tag them for that purpose? I want to make a button for the render menu of the properties panel which will change one of the VIEW_3D area types to “Rendered” viewport shading mode.

Areas and Spaces don’t support ID properties.

But you can check certain properties, like width and height of an area maybe.

Regions have IDs:
http://www.blender.org/documentation/blender_python_api_2_71_release/bpy.types.Region.html?highlight=region.id#bpy.types.Region.id

Thanks. Well I’m working on an addon so I don’t suppose a method like this would be very stable if the user started moving the screen around. Is there a way I could target a 3D View area type based on it being in the perspective of a camera? Or is there perhaps a camera command command for “Rendered” viewport shading? Thanks again.

I would use a region’s as_pointer() instead of id. Region ids are unique, but they cannot be used to identify a specific region, as they are not guaranteed to remain the same. If you maximize and restore other areas, the region ids tend to change where the region’s pointer value does not.

Note: Do not use area pointers, only region pointers. I usually use the area’s ‘WINDOW’ region.

Thanks SynaGl0w. Could you maybe post a one or two liner demonstrating how you use region pointers? I don’t even know what those would be concatenated with.

Just call the region’s as_pointer() method. It returns the pointer as an int.

I don’t know how to do that. If you don’t want to take the time to write a line explaining what that looks like, that’s ok, just making sure.

Simple as:
unique_value = region.as_pointer()

region being assigned the ‘WINDOW’ region of the area you want to identify.

Oi, lol. You weren’t kidding, that’s very short and simple. I’m not sure how to first assign region as the 3D View area type to get its pointer value. I’m very unfamiliar with this realm of Python within Blender. Could you possibly write me or direct me to an example of this in action? If that’s getting too tedious that’s fine, I may just need to do some more research than I want too before I can process this. Thanks.

for area in bpy.context.screen.areas:
    if area.type == 'VIEW_3D':
        for region in area.regions:
            if region.type == 'WINDOW':
                print(region.as_pointer())
                break

You might also try:

hash(region)

to get an unique identifier.

Sorry to reply so late to this thread. Thanks for all the responses. CoDEmanX the script works only the values for the pointers change everytime I open up Blender, Same with using hash(region) as mentioned by pink vertex. The values change each time so I don’t know how I could use either method to identify a specific 3D View when they change every time I open Blender.

Also, even when only running Blender once I can’t seem to use this code to target in a command on a specific window. Anyone know what’s wrong?

import bpy

for area in bpy.context.screen.areas:
    if area.type == 'VIEW_3D':
        for region in area.regions:
            if region.type == 'WINDOW':
                print(region.as_pointer())
                
                region = region.as_pointer()
                if region == 68624488:
                    bpy.context.space_data.viewport_shade = 'RENDERED'
                
                break

This just gives me an error. Ideally I’d like to be able to do stuff to a specific 3D View window once I am able to specify it.

Of it changes. I really wonder why you try to treat an area like an individual object - it simply is not. There are plenty other properties you could use, like size, position etc. to find a suitable one.

I’m afraid your comment got cut off there, not sure what you were saying before “Of it changes”. Why do I want to treat an area like an individual object? I simply want to be able to nest buttons in the properties panel which can affect a specific 3D View window’s settings such as viewport shading.

Pointers, hashes, etc. are all runtime unique, thus work for identifying things during runtime.

If you’re looking for constant way between runs to identify areas, I guess you could try just using the index for the areas you want of the active screen. I think those remain constant between runs, though I am not sure.

Example:

for index, area in enumerate(C.screen.areas):
    print("{}: {}".format(index, area.type))

The real question then becomes: With multiple areas of the same type how do you know which one is which? Well you can just figure it out in the console and hard-code the index when you access different areas, or you can go by area type and size (largest/smallest, etc.).

For example this sets the smallest View3d to rendered mode:

import bpy

v3d_list = [area for area in bpy.context.screen.areas if area.type == 'VIEW_3D']
if v3d_list:
    smallest_area = min(v3d_list, key=lambda area: area.width * area.height)
    smallest_area.spaces.active.viewport_shade = 'RENDERED'

SynaGl0w that’s perfect. This gives a lot potential control for testing. Thanks all!

I meant to say “Of course it changes.” (SynaGl0w explained why)

If you want to affect a certain Area via a button, you would usually add an operator to the T or N toolshelf of that area. Run your operation on bpy.context.area, which will refers to the area the toolshelf region belongs to.

Imagine one control area that allows you to manipulate multiple screens where all of the headers and menus are closed on each screen giving you a clean presentation. Or perhaps you create presets which can run multiple settings on different screens so you can see the difference immediately. Targeting specific view screens allows you to do this. Awesomely, you guys helped me figure out how to do it today.