2

I'm hoping someone can help me use the 3DView->Edit Mode builtin tool 'spin'. I've extruded a number of vertices and their edges to form a (closed) 2D face. The object is named called 'RocketNozzle'. I want to use Python to 'spin' this face around the z-axis. I can do this manually from the 3DView editor, but am running into problems using Python to script it. The code below shows my current attempt. I'm basing my approach on these two articles:

I know the line with bpy.ops.wm.tool_set_by_id(override_context, name="builtin.spin") is working, because the spin tool is shown active after this line executes.

But I can't get a reference to the active tool back into the script! I think if I can successfully get a reference to the active (spin) tool, that I can set the three properties I want, and then call tool.Execute() ?? to make the spin occur. I just can't seem to get a valid reference to the tool back into the script.

TIA for any help, insights, or links!

# lots of code to get to this point ...

The object at this point is a two-dimensional face having many vertices/edges that form the outlines of the inner and outer walls of a complex curved surface

rotate the face around the z-axis

Select the entire object

bpy.ops.object.mode_set(mode = 'OBJECT') obj = bpy.data.objects[PartName]

Go to Edit Mode

bpy.ops.object.mode_set(mode = 'EDIT')

Select all of the vertices

bpy.ops.mesh.select_mode(type="VERT") bpy.ops.mesh.select_all(action = 'SELECT')

Spin them all around the z-axis

Select the builtin Spin tool from the Object->Edit menu

how to change a tool through the Blender API

how to set the active tool

area = [area for area in bpy.context.screen.areas if area.type == "VIEW_3D"][0] override_context = bpy.context.copy() override_context['window'] = bpy.context.window override_context['screen'] = bpy.context.screen override_context['area'] = area override_context['region'] = area.regions[-1] override_context['scene'] = bpy.context.scene override_context['space_data'] = area.spaces.active

Set the active tool to be the spin tool

bpy.ops.wm.tool_set_by_id(override_context, name="builtin.spin")

Get the active tool

(https://blender.stackexchange.com/questions/178959/enable-disable-3d-cursor-tool-properties-from-python)

from bl_ui.space_toolsystem_common import ToolSelectPanelHelper

######################

Manual steps here, 'cause the next line throws an exception

tool = ToolSelectPanelHelper.tool_active_from_context(override_context)

Using override_context in the line above, throws an exception :

line 710, in tool_active_from_context

space_type = context.space_data.type

AttributeError: 'dict' object has no attribute 'space_data'

tool = ToolSelectPanelHelper.tool_active_from_context(bpy.context)

Using bpy.context as shown in the lineabove causes the next line to fail with the message

AttributeError: 'NoneType' object has no attribute 'steps'

tool.steps = 32 tool.angle = 360 tool.axis = [0,0,1]

Make it spin somehow

tool.Execute() # not sure if this is correct....

End area of manual steps

######################

copy the lines from here to the end and paste them into Blender's Python Console

remove duplicates again, to ensure the spin did not add any extra unwanted vertices

also change the merge distance (make it larger) in case the duplicate vertices from the spin don't quite line up exactly

bpy.ops.mesh.remove_doubles(threshold=0.01, use_unselected=True)

more code here...

```

  • Instead of messing with changing the tool, just call it directly? bpy.ops.mesh.spin(angle=3.14159, center=(0,0,0), axis=(0,0,1)) – Ron Jensen Oct 28 '21 at 23:43
  • 1
    Personally would ditch using the tools / operators completely. Related https://blender.stackexchange.com/questions/212786/how-to-create-cylinder-with-varying-radius-at-different-height/212816#212816 and https://blender.stackexchange.com/questions/114126/how-do-i-draw-a-parametric-column-or-cylinder-with-varying-radius-using-python/114129#114129 – batFINGER Oct 29 '21 at 02:49

1 Answers1

0

I agree with Ron Jensen's comment. There's no reason to override the spin tool, just invoke it with settings that accomplish your goal. You can replace most of your code with:

# lots of code to get to this point ...

The object at this point is a two-dimensional face having many vertices/edges that form the outlines of the inner and outer walls of a complex curved surface

rotate the face around the z-axis

Select the entire object

bpy.ops.object.mode_set(mode = 'OBJECT') obj = bpy.data.objects[PartName]

Go to Edit Mode

bpy.ops.object.mode_set(mode = 'EDIT')

Select all of the vertices

bpy.ops.mesh.select_mode(type="VERT") bpy.ops.mesh.select_all(action = 'SELECT') bpy.ops.mesh.spin(steps=32, angle=2*pi, center=(0,0,0), axis=(0,0,1))

remove duplicates again, to ensure the spin did not add any extra unwanted vertices

also change the merge distance (make it larger) in case the duplicate vertices from the spin don't quite line up exactly

bpy.ops.mesh.remove_doubles(threshold=0.01, use_unselected=True)

that is, delete everything between

# Spin them all around the z-axis

and

# copy the lines from here to the end and paste them into Blender's Python Console

inclusive and replace them with

bpy.ops.mesh.spin(steps=32, angle=2*pi, center=(0,0,0), axis=(0,0,1))

This has the added bonus that it won't throw exceptions and you can execute it all within the script.

Marty Fouts
  • 33,070
  • 10
  • 35
  • 79