I went away and learned some OO in python, and now I will pick up where I left off - creating mesh objects from mathematical expressions. In the simple test below, I would like to cleanly trim the tops and bottoms of the surfaces where they would intersect planes at Z = +1 and Z = -1. So far I just append faces which have at least one vertex inside. (there are probably unused vertices which I should clean up at some point).
I am hoping there is a simple way to trim this (or future) object at Z = +/-1 within the script. There are probably a number of possible ways to do this - what would be most helpful is both a few lines of script and a pointer to the relevant documentation on mesh object methods so I can dig in and learn. Any other pointers/suggestions would be helpful. I hope to plot some pretty complicated stuff, so helping me starting off on the right track would be greatly appreciated!
Note: An alternative approach would be to calculate the exact intersections myself, but for math more complicated than just np.tan() I'd have to use something like
from scipy import fsolve
to find the intersection with the planes, and that's another issue.
import bpy
import numpy as np
pi = np.pi
nx, ny = 40, 21
x = pi * np.linspace(-0.475, 1.475, nx)
y = pi * np.linspace( 0.0, 2.0, ny)
X, Y = np.meshgrid(x, y)
Z = np.tan(X + Y)
verts = []
for iy in range(ny):
for ix in range(nx):
vert = (X[iy,ix], Y[iy,ix], Z[iy,ix])
verts.append(vert)
lo, hi = -1.0, 1.0
faces = []
for iy in range(ny-1):
for ix in range(nx-1):
i = ix + nx*iy
face = (int(i), int(i+1), int(i+nx+1), int(i+nx))
highpoint = max([verts[iv][2] for iv in face])
lowpoint = min([verts[iv][2] for iv in face])
# if face has at least one vertex inside hi-lo range,
# but doesn't cross Z=0 (by more than a little)
if (highpoint > lo and lowpoint < hi) and highpoint*lowpoint >= -0.1:
faces.append(face)
# alternatively could I remove them later using some things such as
# faces.pop() and face.co[:][2]???
meshthing = bpy.data.meshes.new("Tan")
object = bpy.data.objects.new("Tan", meshthing)
object.location = (0,0,0) #bpy.context.scene.cursor_location
bpy.context.scene.objects.link(object)
meshthing.from_pydata(verts,[],faces)
#meshthing.update(calc_edges=True)
mat = bpy.data.materials.new("PKHG")
mat.diffuse_color = (float(1.5),0.0,1.0)
mat.specular_color = (200.0,1.0,100.0)
object.active_material = mat
mypolys = meshthing.polygons
for p in mypolys:
p.use_smooth = True
# this helps ensure it's visible and selected
bpy.data.objects['Tan'].select = False
bpy.data.objects['Tan'].select = True
print_info = False
for item in bpy.data.objects:
print(item.name)
if item.type == 'MESH' and print_info:
for vertex in item.data.vertices:
print(vertex.co)
# This doesn't work yet
for face in item.data.tessfaces:
print(face.co)