# 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]