import Blender import os import struct from Blender import * from Blender import Lamp from Blender.Scene import Render from Blender.Draw import * from Blender.BGL import * from Blender import Registry from Blender import Text from math import * #globals #get the root directory that the current file is in #we'll write the muray files there. path = Blender.Get('filename') tokens = path.split('\\') fileName = tokens.pop(); file = fileName.split('.') fileName = file[0] path ='' for i in tokens: path = path + i + '\\' def export(): #open a file to export to f = open(path + fileName + '.mra','wb') s = open(path + fileName + '.mrb','wb') f.write('muRay scene description\n') f.write(' ') def writeln(out): f.write(out + '\n') def fmt(input): return '%5.5f' %input def point_by_matrix(p, m): return [p[0] * m[0][0] + p[1] * m[1][0] + p[2] * m[2][0] + m[3][0], p[0] * m[0][1] + p[1] * m[1][1] + p[2] * m[2][1] + m[3][1], p[0] * m[0][2] + p[1] * m[1][2] + p[2] * m[2][2] + m[3][2]] def vector_by_matrix(p, m): return [p[0] * m[0][0] + p[1] * m[1][0] + p[2] * m[2][0], p[0] * m[0][1] + p[1] * m[1][1] + p[2] * m[2][1], p[0] * m[0][2] + p[1] * m[1][2] + p[2] * m[2][2]] def contain(min, max, point): for v in point: if v[0] < min[0]: min[0] = v[0] if v[1] < min[1]: min[1] = v[1] if v[2] < min[2]: min[2] = v[2] if v[0] > max[0]: max[0] = v[0] if v[1] > max[1]: max[1] = v[1] if v[2] > max[2]: max[2] = v[2] def containSphere(min,max,sphere): radius = sphere.getSize()[0] if min[0] > sphere.LocX-radius: min[0] = sphere.LocX-radius if min[1] > sphere.LocY-radius: min[1] = sphere.LocY-radius if min[2] > sphere.LocZ-radius: min[2] = sphere.LocZ-radius if max[0] < sphere.LocX+radius: max[0] = sphere.LocX+radius if max[1] < sphere.LocY+radius: max[1] = sphere.LocY+radius if max[2] < sphere.LocZ+radius: max[2] = sphere.LocZ+radius #Grab the scene scn = Scene.GetCurrent() context = scn.getRenderingContext() obj = Blender.Object.Get() #export general scene data #background color w=Blender.World.Get() scene = Blender.Scene.GetCurrent().getChildren() writeln('') #create the baked textures list baked_maps=[] #create a materials list material_array =[] materials = Material.get() for m in materials: refFile = "NULL"; textureFile = "NULL"; alphaFile = "NULL"; normalFile = "NULL"; emitFile = "NULL"; specFile = "NULL"; for mtex in m.getTextures(): if mtex: #check if there is an image if mtex.tex.type == Texture.Types.IMAGE: print mtex.tex.image.getFilename() #map to color if mtex.mapto == Texture.MapTo.COL: textureFile = mtex.tex.image.getFilename() if mtex.mapto == Texture.MapTo.ALPHA: alphaFile = mtex.tex.image.getFilename() if mtex.mapto == Texture.MapTo.NOR: normalFile = mtex.tex.image.getFilename() if mtex.mapto == Texture.MapTo.EMIT: emitFile = mtex.tex.image.getFilename() if mtex.mapto == Texture.MapTo.REF: refFile = mtex.tex.image.getFilename() if mtex.mapto == Texture.MapTo.SPEC: specFile = mtex.tex.image.getFilename() print m.getDiffuseShader() material_array.append(m.getName()) writeln('shad=' + str(m.rgbCol) + '|' +str(m.getRayMirr()) + '|' + str(m.getHardness()) + '|' + str(m.getAlpha()) +'|'+ str(m.getIOR()) +'|'+ str(m.getSpec())+'|'+ str(m.getEmit())+'|' + str(m.getRef()) + '|' + str(m.getDiffuseShader()) +'|' + str(m.getSpecShader()) + '|' + str(m.getSpecCol()) +'|' + str(textureFile) + '|' + str(alphaFile) + '|' + str(normalFile) + '|' + str(emitFile)+'|' + str(refFile) + '|' + str(specFile) ) #while looping through the scene, we will need to collect the maximum #extents of the scene. These will be written to the head of the file #after all mesh objects have been measure min = [1e300,1e300,1e300]; max = [-1e200,-1e300,-1e300]; numObjects = 0 for obj in scene: if obj.getType() == 'Camera': cam_mat = obj.getMatrix('worldspace') print 'Exporting camera' height = context.imageSizeY() width = context.imageSizeX() lens = obj.getData().lens fov = lens; writeln('cam=' + str(camType.val) + '['+str(cam_mat[0][0]) + ',' + str(cam_mat[0][1]) + ',' + str(cam_mat[0][2]) + ']' + '|' + '['+str(cam_mat[1][0]) + ',' + str(cam_mat[1][1]) + ',' + str(cam_mat[1][2]) + ']' + '|' + '['+str(-cam_mat[2][0]) + ',' + str(-cam_mat[2][1]) + ',' + str(-cam_mat[2][2]) + ']' + '|' + '['+str(cam_mat[3][0]) + ',' + str(cam_mat[3][1]) + ',' + str(cam_mat[3][2]) + ']' + '|' + str(width) + ',' + str(height) + ']' + '|' + str(fov) + ',' + str(fov) + ']' + str(obj.getData().getClipStart()) + '|' + str(camRadiusSlider.val) + '|' ) elif obj.getType() == 'Lamp': print 'Exporting Lamp' l=Lamp.Get(obj.getName()) m = obj.getMatrix() if l.getType() == 0: #lamp=location,color,size,energy for a lamp writeln('lamp=[' + str(obj.getLocation()) + ']|['+ str(3*l.getEnergy()*l.col[0]) +','+ str(3*l.getEnergy()*l.col[1]) + ','+str(3*l.getEnergy()*l.col[2]) ) elif l.getType() == 1: #sun=location,color,energy,direction print 'Exporting the sun' vec = vector_by_matrix([0,0,1],m) print str(vec) writeln('sun=['+ str(vec) + ']|[' + str(3*l.getEnergy()*l.col[0]) +','+ str(3*l.getEnergy()*l.col[1]) + ','+str(3*l.getEnergy()*l.col[2]) ) elif obj.getType() =='Surf': material_index = material_array.index(obj.getName()) containSphere(min,max,obj) writeln('sphere=[' + str(obj.getLocation()) + ']|['+ str(obj.size[0]) + ']|['+ str(material_index)) elif obj.getType() == 'Mesh': #get standard mesh data m = NMesh.GetRawFromObject(obj.getName()) mat = obj.getMatrix('worldspace') #for every mesh, we dump a list of vertices numverts = len(m.verts) numTris = 0 print 'verts ' + str(numverts) writeln('numverts=' + str(numverts)) for i in range(numverts): x,y,z = point_by_matrix(m.verts[i].co,mat) writeln('v=' + fmt(x) + '|' + fmt(y) +'|' + fmt(z)) #iterate through faces - then split faces into triangles faces = m.faces #last lastUVTexture = 0 lastidx = 0; for fa in faces: #each face may have an image if str(fa.image) == 'None': idx = -1 else: #is this image the last one? if lastUVTexture == fa.image: idx = lastidx #different texture, have we seen it before? try: idx = baked_maps.index(fa.image) #create new entry except ValueError: baked_maps.append(fa.image) idx = baked_maps.index(fa.image) lastUVTexture = fa.image lastidx = idx; if len(fa.v) == 3: numTris += 1 numObjects+=1 #check for uv coordinates #there has got to be a better way to do this if len(fa.uv) == 0: zers=[0,0]; fa.uv = [zers,zers,zers]; trans = [point_by_matrix(fa.v[0].co,mat),point_by_matrix(fa.v[1].co,mat),point_by_matrix(fa.v[2].co,mat)] contain(min,max,trans) writeln('t=' + str(fa.v[0].index) + '|' + str(fa.v[1].index) + '|' + str(fa.v[2].index) + '|' + str(material_array.index(m.materials[fa.mat].getName())) + '|' + fmt(fa.uv[0][0]) + '|' + fmt(1-fa.uv[0][1]) + '|' + fmt(fa.uv[1][0]) + '|' + fmt(1-fa.uv[1][1]) + '|' + fmt(fa.uv[2][0]) + '|' + fmt(1-fa.uv[2][1]) + '|' + str(idx) ) else: numTris += 2 numObjects+=2 #check for uv coordinates #there has got to be a better way to do this if len(fa.uv) == 0: zers=[0,0]; fa.uv = [zers,zers,zers,zers]; try: trans = [point_by_matrix(fa.v[0].co,mat),point_by_matrix(fa.v[1].co,mat),point_by_matrix(fa.v[2].co,mat)] contain(min,max,trans) writeln('t=' + str(fa.v[0].index) + '|' + str(fa.v[1].index) + '|' + str(fa.v[2].index) + '|' + str(material_array.index(m.materials[fa.mat].getName())) + '|' + fmt(fa.uv[0][0]) + '|' + fmt(1-fa.uv[0][1]) + '|' + fmt(fa.uv[1][0]) + '|' + fmt(1-fa.uv[1][1]) + '|' + fmt(fa.uv[2][0]) + '|' + fmt(1-fa.uv[2][1]) + '|' + str(idx) ) trans = [point_by_matrix(fa.v[2].co,mat),point_by_matrix(fa.v[3].co,mat),point_by_matrix(fa.v[0].co,mat)] contain(min,max,trans) writeln('t=' + str(fa.v[2].index) + '|' + str(fa.v[3].index) + '|' + str(fa.v[0].index) + '|' + str(material_array.index(m.materials[fa.mat].getName())) + '|' + fmt(fa.uv[2][0]) + '|' + fmt(1-fa.uv[2][1]) + '|' + fmt(fa.uv[3][0]) + '|' + fmt(1-fa.uv[3][1]) + '|' + fmt(fa.uv[0][0]) + '|' + fmt(1-fa.uv[0][1]) + '|' + str(idx) ) except: print 'caught quad exception on ' + str(fa) #if the background is set pass that in, else pass color if Background.val: writeln('bgimage=' + str(BackgroundText.val)) else: writeln('bgcolor=' + str(w[0].getHor())) #write out the baked textures for tex in baked_maps: s.write('b=' + str(tex) + '\n') #done with the scene f.close s.close def render(): spawnPath = path + fileName os.spawnl(os.P_NOWAIT,executable,'foo ' + path + ' ' + fileName) #os.spawnl(os.P_NOWAIT,"/home/sheemwaza/base/optimized/src/base","monkey","/home/sheemwaza/out.mra") #retcode=Popen(["/home/sheemwaza/base/src/base","/home/sheemwaza/out.mra"]).pid print 'no op' mSampleSlider = Create(0) camRadiusSlider = Create(1) imageSamples = Create(1) shadowSamples = Create(4) muonSlider = Create(0) Muon = Create(0) BackgroundText = Create('using background color') Background = Create(0) numSample = Create(4) hemiToggle = Create(0) camType = Create(1) iCacheToggle = Create(0) samplerWindow = Create(1) GIWindow = Create(0) partOutput = Create(0) bounce = Create(0) filterWidth = Create(0) jitter = Create(0) sbackground = Create(1) materialsDrop = Create(0) def draw(): global mSampleSlider, muonSlider, Muon,BackgroundText global Background, numSample, hemiToggle, bounce, ExitButton, iCacheToggle global Button2, camType, exportButton global imageSamples, shadowSamples global camRadiusSlider global samplerWindow, GIWindow global partOutput global filterWidth, jitter global sbackground glClearColor(1.0, 1.0, 1.0, 0.0) glClear(GL_COLOR_BUFFER_BIT) leftMargin = 10; bottomMargin = 15; columnWidth = 170; buttonWidth = columnWidth - leftMargin; columnHeight = 35; buttonHeight = columnHeight - bottomMargin; #always display these buttons Button('Exit', 3, leftMargin, 5, buttonWidth, buttonHeight, '') Button('Export', 1, leftMargin+columnWidth,5, buttonWidth, buttonHeight, '') Button('Render', 2, leftMargin+ 2*columnWidth, 5, buttonWidth, buttonHeight, '') camType = Menu('Camera Model%t|Perspective %x1|Spherical %x2|Architecture %x3|DOF %x4', 5, leftMargin, 5*columnHeight, buttonWidth, buttonHeight, camType.val, 'Select which type of camera to use.') imageSamples = Slider('Image', 11, leftMargin , 6*columnHeight, buttonWidth, buttonHeight, imageSamples.val, 1, 20, imageSamples.val,'') shadowSamples = Slider('Shadow', 12, leftMargin + columnWidth, 6*columnHeight, buttonWidth, buttonHeight, shadowSamples.val, 1, 20, 1,'') #these are the GI settings #Background = Toggle('Set Background', 7,leftMargin, 4*columnHeight, buttonWidth, buttonHeight, Background.val, '') sbackground = Menu('Background%t|Uniform %x1|CIE Clear Sky %x2|CIE Overcast %x3|Sky Model %x4', 102, leftMargin, 3*columnHeight, buttonWidth, buttonHeight,sbackground.val, 'Set Background') numSample = Slider('Samples', 6, leftMargin + columnWidth, 2*columnHeight, buttonWidth, buttonHeight,numSample.val, 1, 64, 4, 'The number of hemisphere samples.') bounce = Slider('Bounce', 0, leftMargin + 2 * columnWidth, 2*columnHeight, buttonWidth, buttonHeight, bounce.val, 1, 5, 0,'') if Background.val == 1: BackgroundText = String('', 6, leftMargin + columnWidth, 4*columnHeight, buttonWidth, buttonHeight, BackgroundText.val, 512, '') if camType.val == 4: camRadiusSlider = Slider('Radius', 0, leftMargin + columnWidth, 5*columnHeight, buttonWidth, buttonHeight, camRadiusSlider.val, 1, 20, 1,'') def setBackground(fname): print fname BackgroundText.val=fname def event(evt, val): if (evt== QKEY and not val): Exit() def bevent(evt): if evt == 7: #setBackground Blender.Window.FileSelector(setBackground,'OPEN FILE') elif evt == 10: print 'Materials' Blender.Redraw() elif evt == 3: #ExitButton Exit() elif evt == 2: #Button2 export() render() elif evt == 1: #exportButton export() else: Blender.Redraw() Register(draw, event, bevent)