2
$\begingroup$

I know a little bit of Javascript but don't have a lot of experience scripting in blender or Python. I've tried to set the Radius of the new Circle Select tool by code as it's not possible to use a scroll wheel my Wacom pen naturally, also the new radius if set by the mouse wheel does not persist as it does with the old modal circle select by using f + scroll wheel and that tool is bad as you can't move around in the viewport while it's active. My plan is to hook the script up to some keyboard shortcut etc.

I've tried to change it by something like this

import bpy

#switch context
previous_context = bpy.context.area.type
bpy.context.area.type = 'VIEW_3D'

#bpy.op.VIEW3D_OT_select_circle.radius = 30
bpy.ops.view3d.select_circle(x=300, y=150, radius=300, gesture_mode = 3)
#restore previous context
bpy.context.area.type = previous_context

or

VIEW3D_OT_circle_select.radius = 90

But I can't get it to work. What am I doing wrong, is the circle select radius property simply not possible to set from Python?

$\endgroup$

1 Answer 1

2
$\begingroup$

What you are trying to do is change the current context. Instead, you should just be overriding the context.

First step for that would be finding the context that you want to use, that would be our VIEW3D REGION for this case, so we can just cycle through all the context screens available till we find VIEW_3D

for area in bpy.context.screen.areas:
    if area.type == "VIEW_3D":
        #Do stuff

Now just the area itself is not enough as there are different regions inside an area. For our use case we will be needing the window region.

for region in area.regions:
            if region.type == "WINDOW":
                #Do stuff

Now we the required components to define a new context. What we can do is clone our current context and replace its area and region with the ones we just found.

for area in bpy.context.screen.areas:        #Cycle through all the avaliable areas
    if area.type == "VIEW_3D":               #if area is called VIEW_3D
        for region in area.regions:          #Cycle through all the regions in that area
            if region.type == "WINDOW":      #if the region is WINDOW
                view3dArea = area            #save the area and region in variables
                view3dRegion = region
                break                        #exit the loops

override = bpy.context.copy()                #Make a copy of current context
override['area'] = view3dArea                #Change area to the one we just found
override['region'] = view3dRegion            #Same with the region

Now that we have the right context we just need to pass it into the function. Simply done by passing it as the first argument as its positional argument.

bpy.ops.view3d.select_circle(override, Other stuff)

You can make a simple function out of this so you can call it whenever you want.

import bpy
def select(x,y,rad):
    for area in bpy.context.screen.areas:
    if area.type == "VIEW_3D":
        for region in area.regions:
            if region.type == "WINDOW":
                view3dArea = area
                view3dRegion = region
                break
    override = bpy.context.copy()
    override['area'] = view3dArea
    override['region'] = view3dRegion
    bpy.ops.view3d.select_circle(override,x=x, y=x, radius=rad, mode='SET')

Simply call that function with the desired radius and coordinates.

select (300,200,50)

enter image description here

Or you can change the radius and get a bigger selection

select (300,200,100)

enter image description here

$\endgroup$
1
  • $\begingroup$ While the script works as you intended, it's still not persistently changing the radius of the Circle Select (as you can see here imgur.com/yc2CAbA) which is what I really want. $\endgroup$
    – JoelArt
    Mar 22, 2020 at 4:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .