I want to be able to take a function f(x) and first make a plot of the function on given interval and then build a solid of revolution of that mesh by rotating it around X-axis of the plot.
I've made a script that generates the graph. My question is how to spin the mesh (360° angle).
I tried to use function bpy.ops.mesh.spin
:
bpy.ops.mesh.spin(steps=36, angle=2*pi, axis=(1, 0, 0))
but I still get RuntimeError
Traceback (most recent call last):
File "<blender_console>", line 1, in <module>
File "C:\Program Files\Blender Foundation\Blender\2.72\scripts\modules\bpy\ops.py", line 188, in __call__
ret = op_call(self.idname_py(), None, kw)
RuntimeError: Operator bpy.ops.mesh.spin.poll() failed, context is incorrect
My code for generating graph mesh of given function:
# User function (return None if undefined)
def user_function(x):
"Math function for given X, returns Y"
if x == 0:
return None
return 1/x
# Resolution - number of samples
res = 100
# MIN and MAX values for the graph to plot
minX = 1
maxX = 10
minY = 0
maxY = 1
# Real size of a rectangle of the graph
sizeX = 2
sizeY = 2
# Recalculate Y-value for undefined points
recalculate_undefined = True
# Whether to delete old object
delete_old = True
# ===== Program =====
import bpy
step = (maxX - minX) / (res - 1)
coefX = sizeX / (maxX - minX)
coefY = sizeY / (maxY - minY)
RminX = - sizeX / 2
RminY = - coefY * minY
Z = 0
vertices = []
undefined = []
# Calculate values
for ix in range(res):
x = minX + step * ix
# Calculate and store Y-value
y = user_function(x)
if y == None:
undefined.append(ix)
y = 0
y = min(maxY, y)
y = max(minY, y)
cX = step * ix * coefX + RminX
cY = y * coefY + RminY
cZ = Z
vertices.append((cX, cY, cZ))
# Calculate undefined points
if recalculate_undefined == True:
for ix in undefined:
avg = []
if ix > 0 and (ix - 1) not in undefined:
avg.append(ix - 1)
if ix < (res - 1) and (ix + 1) not in undefined:
avg.append(ix + 1)
if len(avg) >= 1:
y = 0
for a in avg:
y += vertices[a][1]
y /= len(avg)
vertices[ix] = (vertices[ix][0], y, Z)
# Delete old object
if delete_old == True:
if "Graph" in bpy.data.objects:
bpy.ops.object.select_all(action = 'DESELECT')
bpy.data.objects["Graph"].select = True
bpy.ops.object.delete()
for item in bpy.data.meshes:
if item.users == 0:
bpy.data.meshes.remove(item)
# Create new mesh
mesh = bpy.data.meshes.new("graph")
# Build edges from vertices
edges = [(ix, ix + 1) for ix in range(res - 1)]
faces = []
# Complete mesh and build object
mesh.from_pydata(vertices, edges, faces)
object = bpy.data.objects.new("Graph", mesh)
bpy.context.scene.objects.link(object)
object.location = bpy.context.scene.cursor_location
Edit1:
This post is not a duplicate of poll() failed, context incorrect? - Example: bpy.ops.view3d.background_image_add().
I'm looking for a solution without only avoiding the error by changing contexts.