利用者:Korc/Indigo exporter
< 利用者:Korc
This indigo v0.6 exporter script for blender.
Save the following code as .py file under your .blender/scripts directory.
indigo0.6_export.py:
#!BPY """Registration info for Blender menus: Name: 'Indigo v0.6t6-b1...' Blender: 240 Group: 'Export' Tooltip: 'Export to Indigo v0.6 scene format (.xml)' """ # # ***** BEGIN GPL LICENSE BLOCK ***** # # -------------------------------------------------------------------------- # INDIGO v0.6 test 6 exporter beta 1 # -------------------------------------------------------------------------- # # Authors: # * Indigo exporter - Nick Chapman, Zuegs, Ewout Fernhout, Leope # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # ***** END GPL LICENCE BLOCK ***** # -------------------------------------------------------------------------- ###################################################### # Importing modules ###################################################### import math #import subprocess import os import Blender import struct from Blender import NMesh, Scene, Object, Material, Texture, Window from Blender import sys as bsys, Mathutils, Draw, BGL from Blender.sys import * def info(object, spacing=10, collapse=1): """Print methods and doc strings. Takes module, class, list, dictionary, or string.""" methodList = [e for e in dir(object) if callable(getattr(object, e))] processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s) print "\n".join(["%s %s" % (method.ljust(spacing), processFunc(str(getattr(object, method).__doc__))) for method in methodList]) ###################################################### # Data Structures ###################################################### ###################################################### # Functions ###################################################### # New name based on old with a different extension def newFName(ext): return Blender.Get('filename')[: -len(Blender.Get('filename').split('.', -1)[-1]) ] + ext # exporting a mesh def exportMesh(mesh): vdata = [] # list of [ii0, ii1, ii2, ...] lists indexed by Blender-Vertex-index vlist = [] # list of [coord, normal, uv] lists indexed by Indigo-Vertex-index flist = [] def addVertex(bvindex, coord, normal, uv): index = -1 if (bvindex < len(vdata)): for ivindex in vdata[bvindex]: v = vlist[ivindex] if (abs(v[0][0]-coord[0])<0.0001) and \ (abs(v[0][1]-coord[1])<0.0001) and \ (abs(v[0][2]-coord[2])<0.0001) and \ (abs(v[1][0]-normal[0])<0.0001) and \ (abs(v[1][1]-normal[1])<0.0001) and \ (abs(v[1][2]-normal[2])<0.0001): if ((v[2]==[]) and (uv==[])) or \ ((abs(v[2][0]-uv[0])<0.0001) and \ (abs(v[2][1]-uv[1])<0.0001)): index = ivindex if index < 0: index = len(vlist) vlist.append([coord, normal, uv]) while bvindex >= len(vdata): vdata.append([]) vdata[bvindex].append(index) return index def getVertices(): def getUVStr(uv): if uv != []: return " uv0=\"%f %f\"" %(uv[0], uv[1]) else: return "" return "".join(map( \ lambda v: "\t\t\t<vertex pos=\"%f %f %f\" normal=\"%f %f %f\"%s />\n" \ %(v[0][0], v[0][1], v[0][2], v[1][0], v[1][1], v[1][2], getUVStr(v[2])), \ vlist)) def addFace(mindex, index0, index1, index2): while mindex >= len(flist): flist.append([]) flist[mindex].append([index0, index1, index2]) def getFaces(): def getMaterialName(mindex): if mindex < len(mesh.materials): return mesh.materials[mindex].name else: print "Warning: faces without material" return "Default" return "".join(map( \ lambda fli: "\t\t\t<triangle_set>\n\t\t\t\t<material_name>%s</material_name>\n"%(getMaterialName(fli)) \ + "".join(map(lambda f: "\t\t\t\t<tri>%d %d %d</tri>\n"%(f[0], f[1], f[2]), flist[fli])) \ + "\t\t\t</triangle_set>\n" , range(len(flist)))) vdata = [] vlist = [] flist = [] for face in mesh.faces: iis = [-1, -1, -1, -1] for vi in range(len(face.v)): vert = face.v[vi] if face.smooth: normal = vert.no else: normal = face.no if len(face.uv) == len(face.v): uv = face.uv[vi] else: uv = [] iis[vi] = addVertex(vert.index, vert.co, normal, uv) addFace(face.materialIndex, iis[0], iis[1], iis[2]) if len(face.v)==4: addFace(face.materialIndex, iis[2], iis[3], iis[0]) str = "\t<mesh>\n" str += "\t\t<name>%s</name>\n" %(mesh.name.replace("<","-").replace(">","-")) str += "\t\t<embedded>\n" str += "\t\t\t<expose_uv_set>\n" str += "\t\t\t\t<index>0</index>\n" str += "\t\t\t\t<name>uv</name>\n" str += "\t\t\t</expose_uv_set>\n" str += getVertices() str += getFaces() str += "\t\t</embedded>\n" str += "\t</mesh>\n\n" return str # zuegs: added color exponent def colGamma(value): global ColExponent return value**(1.0*ColExponent.val) # exporting a material def exportMaterial(mat): str = "\t<material>\n" str += "\t\t<name>%s</name>\n" %mat.name if (mat.mode & Material.Modes.RAYTRANSP) or (mat.mode & Material.Modes.RAYMIRROR): str += "\t\t<specular>\n" if (mat.mode & Material.Modes.RAYMIRROR): str += "\t\t\t<normal_reflectance>%.3f</normal_reflectance>\n" %mat.rayMirr #else: #str += "\t\t\t<normal_reflectance>0</normal_reflectance>\n" str += "\t\t\t<ior>%.3f</ior>\n" %mat.IOR if (mat.mode & Material.Modes.RAYTRANSP): str += "\t\t\t<transparent>true</transparent>\n" str += "\t\t\t<cauchy_b_coeff>%.3f</cauchy_b_coeff>\n" %mat.filter str += "\t\t\t<rgb_absorptivity>%.3f %.3f %.3f</rgb_absorptivity>\n" %((1-mat.R)*(1-mat.R),(1-mat.G)*(1-mat.G),(1-mat.B)*(1-mat.B)) else: str += "\t\t\t<transparent>false</transparent>\n" str += "\t\t\t<cauchy_b_coeff>0.0</cauchy_b_coeff>\n" str += "\t\t\t<rgb_absorptivity>0 0 0</rgb_absorptivity>\n" for t in mat.getTextures(): if (t != None) and (t.tex.type == Blender.Texture.Types.IMAGE): # and (t.texco & Blender.Texture.TexCo['UV']) if t.mapto & Blender.Texture.MapTo['NOR']: if t.tex.getImage(): str += "\t\t\t<bump_map>\n" str += "\t\t\t\t<uv_set>uv</uv_set>\n" (imagefilepath, imagefilename) = os.path.split(t.tex.getImage().getFilename()) str += "\t\t\t\t<path>%s</path>\n" %(imagefilename) str += "\t\t\t\t<gain>%f</gain>\n" %(t.norfac * 0.1) str += "\t\t\t\t<exponent>%f</exponent>\n" %(1) str += "\t\t\t</bump_map>\n" str += "\t\t</specular>\n" else: specfac = mat.getSpec() if specfac > 0.0001: str += "\t\t<phong>\n" if mat.name.find(".nk") != -1: str += "\t\t\t<nk_data>nkdata/%s</nk_data>\n" %(mat.name.split(".nk")[0]+".nk") else: str += "\t\t\t<diffuse>%.3f %.3f %.3f</diffuse>\n" %(colGamma(mat.R)*DiffuseGain.val,colGamma(mat.G)*DiffuseGain.val,colGamma(mat.B)*DiffuseGain.val) str += "\t\t\t<specular>%.3f %.3f %.3f</specular>\n" %(colGamma(mat.specR*specfac)*SpecularGain.val,colGamma(mat.specG*specfac)*SpecularGain.val,colGamma(mat.specB*specfac)*SpecularGain.val) str += "\t\t\t<fresnel_scale>%.3f</fresnel_scale>\n" %(mat.ref) str += "\t\t\t<exponent>%.3f</exponent>\n" %(mat.hard*10) else: str += "\t\t<diffuse>\n" str += "\t\t\t<colour>%.3f %.3f %.3f</colour>\n" %(colGamma(mat.R)*DiffuseGain.val,colGamma(mat.G)*DiffuseGain.val,colGamma(mat.B)*DiffuseGain.val) for t in mat.getTextures(): if (t != None) and (t.texco & Blender.Texture.TexCo['UV']) and (t.tex.type == Blender.Texture.Types.IMAGE): if t.mapto & Blender.Texture.MapTo['COL']: if t.tex.getImage(): str += "\t\t\t<albedo_texture>\n" str += "\t\t\t\t<uv_set>uv</uv_set>\n" (imagefilepath, imagefilename) = os.path.split(t.tex.getImage().getFilename()) str += "\t\t\t\t<path>%s</path>\n" %(imagefilename) str += "\t\t\t\t<gain>%f</gain>\n" %(t.colfac) str += "\t\t\t\t<exponent>%f</exponent>\n" %(TexExponent.val) str += "\t\t\t</albedo_texture>\n" if t.mapto & Blender.Texture.MapTo['NOR']: if t.tex.getImage(): str += "\t\t\t<bump_map>\n" str += "\t\t\t\t<uv_set>uv</uv_set>\n" (imagefilepath, imagefilename) = os.path.split(t.tex.getImage().getFilename()) str += "\t\t\t\t<path>%s</path>\n" %(imagefilename) str += "\t\t\t\t<gain>%f</gain>\n" %(t.norfac * 0.1) str += "\t\t\t\t<exponent>%f</exponent>\n" %(1) str += "\t\t\t</bump_map>\n" if mat.getSpec() > 0: str += "\t\t</phong>\n" else: str += "\t\t</diffuse>\n" str += "\t</material>\n\n" return str # collect Materials matnames = [] def collectObjectMaterials(obj): global matnames objectname = obj.getName() objecttype = obj.getType() if (objecttype == "Mesh") or (objecttype == "Curve") or (objecttype == "Text"): materials = obj.getData().getMaterials() meshlight = 0 if len(materials) > 0: mat0 = materials[0] if mat0.emit > 0: meshlight = 1 if meshlight == 0: for mat in materials: if mat.name not in matnames: matnames.append(mat.name) elif (objecttype == "Empty"): group = obj.DupGroup if group: groupname = group.name for o, m in obj.DupObjects: collectObjectMaterials(o) # exporting a object # zuegs: added support for Curves, Groups and other object-types meshlist = [] def exportObject(obj, matrix): global meshlist str = "" objectname = obj.getName() objecttype = obj.getType() if (objecttype == "Mesh") or (objecttype == "Curve") or (objecttype == "Text"): mesh = Blender.NMesh.GetRawFromObject(objectname) meshname = mesh.name if (objecttype == "Curve") or (objecttype == "Text"): # print "Curve object %s: current mesh name is %s. Tweak to %s." %(objectname, meshname, obj.getData().getName()) meshname = obj.getData().getName() mesh.name = meshname for f in mesh.faces: f.smooth = 1 if (objecttype == "Curve"): # print "Curve object %s: current material count %d. Tweak to %d." %(objectname, len(mesh.getMaterials()), len(obj.getData().getMaterials())) mesh.setMaterials(obj.getData().getMaterials()) meshlight = 0 if len(mesh.materials) > 0: mat0 = mesh.materials[0] if mat0.emit > 0: meshlight = 1 if meshlight: print "processing Object \"%s\" as Meshlight (Mesh \"%s\")..." %(objectname, meshname) else: print "processing Object \"%s\" (Mesh \"%s\")..." %(objectname, meshname) str += "\t<!-- %s -->\n" %(objectname.replace("<","-").replace(">","-")) try: meshlist.index(meshname) except ValueError: str += exportMesh(mesh) meshlist.append(meshname) pos = obj.getLocation() # matrix = obj.getMatrix() # matrix is passed as argument to the function if meshlight: str += "\t<meshlight>\n" else: str += "\t<model>\n" str += "\t\t<pos>%f %f %f</pos>\n" % (matrix[3][0], matrix[3][1], matrix[3][2]) str += "\t\t<scale>1.0</scale>\n" str += "\t\t<rotation>\n" str += "\t\t\t<matrix>\n" str += "\t\t\t\t" for v in range(3): for z in range(3): str += "%f " % matrix[z][v] str += "\n" str += "\t\t\t</matrix>\n" str += "\t\t</rotation>\n" str += "\t\t<mesh_name>%s</mesh_name>\n" %(meshname.replace("<","-").replace(">","-")) if meshlight: str += "\t\t<spectrum>\n" if (mat0.translucency > 0): str += "\t\t\t<peak>\n" str += "\t\t\t\t<peak_min>%.0f</peak_min>\n" %(mat0.translucency*1000) str += "\t\t\t\t<peak_width>%.0f</peak_width>\n" %(mat0.amb*1000) str += "\t\t\t\t<base_value>0</base_value>\n" str += "\t\t\t\t<peak_value>%.0f</peak_value>\n" %(mat0.emit*100) str += "\t\t\t</peak>\n" elif (mat0.translucency == 0 and mat0.amb > 0): str += "\t\t\t<blackbody>\n" str += "\t\t\t\t<temperature>%.0f</temperature>\n" %(mat0.amb*10000) # zuegs: correction for blackbody energie str += "\t\t\t\t<gain>%.10f</gain>\n" %(pow(10,10*(mat0.emit-1)) / (7.5659e-16*pow(mat0.amb*10000, 4))) str += "\t\t\t</blackbody>\n" elif (mat0.translucency == 0 and mat0.amb == 0): str += "\t\t\t<rgb>\n" str += "\t\t\t\t<rgb>%.3f %.3f %.3f</rgb>\n" %(pow(100,(mat0.R))-1, pow(100,(mat0.G))-1, pow(100,(mat0.B))-1) str += "\t\t\t</rgb>\n" str += "\t\t</spectrum>\n" str += "\t</meshlight>\n" else: str += "\t</model>\n\n" elif (objecttype == "Empty"): group = obj.DupGroup if (group): groupname = group.name print "processing Object \"%s\" (Group \"%s\")..." %(objectname, groupname) for o, m in obj.DupObjects: str += exportObject(o, m) print "end processing Object \"%s\" (Group \"%s\")..." %(objectname, groupname) else: print "Skip \"%s\" (type \"%s\")" %(obj.getName(), obj.getType()) return str def IndigoBoolean(val): if val != 0: val = "true" else: val = "false" return val ###################################################### # EXPORT ###################################################### def save_indigo(filename, unindexedname): global meshlist, matnames print("INDIGO EXPORT\n") time1 = Blender.sys.time() print("Saving to '" + filename + "'...\n") file = open(filename, 'w') ##### XML header ###### file.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n") file.write("<scene>\n") # write render_settings file.write("\t<renderer_settings>\n") file.write("\t\t<width>%d</width>\n" % (SizeX.val*ScaleSize.val/100)) file.write("\t\t<height>%d</height>\n" % (SizeY.val*ScaleSize.val/100)) file.write("\t\t<metropolis>%s</metropolis>\n" %(IndigoBoolean(MLT.val))) file.write("\t\t<large_mutation_prob>%g</large_mutation_prob>\n" % float(LMP.val)) file.write("\t\t<max_change>%g</max_change>\n" % float(MaxChange.val)) file.write("\t\t<max_num_consec_rejections>%d</max_num_consec_rejections>\n" % MaxNumConsRej.val) file.write("\t\t<bidirectional>%s</bidirectional>\n" %(IndigoBoolean(Bidirectional.val))) file.write("\t\t<russian_roulette_live_prob>%g</russian_roulette_live_prob>\n" % float(RRLP.val)) file.write("\t\t<max_depth>%s</max_depth>\n" % MaxDepth) file.write("\t\t<strata_width>%s</strata_width>\n" % StrataWidth) file.write("\t\t<logging>%s</logging>\n" %(IndigoBoolean(Logging.val))) file.write("\t\t<save_untonemapped_exr>%s</save_untonemapped_exr>\n" %(IndigoBoolean(SaveUTMExr.val))) file.write("\t\t<save_tonemapped_exr>%s</save_tonemapped_exr>\n" %(IndigoBoolean(SaveTMExr.val))) file.write("\t</renderer_settings>\n\n") # write tone mapping file.write("\t<tonemapping>\n") if ToneMapType.val == 0: file.write("\t\t<linear>\n") file.write("\t\t\t<scale>%.3f</scale>\n" %float(ToneMapScale.val)) file.write("\t\t</linear>\n") file.write("\t\t<!--\n") file.write("\t\t<reinhard>\n") file.write("\t\t\t<pre_scale>1.0</pre_scale>\n") file.write("\t\t\t<post_scale>1.0</post_scale>\n") file.write("\t\t\t<burn>0.8</burn>\n") file.write("\t\t</reinhard>\n") file.write("\t\t-->\n") elif ToneMapType.val == 1: file.write("\t\t<!--\n") file.write("\t\t<linear>\n") file.write("\t\t\t<scale>1.0</scale>\n") file.write("\t\t</linear>\n") file.write("\t\t-->\n") file.write("\t\t<reinhard>\n") file.write("\t\t\t<pre_scale>%.6f</pre_scale>\n" %float(ToneMapPreScale.val)) file.write("\t\t\t<post_scale>%.6f</post_scale>\n" %float(ToneMapPostScale.val)) file.write("\t\t\t<burn>%.3f</burn>\n" %ToneMapBurn.val) file.write("\t\t</reinhard>\n") file.write("\t</tonemapping>\n\n") # write background if EnvType.val == 0: worldcolor = Blender.World.Get('World').getHor() file.write("\t<background>\n") file.write("\t\t<spectrum>\n") file.write("\t\t\t<rgb>\n") file.write("\t\t\t\t<rgb>%g %g %g</rgb>\n" %(worldcolor[0], worldcolor[1], worldcolor[2])) file.write("\t\t\t</rgb>\n") file.write("\t\t</spectrum>\n") file.write("\t</background>\n\n") #get all the objects in this scene activelayers = Window.ViewLayer() for i in range(len(activelayers)): activelayers[i] = 2**(activelayers[i]-1) object_list1 = Blender.Scene.GetCurrent().getChildren() object_list = [] matnames= [] for obj in object_list1: if obj.Layer in activelayers: object_list.append(obj) collectObjectMaterials(obj) ##### Materialfile include ##### if MatFile.val is 0: ##### Define a dummy material ###### file.write("\t<material>\n") file.write("\t\t<name>Default</name>\n") file.write("\t\t<diffuse>\n") file.write("\t\t\t<colour>1 1 1</colour>\n") file.write("\t\t</diffuse>\n") file.write("\t</material>\n") ##### Process Materials ###### materials = Material.Get() for mat in materials: if mat.name in matnames: file.write(exportMaterial(mat)) else: materialfile = makename(unindexedname, '-materials.xml') materialinclude = basename(materialfile) file.write("\t<include>\n") file.write("\t\t<pathname>%s</pathname>\n" %(materialinclude)) file.write("\t</include>\n\n") ##### Process sun ###### if EnvType.val == 1: for obj in object_list: if obj.getType() == "Lamp": if obj.data.getType() == 1: # sun object print("Processing sun lamp object...\n") invmatrix = Mathutils.Matrix(obj.getInverseMatrix()) file.write("\t<skylight>\n") file.write("\t\t<sundir>%f %f %f</sundir>\n" % (invmatrix[0][2], invmatrix[1][2], invmatrix[2][2])) file.write("\t\t<turbidity>%f</turbidity>\n" %Turbidity.val) file.write("\t\t<sky_gain>%f</sky_gain>\n" %SkyGain.val) file.write("\t</skylight>\n\n") ##### Process Env Map ##### if EnvType.val == 2: if EnvFile.val != "none" and EnvFile.val != "": file.write("\t<env_map>\n") file.write("\t\t<%s>\n" %(EnvMapTypeV[EnvMapType.val])) file.write("\t\t\t<path>%s</path>\n" %(EnvFile.val)) file.write("\t\t\t<gain>%.3f</gain>\n" %(EnvGain.val)) if EnvMapType.val == 0: file.write("\t\t\t<width>%d</width>\n" %(EnvWidth.val)) file.write("\t\t</%s>\n" %(EnvMapTypeV[EnvMapType.val])) file.write("\t</env_map>\n\n") ##### Process camera ###### currentscene = Scene.GetCurrent() camObj = currentscene.getCurrentCamera() if camObj: print "processing Camera..." matrix = camObj.getMatrix() pos = matrix[3] forwards = matrix[2] up = matrix[1] file.write("\t<camera>\n") file.write("\t\t<pos>%f %f %f</pos>\n" % (pos[0], pos[1], pos[2])) file.write("\t\t<up>%f %f %f</up>\n" % (up[0], up[1], up[2])) file.write("\t\t<forwards>%f %f %f</forwards>\n" % (-forwards[0], -forwards[1], -forwards[2])) aspect = float(SizeX.val) / float(SizeY.val) film = 0.001 * FilmWidth.val # zuegs: correct aspect stuff for portrait-mode if aspect < 1.0: lensfocal = (camObj.data.getLens() * film / aspect)/32 else: lensfocal = (camObj.data.getLens() * film)/32 file.write("\t\t<aperture_radius>%f</aperture_radius>\n" % ApertureRadius.val) file.write("\t\t<focus_distance>%f</focus_distance>\n" % FocusDistance.val) file.write("\t\t<aspect_ratio>%g</aspect_ratio>\n" % aspect) file.write("\t\t<sensor_width>%f</sensor_width>\n" % film) file.write("\t\t<lens_sensor_dist>%f</lens_sensor_dist>\n" % lensfocal) file.write("\t\t<white_balance>%s</white_balance>\n" % whiteBalanceV[WhiteBalance.val]) file.write("\t</camera>\n\n") ##### Check for ground plane ###### if GroundPlane.val is 1: file.write("\t<plane>\n") file.write("\t\t<normal>0 0 1</normal>\n") file.write("\t\t<dist>-0.000001</dist>\n") file.write("\t\t<material_name>Default</material_name>\n") file.write("\t</plane>\n\n") ##### Process Meshes ###### meshlist = [] for obj in object_list: file.write(exportObject(obj, obj.getMatrix())) ##### XML FOOTER ###### file.write("</scene>\n") file.close() print("Finished.\n") if MatFile.val and not MatSaved: print("Saving Material file...\n") file = open(materialfile, 'w') file.write("<scenedata>\n\n") ##### Define a dummy material ###### file.write("\t<material>\n") file.write("\t\t<name>Default</name>\n") file.write("\t\t<diffuse>\n") file.write("\t\t\t<colour>1 1 1</colour>\n") file.write("\t\t</diffuse>\n") file.write("\t</material>\n") ##### Process Materials ###### materials = Material.Get() for mat in materials: if mat.name in matnames: file.write(exportMaterial(mat)) file.write("</scenedata>") file.close() time2 = Blender.sys.time() print("Processing time: %f\n" %(time2-time1)) #Draw.Exit() #### SAVE ANIMATION #### def save_anim(filename): global MatSaved MatSaved = 0 startF = Blender.Get('staframe') endF = Blender.Get('endframe') for i in range (startF, endF): Blender.Set('curframe', i) Blender.Redraw() frameindex = "-" + str(i) + ".xml" indexedname = makename(filename, frameindex) unindexedname = filename save_indigo(indexedname, unindexedname) MatSaved = 1 #### SAVE STILL (hackish...) #### def save_still(filename): global MatSaved MatSaved = 0 unindexedname = filename save_indigo(filename, unindexedname) ###################################################### # Settings GUI ###################################################### # Assign event numbers to buttons evtNoEvt = 0 evtExport = 1 evtExportAnim = 2 evtIsNumber = 3 evtFocusS = 4 evtFocusC = 5 # Set initial values of buttons ## <size>800 600</size> sceneSizeX = Scene.GetCurrent().getRenderingContext().imageSizeX() sceneSizeY = Scene.GetCurrent().getRenderingContext().imageSizeY() SizeX = Draw.Create(sceneSizeX) SizeY = Draw.Create(sceneSizeY) strScaleSize = "Scale Size %t | 100 % %x100 | 75 % %x75 | 50 % %x50 | 25 % %x25" ScaleSize = Draw.Create(100) TexExponent = Draw.Create(2.3) ColExponent = Draw.Create(2.3) ## <metropolis>1</metropolis> MLT = Draw.Create(1) ## <large_mutation_prob>0.1</large_mutation_prob> LMP = Draw.Create(0.1) ## <max_change>0.02</max_change> MaxChange = Draw.Create(0.02) ## <max_num_consec_rejections>100</max_num_consec_rejections> MaxNumConsRej = Draw.Create(100) ## <russian_roulette_live_prob>0.7</russian_roulette_live_prob> RRLP = Draw.Create(0.7) ## <max_depth>1000</max_depth> MaxDepth = Draw.Create(1000) ## <bidirectional>true</bidirectional> Bidirectional = Draw.Create(1) ## <strata_width>14</strata_width> StrataWidth = Draw.Create(14) ## <logging>0</logging> Logging = Draw.Create(0) ## <save_untonemapped_exr>false</save_untonemapped_exr> SaveUTMExr = Draw.Create(0) ## <save_tonemapped_exr>false</save_tonemapped_exr> SaveTMExr = Draw.Create(0) ## <sensor_width>0.035</sensor_width> FilmWidth = Draw.Create(35) ## <lens_radius>0.0</lens_radius> ApertureRadius = Draw.Create(0.001) ## <focus_distance>2.0</focus_distance> FocusDistance = Draw.Create(2.0) ## <white_balance>D65</white_balance> whiteBalanceV="E D50 D55 D65 D75 A B C 9300 F2 F7 F11".split() strWhiteBalance="White balance %t | "+" | ".join([name+" %x"+str(idx) for idx,name in enumerate(whiteBalanceV)]) WhiteBalance = Draw.Create(4) ## Environment Type strEnvType = "Env Type %t | Background %x0 | SunSky %x1 | Map %x2" EnvType = Draw.Create(0) ## <turbidity>2.0</turbidity> Turbidity = Draw.Create(2.0) ## <sky_gain>2.0</sky_gain> SkyGain = Draw.Create(0.005) GroundPlane = Draw.Create(0) ## Separate materials MatFile = Draw.Create(0) ## Environment map EnvFile = Draw.Create("none") strEnvMapType = "Map type %t | Spherical %x0 | LatLong %x1" EnvMapType = Draw.Create(0) EnvMapTypeV = {} EnvMapTypeV[0] = "spherical" EnvMapTypeV[1] = "latlong" EnvGain = Draw.Create(1.0) EnvWidth = Draw.Create(640) ## Tonemapping strToneMapType = "ToneMap type %t | Linear %x0 | Reinhard %x1" ToneMapType = Draw.Create(1) ToneMapScale = Draw.Create("1.0") ToneMapPreScale = Draw.Create("1.0") ToneMapPostScale = Draw.Create("1.0") ToneMapBurn = Draw.Create(0.8) ## Overall color gain DiffuseGain = Draw.Create(1.00) SpecularGain = Draw.Create(1.00) # text color fix textcol = [0, 0, 0] ## Registry def update_Registry(): #global EnvFile, EnvMapType d = {} d['sizex'] = SizeX.val d['sizey'] = SizeY.val d['scalesize'] = ScaleSize.val d['texexponent'] = TexExponent.val d['colexponent'] = ColExponent.val d['filmwidth'] = FilmWidth.val d['apertureradius'] = ApertureRadius.val d['focusdistance'] = FocusDistance.val d['whitebalance'] = WhiteBalance.val d['mlt'] = MLT.val d['lmp'] = LMP.val d['maxchange'] = MaxChange.val d['maxnumconsrej'] = MaxNumConsRej.val d['bidirectional'] = Bidirectional.val d['rrlp'] = RRLP.val d['maxdepth'] = MaxDepth.val d['stratawidth'] = StrataWidth.val d['logging'] = Logging.val d['groundplane'] = GroundPlane.val d['saveutmexr'] = SaveUTMExr.val d['savetmexr'] = SaveTMExr.val d['tonemaptype'] = ToneMapType.val d['tonemapscale'] = ToneMapScale.val d['tonemapprescale'] = ToneMapPreScale.val d['tonemappostscale'] = ToneMapPostScale.val d['tonemapburn'] = ToneMapBurn.val d['envtype'] = EnvType.val d['envfile'] = EnvFile.val d['envmaptype'] = EnvMapType.val d['envgain'] = EnvGain.val d['envwidth'] = EnvWidth.val d['turbidity'] = Turbidity.val d['skygain'] = SkyGain.val d['matfile'] = MatFile.val Blender.Registry.SetKey('BlenderIndigo', d, True) rdict = Blender.Registry.GetKey('BlenderIndigo', True) if rdict: try: SizeX.val = rdict['sizex'] SizeY.val = rdict['sizey'] ScaleSize.val = rdict['scalesize'] TexExponent.val = rdict['texexponent'] ColExponent.val = rdict['colexponent'] FilmWidth.val = rdict['filmwidth'] ApertureRadius.val = rdict['apertureradius'] FocusDistance.val = rdict['focusdistance'] WhiteBalance.val = rdict['whitebalance'] MLT.val = rdict['mlt'] LMP.val = rdict['lmp'] MaxChange.val = rdict['maxchange'] MaxNumConsRej.val = rdict['maxnumconsrej'] Bidirectional.val = rdict['bidirectional'] RRLP.val = rdict['rrlp'] MaxDepth.val = rdict['maxdepth'] StrataWidth.val = rdict['stratawidth'] Logging.val = rdict['logging'] GroundPlane.val = rdict['groundplane'] SaveUTMExr.val = rdict['saveutmexr'] SaveTMExr.val = rdict['savetmexr'] ToneMapType.val = rdict['tonemaptype'] ToneMapScale.val = rdict['tonemapscale'] ToneMapPreScale.val = rdict['tonemapprescale'] ToneMapPostScale.val = rdict['tonemappostscale'] ToneMapBurn.val = rdict['tonemapburn'] EnvType.val = rdict['envtype'] EnvFile.val = rdict['envfile'] EnvMapType.val = rdict['envmaptype'] EnvGain.val = rdict['envgain'] EnvWidth.val = rdict['envwidth'] Turbidity.val = rdict['turbidity'] SkyGain.val = rdict['skygain'] MatFile.val = rdict['matfile'] except: update_Registry() def gui(): global evtNoEvt, evtExport, evtExportAnim, evtFocusS, evtFocusC global SizeX, SizeY, strScaleSize, ScaleSize, TexExponent, ColExponent, RRLP, MaxDepth, Bidirectional, StrataWidth, Logging, ApertureRadius, FocusDistance, GroundPlane, MatFile, FilmWidth global SaveUTMExr, SaveTMExr, ToneMapType, ToneMapScale, ToneMapPreScale, ToneMapPostScale, ToneMapBurn global MLT, LMP, MaxChange, MaxNumConsRej global textcol, strEnvType, EnvType, EnvFile, strEnvMapType, EnvMapType, EnvGain, EnvWidth, Turbidity, SkyGain, DiffuseGain, SpecularGain global strWhiteBalance, WhiteBalance, whiteBalanceV Draw.Button("Export", evtExport, 10, 25, 100, 18, "Open file dialog and export") Draw.Button("Export Anim", evtExportAnim, 130, 25, 100, 18, "Open file dialog and export animation (careful: takes a lot of diskspace!!!)") MatFile = Draw.Toggle("Separate Materials", evtNoEvt, 250, 25, 200, 18, MatFile.val, "Save all the material settings to a separate file with a \"-materials\" extension") BGL.glColor3f(textcol[0], textcol[1], textcol[2]) ; BGL.glRasterPos2i(10,10) ; Draw.Text("Press Q or ESC to quit.", "tiny") # BGL.glRasterPos2i(10,470) ; Draw.Text("I N D I G O v0.6beta3 exporter") # BGL.glRasterPos2i(10,450) ; Draw.Text("Size:") SizeX = Draw.Number("X: ", evtNoEvt, 65, 445, 75, 18, SizeX.val, 1, 4096, "Width of the render") SizeY = Draw.Number("Y: ", evtNoEvt, 150, 445, 75, 18, SizeY.val, 1, 3072, "Height of the render") ScaleSize = Draw.Menu(strScaleSize, evtNoEvt, 230, 445, 65, 18, ScaleSize.val, "Scale Image Size of ...") TexExponent = Draw.Slider("Tex exp: ", evtNoEvt, 10, 425, 210, 18, TexExponent.val, 0.0, 5.0, 0, "Texture gamma exponent") # zuegs: added color exponent ColExponent = Draw.Slider("Col exp: ", evtNoEvt, 240, 425, 210, 18, ColExponent.val, 0.01, 5.0, 0, "Color gamma exponent") # BGL.glRasterPos2i(10,405) ; Draw.Text("Camera settings") FilmWidth = Draw.Number("Film Width: ", evtNoEvt, 10, 380, 250, 18, FilmWidth.val, 0.0, 100, "Width of the \"Film.\" in mm.") ApertureRadius = Draw.Number("Aperture Radius: ", evtNoEvt, 10, 360, 250, 18, ApertureRadius.val, 0.0, 1.0, "In meters, 0 is off. Defines the radius of the camera lens, or the radius of the camera aperture. Larger radius means more depth of field.") FocusDistance = Draw.Number("Focus Distance: ", evtNoEvt, 10, 340, 250, 18, FocusDistance.val, 0.0, 100, "Distance from the camera at which objects will be in focus. Has no effect if Lens Radius is 0.") Draw.Button("S", evtFocusS, 265, 340, 15, 18, "Get the distance from the selected object") Draw.Button("C", evtFocusC, 280, 340, 15, 18, "Get the distance from the 3d cursor") BGL.glRasterPos2i(300,365) ; Draw.Text("white balance") WhiteBalance = Draw.Menu(strWhiteBalance, evtNoEvt, 385, 360, 65, 18, WhiteBalance.val, "Set the white_balance (def=D65)") # BGL.glRasterPos2i(10,320) ; Draw.Text("Metropolis light transport settings") MLT = Draw.Toggle("Metropolis", evtNoEvt, 10, 295, 100, 18, MLT.val, "If pressed, use MLT otherwise use pathtracer") LMP = Draw.Number("Large mutation probability: ", evtNoEvt, 112, 295, 338, 18, LMP.val, 0.0, 1.0, "Probability of using fresh random numbers") MaxChange = Draw.Number("Max Change: ", evtNoEvt, 112, 275, 338, 18, MaxChange.val, 0.0, 1.0, "Maximum mutation size") MaxNumConsRej = Draw.Number("Max num consec rejections:", evtNoEvt, 112, 255, 338, 18, MaxNumConsRej.val, 0, 10000, "The lower the value the more biased the calculation") # BGL.glRasterPos2i(10,235) ; Draw.Text("General tracing parameters") Bidirectional = Draw.Toggle("Bidirectional", evtNoEvt, 10, 210, 100, 18, Bidirectional.val, "If pressed, use bidirectional tracing") RRLP = Draw.Number("Russian roulette live probability: ", evtNoEvt, 112, 210, 338, 18, RRLP.val, 0.0, 1.0, "Russian roulette live probability") MaxDepth = Draw.Number("Max depth:", evtNoEvt, 112, 190, 338, 18, MaxDepth.val, 1, 10000, "Maximum ray bounce depth") # BGL.glRasterPos2i(10,150) ; Draw.Text("Path tracer settings") StrataWidth = Draw.Number("Strata width:", evtNoEvt, 10, 125, 150, 18, StrataWidth.val, 1, 50, "Number of samples per pixel = strata width*strata width") # BGL.glColor3f(0.5,0.5,0.5) BGL.glRectf(200.0,100.0,450.0,185.0) BGL.glColor3f(0.0,0.0,0.0) BGL.glRasterPos2i(200,170) ; Draw.Text("Env Type") EnvType = Draw.Menu(strEnvType, evtNoEvt, 300, 165, 150, 18, EnvType.val, "Set the Enviroment type") if EnvType.val == 2: EnvFile = Draw.String("Probe: ", evtNoEvt, 200, 145, 250, 18, EnvFile.val, 50, "the file name of the raw/exr probe") EnvMapType = Draw.Menu(strEnvMapType, evtNoEvt, 350, 125, 100, 18, EnvMapType.val, "Set the map type of the probe") EnvGain = Draw.Number("Gain: ", evtNoEvt, 200, 125, 100, 18, EnvGain.val, 0.00, 100.00, "Gain") if EnvMapType.val == 0: EnvWidth = Draw.Number("Width: ", evtNoEvt, 350, 105, 100, 18, EnvWidth.val, 1, 10000, "Width") # BGL.glRasterPos2i(10,105) ; Draw.Text("Miscellaneous") Logging = Draw.Toggle("Logging", evtNoEvt, 10, 80, 100, 18, Logging.val, "Write to log.txt if pressed") SaveUTMExr = Draw.Toggle("Save utm EXR", evtNoEvt, 130, 80, 100, 18, SaveUTMExr.val, "Save untonemapped EXR file") SaveTMExr = Draw.Toggle("Save tm EXR", evtNoEvt, 130, 60, 100, 18, SaveTMExr.val, "Save tonemapped EXR file") BGL.glColor3f(0.4,0.4,0.5) BGL.glRectf(250.0,60.0,450.0,100.0) BGL.glColor3f(0.0,0.0,0.0) ToneMapType = Draw.Menu(strToneMapType, evtNoEvt, 250, 60, 85, 18, ToneMapType.val, "Set the type of the tonemapping") if ToneMapType.val == 0: ToneMapScale = Draw.String("Scale: ", evtIsNumber, 250, 80, 200, 18, ToneMapScale.val, 50, "Scale pixel value") elif ToneMapType.val == 1: ToneMapBurn = Draw.Number("Burn: ", evtNoEvt, 250, 80, 85, 18, ToneMapBurn.val, 0.0, 1.0, "1.0: no burn out, 0.1 lot of burn out") ToneMapPreScale = Draw.String("PreS: ", evtIsNumber, 340, 80, 110, 18, ToneMapPreScale.val, 50, "Pre Scale: See Indigo Manual ;)") ToneMapPostScale = Draw.String("PostS: ", evtIsNumber, 340, 60, 110, 18, ToneMapPostScale.val, 50, "Post Scale: See Indigo Manual ;)") GroundPlane = Draw.Toggle("Ground Plane", evtNoEvt, 10, 60, 100, 18, GroundPlane.val, "Place infinite large ground plane at 0,0,0") if EnvType.val == 1: Turbidity = Draw.Number("Sky Turbidity", evtNoEvt, 300, 145, 150, 18, Turbidity.val, 1.5, 5.0, "Sky Turbidity") SkyGain = Draw.Number("Sky Gain", evtNoEvt, 300, 125, 150, 18, SkyGain.val, 0.0, 5.0, "Sky Gain") # # DiffuseGain = Draw.Number("Diffuse gain: ", evtNoEvt, 130, 40, 150, 18, DiffuseGain.val, 0.0, 1.0, "Overall diffuse color gain") # SpecularGain = Draw.Number("Specular gain: ", evtNoEvt, 300, 40, 150, 18, SpecularGain.val, 0.0, 1.0, "Overall specular color gain") def event(evt, val): # function that handles keyboard and mouse events if evt == Draw.ESCKEY or evt == Draw.QKEY: stop = Draw.PupMenu("OK?%t|Cancel export %x1") if stop == 1: Draw.Exit() return def buttonEvt(evt): # function that handles button events if evt == evtExport: Blender.Window.FileSelector(save_still, "Export", newFName('xml')) if evt == evtExportAnim: Blender.Window.FileSelector(save_anim, "Export Animation", newFName('xml')) #if there was an event, redraw the window if evt: Draw.Redraw() if evt == evtNoEvt: Draw.Redraw() update_Registry() if evt == evtIsNumber: global ToneMapScale, ToneMapPreScale, ToneMapPostScale try: float(ToneMapScale.val) except: ToneMapScale.val = "NUMBERS ONLY !!!" try: float(ToneMapPreScale.val) except: ToneMapPreScale.val = "FLOAT !!" try: float(ToneMapPostScale.val) except: ToneMapPostScale.val = "FLOAT !!" Draw.Redraw() update_Registry() if evt == evtFocusS: setFocus("S") Draw.Redraw() update_Registry() if evt == evtFocusC: setFocus("C") Draw.Redraw() update_Registry() def setFocus(target): global FocusDistance currentscene = Scene.GetCurrent() camObj = currentscene.getCurrentCamera() selObj = Object.GetSelected()[0] loc1 = camObj.getLocation() if target == "S": try: loc2 = selObj.getLocation() except: print "select an object to focus\n" if target == "C": loc2 = Window.GetCursorPos() FocusDistance.val = (((loc1[0]-loc2[0])**2)+((loc1[1]-loc2[1])**2)+((loc1[2]-loc2[2])**2))**0.5 Draw.Register(gui, event, buttonEvt)