# There is apparently no need to change the directory for Blender 2.7 as it's in the .blend file
# directory by default.
# This script creates a surface from one or multiple input files. By default
# it assumes many - just edit the filename manually to use a single file.
# File format is x,y,z,value.
import numpy
import bpy
import math
filebase = 'M33AndMilkyWay'
# Get the current frame
frame = bpy.context.scene.frame_current
filename = filebase+'_'+str(frame).zfill(3)+'.txt'
# Read in the data from the correct file
data = numpy.genfromtxt(filename)
sizex = int(numpy.max(data[:,0]))+1
sizey = int(numpy.max(data[:,1]))+1
# Get the minimum flux
minf = abs(numpy.nanmin(data[:,3]))
# Create a new mesh
me = bpy.data.meshes.new('Surface')
# Create a list of vertices
verts = []
for x in range(0,sizex):
for y in range(0,sizey):
verts.append((x,y,0))
# Now fill in the faces. At each i index of any vertex, assume it's the lower left corner of a
# face. Increasing the index will increae first the y row and then (when it reaches the very top)
# the x row). So we need a list of the vertices on the top row (toplist) to check that our
# assumption is valid.
toplist = []
for i in range(sizey-1,sizex*sizey,sizey):
toplist.append(i)
# We also need the index of the final vertex where this is possible. This one left and one down of
# the final vertex.
# Each x column increases in steps of sizey
# So the last but one x column will begin with the value :
final = (sizey*(sizex-2)) + (sizey-2)
# It's -2 because we count from zero and we want one less than the maximum anyway.
i = 0
faces = []
while i <= final:
faces.append([i,i+sizey,i+sizey+1,i+1])
i = i +1
if i in toplist:
i = i +1
# Create the mesh. Syntax is verts list, edge list, face list
me.from_pydata(verts, [], faces)
# Create the object
obj = bpy.data.objects.new('Surface', me)
# Now we can move the vertex positions. Apparently vertex data is now extracted from object data,
# not mesh data.
mesh = obj.data
# Get the median level of the surface so we can keep all the planes at the
# same level
medflux = 200.0*math.sqrt(numpy.nanmedian(data[:,3])+minf+1.0)
for i in range(0,data.shape[0]):
xp = data[i,0]
yp = data[i,1]
flux = data[i,3]
mesh.vertices[i].co.x = xp
mesh.vertices[i].co.y = yp
mesh.vertices[i].co.z = (200.0*math.sqrt(flux+minf+1.0)) - medflux
# Add the object to the current scene
scene = bpy.context.scene
scene.objects.link(obj)
# For reference
# scene.objects.active = obj
# obj.select = True
# To get index of currently selected vertex or vertices (must be in object mode)
#[i.index for i in bpy.context.active_object.data.vertices if i.select == True]