3 """Registration info for Blender menus:
4 Name: 'LuxBlend v0.6RC5 Exporter'
7 Tooltip: 'Export/Render to LuxRender v0.6RC5 scene format (.lxs)'
10 # ***** BEGIN GPL LICENSE BLOCK *****
12 # --------------------------------------------------------------------------
13 # LuxBlend v0.6RC5 exporter
14 # --------------------------------------------------------------------------
17 # radiance, zuegs, ideasman42, luxblender, dougal2
19 # This program is free software; you can redistribute it and/or
20 # modify it under the terms of the GNU General Public License
21 # as published by the Free Software Foundation; either version 2
22 # of the License, or (at your option) any later version.
24 # This program is distributed in the hope that it will be useful,
25 # but WITHOUT ANY WARRANTY; without even the implied warranty of
26 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 # GNU General Public License for more details.
29 # You should have received a copy of the GNU General Public License
30 # along with this program; if not, write to the Free Software Foundation,
31 # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
33 # ***** END GPL LICENCE BLOCK *****
34 # --------------------------------------------------------------------------
39 ######################################################
41 ######################################################
50 from Blender import Mesh, Scene, Object, Material, Texture, Window, sys, Draw, BGL, Mathutils, Lamp, Image
55 ######################################################
57 ######################################################
59 # New name based on old with a different extension
61 return Blender.Get('filename')[: -len(Blender.Get('filename').split('.', -1)[-1]) ] + ext
66 return str.replace("\\", "\\\\")
69 ### relpath ##########################
70 def relpath(base, target):
71 if target[0:2] == "\\\\" or target[0:2] == "//":
72 return target[2:len(target)]
73 if not os.path.isabs(base):
74 base = os.path.abspath(base)
75 if not os.path.isabs(target):
76 target = os.path.abspath(target)
78 base = os.path.normcase(base)
79 target = os.path.normcase(target)
82 baselist = base.split(os.sep)
83 if baselist[-1] == "":
84 baselist = baselist[:-1]
85 targetlist = target.split(os.sep)
87 top = min([len(baselist), len(targetlist)])
88 while i < top and baselist[i] == targetlist[i]:
91 return os.sep.join(targetlist)
92 if i == len(baselist):
93 return os.sep.join(targetlist[i:])
95 return ('..' + os.sep) * (len(baselist) - i) + os.sep.join(targetlist[i:])
97 ### luxFilePath #####################
100 def luxFilePath(filename):
101 global lxs_filename, previewing
102 scn = Scene.GetCurrent()
103 pm = luxProp(scn, "pathmode", "absolute").get()
104 if (pm=="absolute") or previewing: # absolute paths (the old / default mode)
106 elif pm=="relative": # relative paths
107 base = os.path.dirname(lxs_filename)
108 return relpath(base, filename)
109 elif pm=="flat": # flat mode - only filename
110 return os.path.basename(filename)
114 ###### RGC ##########################
116 scn = Scene.GetCurrent()
117 if luxProp(scn, "RGC", "true").get()=="true":
118 gamma = luxProp(scn, "film.gamma", 2.2).get()
122 if luxProp(scn, "colorclamp", "false").get()=="true":
131 scn = Scene.GetCurrent()
132 if luxProp(scn, "RGC", "true").get()=="true":
133 return luxProp(scn, "film.gamma", 2.2).get()
137 def exportMaterial(mat):
138 str = "# Material '%s'\n" %mat.name
139 return str+luxMaterial(mat)+"\n"
142 def exportMaterialGeomTag(mat):
143 return "%s\n"%(luxProp(mat, "link", "").get())
148 ################################################################
151 dummyMat = 2394723948 # random identifier for dummy material
154 #-------------------------------------------------
156 # helper function to get the material list of an object in respect of obj.colbits
157 #-------------------------------------------------
158 def getMaterials(obj, compress=False):
161 colbits = obj.colbits
162 objMats = obj.getMaterials(1)
163 data = obj.getData(mesh=1)
165 dataMats = data.materials
168 dataMats = data.getMaterials(1)
172 m = max(len(objMats), len(dataMats))
174 objMats.extend([None]*16)
175 dataMats.extend([None]*16)
177 if (colbits & (1<<i) > 0):
180 mats[i] = dataMats[i]
182 mats = [m for m in mats if m]
184 print "Warning: object %s has no material assigned"%(obj.getName())
187 if luxProp(Scene.GetCurrent(), "clay", "false").get()=="true":
188 if clayMat==None: clayMat = Material.New("lux_clayMat")
189 for i in range(len(mats)):
191 mattype = luxProp(mats[i], "type", "").get()
192 if (mattype not in ["portal","light","boundvolume"]): mats[i] = clayMat
197 ######################################################
199 ######################################################
202 #-------------------------------------------------
204 # initializes the exporter object
205 #-------------------------------------------------
206 def __init__(self, scene):
208 self.camera = scene.objects.camera
217 #-------------------------------------------------
218 # analyseObject(self, obj, matrix, name)
219 # called by analyseScene to build the lists before export
220 #-------------------------------------------------
221 def analyseObject(self, obj, matrix, name, isOriginal=True, isDupli=False):
224 obj_type = obj.getType()
225 if (obj.enableDupFrames and isOriginal):
226 for o, m in obj.DupObjects:
227 self.analyseObject(o, m, "%s.%s"%(name, o.getName()), False)
228 if (obj.enableDupGroup or obj.enableDupVerts or obj.enableDupFaces):
230 for o, m in obj.DupObjects:
231 self.analyseObject(o, m, "%s.%s"%(name, o.getName()), True, True)
232 elif ((isDupli or (not obj.getParent() in self.duplis)) and ((obj_type == "Mesh") or (obj_type == "Surf") or (obj_type == "Curve") or (obj_type == "Text"))):
233 mats = getMaterials(obj)
234 if (len(mats)>0) and (mats[0]!=None) and ((mats[0].name=="PORTAL") or (luxProp(mats[0], "type", "").get()=="portal")):
235 self.portals.append([obj, matrix])
236 elif (len(mats)>0) and (luxProp(mats[0], "type", "").get()=="boundvolume"):
237 self.volumes.append([obj, matrix])
240 if (mat!=None) and (mat not in self.materials):
241 self.materials.append(mat)
242 if (mat!=None) and ((luxProp(mat, "type", "").get()=="light") or (luxProp(mat, "emission", "false").get()=="true")):
244 mesh_name = obj.getData(name_only=True)
246 self.meshes[mesh_name] += [obj]
248 self.meshes[mesh_name] = [obj]
249 self.objects.append([obj, matrix])
250 elif (obj_type == "Lamp"):
251 ltype = obj.getData(mesh=1).getType() # data
252 if (ltype == Lamp.Types["Lamp"]) or (ltype == Lamp.Types["Spot"]) or (ltype == Lamp.Types["Area"]):
253 self.lights.append([obj, matrix])
257 #-------------------------------------------------
259 # this function builds the lists of object, lights, meshes and materials before export
260 #-------------------------------------------------
261 def analyseScene(self):
263 for obj in self.scene.objects:
264 if ((obj.Layers & self.scene.Layers) > 0):
265 if self.analyseObject(obj, obj.getMatrix(), obj.getName()): light = True
268 #-------------------------------------------------
269 # exportMaterialLink(self, file, mat)
270 # exports material link. LuxRender "Material"
271 #-------------------------------------------------
272 def exportMaterialLink(self, file, mat):
274 file.write("\tMaterial \"matte\" # dummy material\n")
276 file.write("\t%s"%exportMaterialGeomTag(mat)) # use original methode
278 #-------------------------------------------------
279 # exportMaterial(self, file, mat)
280 # exports material. LuxRender "Texture"
281 #-------------------------------------------------
282 def exportMaterial(self, file, mat):
283 print "material %s"%(mat.getName())
284 file.write("\t%s"%exportMaterial(mat)) # use original methode
286 #-------------------------------------------------
287 # exportMaterials(self, file)
288 # exports materials to the file
289 #-------------------------------------------------
290 def exportMaterials(self, file):
291 for mat in self.materials:
293 self.exportMaterial(file, mat)
295 #-------------------------------------------------
296 # getMeshType(self, vertcount, mat)
297 # returns type of mesh as string to use depending on thresholds
298 #-------------------------------------------------
299 def getMeshType(self, vertcount, mat):
300 scn = Scene.GetCurrent()
302 usesubdiv = luxProp(mat, "subdiv", "false")
303 usedisp = luxProp(mat, "dispmap", "false")
304 sharpbound = luxProp(mat, "sharpbound", "false")
305 nsmooth = luxProp(mat, "nsmooth", "true")
306 sdoffset = luxProp(mat, "sdoffset", 0.0)
308 if usesubdiv.get() == "true":
309 nlevels = luxProp(mat, "sublevels", 1)
310 dstr += "\"loopsubdiv\" \"integer nlevels\" [%i] \"bool dmnormalsmooth\" [\"%s\"] \"bool dmsharpboundary\" [\"%s\"]"% (nlevels.get(), nsmooth.get(), sharpbound.get())
312 if usedisp.get() == "true":
313 dstr += " \"string displacementmap\" [\"%s::dispmap.scale\"] \"float dmscale\" [-1.0] \"float dmoffset\" [%f]"%(mat.getName(), sdoffset.get()) # scale is scaled in texture
315 if dstr != "": return dstr
317 return "\"trianglemesh\""
319 #-------------------------------------------------
320 # exportMesh(self, file, mesh, mats, name, portal)
321 # exports mesh to the file without any optimization
322 #-------------------------------------------------
323 def exportMesh(self, file, mesh, mats, name, portal=False):
326 for matIndex in range(len(mats)):
327 if (mats[matIndex] != None):
328 mesh_str = getMeshType(len(mesh.verts), mats[matIndex])
330 file.write("\tShape %s \"integer indices\" [\n"% mesh_str)
332 self.exportMaterialLink(file, mats[matIndex])
333 file.write("\tPortalShape %s \"integer indices\" [\n"% mesh_str)
335 ffaces = [f for f in mesh.faces if f.mat == matIndex]
337 file.write("%d %d %d\n"%(index, index+1, index+2))
339 file.write("%d %d %d\n"%(index, index+2, index+3))
340 index += len(face.verts)
341 file.write("\t] \"point P\" [\n");
344 file.write("%f %f %f\n"% tuple(vertex.co))
345 file.write("\t] \"normal N\" [\n")
351 file.write("%f %f %f\n"% tuple(normal))
353 file.write("\t] \"float uv\" [\n")
356 file.write("%f %f\n"% tuple(uv))
359 #-------------------------------------------------
360 # exportMeshOpt(self, file, mesh, mats, name, portal, optNormals)
361 # exports mesh to the file with optimization.
362 # portal: export without normals and UVs
363 # optNormals: speed and filesize optimization, flat faces get exported without normals
364 #-------------------------------------------------
365 def exportMeshOpt(self, file, mesh, mats, name, portal=False, optNormals=True):
366 shapeList, smoothFltr, shapeText = [0], [[0,1]], [""]
368 normalFltr, uvFltr, shapeText = [0], [0], ["portal"] # portal, no normals, no UVs
370 uvFltr, normalFltr, shapeText = [1], [1], ["mixed with normals"] # normals and UVs
371 if optNormals: # one pass for flat faces without normals and another pass for smoothed faces with normals, all with UVs
372 shapeList, smoothFltr, normalFltr, uvFltr, shapeText = [0,1], [[0],[1]], [0,1], [1,1], ["flat w/o normals", "smoothed with normals"]
375 for matIndex in range(len(mats)):
376 if (mats[matIndex] != None):
378 self.exportMaterialLink(file, mats[matIndex])
379 for shape in shapeList:
380 blenderExportVertexMap = []
383 ffaces = [f for f in mesh.faces if (f.mat == matIndex) and (f.smooth in smoothFltr[shape])]
388 # v = [vertex.co[0], vertex.co[1], vertex.co[2]]
390 if normalFltr[shape]:
392 # v.extend(vertex.no)
397 if (uvFltr[shape]) and (mesh.faceUV):
398 # v.extend(face.uv[index])
399 v.append(face.uv[index])
400 blenderVIndex = vertex.index
403 if (blenderVIndex < len(blenderExportVertexMap)):
404 for exportVIndex in blenderExportVertexMap[blenderVIndex]:
405 v2 = exportVerts[exportVIndex]
406 if (length==len(v2)) and (v == v2):
407 newExportVIndex = exportVIndex
409 if (newExportVIndex < 0):
410 newExportVIndex = len(exportVerts)
411 exportVerts.append(v)
412 while blenderVIndex >= len(blenderExportVertexMap):
413 blenderExportVertexMap.append([])
414 blenderExportVertexMap[blenderVIndex].append(newExportVIndex)
415 exportVIndices.append(newExportVIndex)
417 exportFaces.append(exportVIndices)
418 if (len(exportVerts)>0):
419 mesh_str = self.getMeshType(len(exportVerts), mats[matIndex])
421 file.write("\tPortalShape %s \"integer indices\" [\n"% mesh_str)
423 file.write("\tShape %s \"integer indices\" [\n"% mesh_str)
424 for face in exportFaces:
425 file.write("%d %d %d\n"%(face[0], face[1], face[2]))
427 file.write("%d %d %d\n"%(face[0], face[2], face[3]))
428 file.write("\t] \"point P\" [\n");
429 # for vertex in exportVerts:
430 # file.write("%f %f %f\n"%(vertex[0], vertex[1], vertex[2]))
431 file.write("".join(["%f %f %f\n"%tuple(vertex[0]) for vertex in exportVerts]))
432 if normalFltr[shape]:
433 file.write("\t] \"normal N\" [\n")
434 # for vertex in exportVerts:
435 # file.write("%f %f %f\n"%(vertex[3], vertex[4], vertex[5]))
436 file.write("".join(["%f %f %f\n"%tuple(vertex[1]) for vertex in exportVerts]))
437 if (uvFltr[shape]) and (mesh.faceUV):
438 file.write("\t] \"float uv\" [\n")
439 # for vertex in exportVerts:
440 # file.write("%f %f\n"%(vertex[6], vertex[7]))
441 file.write("".join(["%f %f\n"%tuple(vertex[2]) for vertex in exportVerts]))
443 if (uvFltr[shape]) and (mesh.faceUV):
444 file.write("\t] \"float uv\" [\n")
445 # for vertex in exportVerts:
446 # file.write("%f %f\n"%(vertex[3], vertex[4]))
447 file.write("".join(["%f %f\n"%tuple(vertex[1]) for vertex in exportVerts]))
449 print " shape(%s): %d vertices, %d faces"%(shapeText[shape], len(exportVerts), len(exportFaces))
451 #-------------------------------------------------
452 # exportMeshes(self, file)
453 # exports meshes that uses instancing (meshes that are used by at least "instancing_threshold" objects)
454 #-------------------------------------------------
455 def exportMeshes(self, file):
456 scn = Scene.GetCurrent()
457 instancing_threshold = luxProp(scn, "instancing_threshold", 2).get()
458 mesh_optimizing = luxProp(scn, "mesh_optimizing", True).get()
460 for (mesh_name, objs) in self.meshes.items():
461 allow_instancing = True
462 mats = getMaterials(objs[0]) # mats = obj.getData().getMaterials()
463 for mat in mats: # don't instance if one of the materials is emissive
464 if (mat!=None) and (luxProp(mat, "type", "").get()=="light"):
465 allow_instancing = False
466 for obj in objs: # don't instance if the objects with same mesh uses different materials
467 ms = getMaterials(obj)
469 allow_instancing = False
470 if obj.modifiers.__len__() > 0:
471 allow_instancing = False
472 if allow_instancing and (len(objs) > instancing_threshold):
473 del self.meshes[mesh_name]
474 mesh.getFromObject(objs[0], 0, 1)
475 print "blender-mesh: %s (%d vertices, %d faces)"%(mesh_name, len(mesh.verts), len(mesh.faces))
476 file.write("ObjectBegin \"%s\"\n"%mesh_name)
477 if (mesh_optimizing):
478 self.exportMeshOpt(file, mesh, mats, mesh_name)
480 self.exportMesh(file, mesh, mats, mesh_name)
481 file.write("ObjectEnd # %s\n\n"%mesh_name)
484 #-------------------------------------------------
485 # exportObjects(self, file)
486 # exports objects to the file
487 #-------------------------------------------------
488 def exportObjects(self, file):
489 scn = Scene.GetCurrent()
490 cam = scn.getCurrentCamera().data
491 objectmblur = luxProp(cam, "objectmblur", "true")
492 usemblur = luxProp(cam, "usemblur", "false")
493 mesh_optimizing = luxProp(scn, "mesh_optimizing", True).get()
495 for [obj, matrix] in self.objects:
496 print "object: %s"%(obj.getName())
497 mesh_name = obj.getData(name_only=True)
500 if(objectmblur.get() == "true" and usemblur.get() == "true"):
502 frame = Blender.Get('curframe')
503 Blender.Set('curframe', frame+1)
504 m1 = 1.0*matrix # multiply by 1.0 to get a copy of orignal matrix (will be frame-independant)
505 Blender.Set('curframe', frame)
510 if motion: # motion-blur only works with instances, so ensure mesh is exported as instance first
511 if mesh_name in self.meshes:
512 del self.meshes[mesh_name]
513 mesh.getFromObject(obj, 0, 1)
514 mats = getMaterials(obj)
515 print " blender-mesh: %s (%d vertices, %d faces)"%(mesh_name, len(mesh.verts), len(mesh.faces))
516 file.write("ObjectBegin \"%s\"\n"%mesh_name)
517 if (mesh_optimizing):
518 self.exportMeshOpt(file, mesh, mats, mesh_name)
520 self.exportMesh(file, mesh, mats, mesh_name)
521 file.write("ObjectEnd # %s\n\n"%mesh_name)
523 file.write("AttributeBegin # %s\n"%obj.getName())
524 file.write("\tTransform [%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s]\n"\
525 %(matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3],\
526 matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3],\
527 matrix[2][0], matrix[2][1], matrix[2][2], matrix[2][3],\
528 matrix[3][0], matrix[3][1], matrix[3][2], matrix[3][3]))
530 file.write("\tTransformBegin\n")
531 file.write("\t\tIdentity\n")
532 file.write("\t\tTransform [%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s]\n"\
533 %(motion[0][0], motion[0][1], motion[0][2], motion[0][3],\
534 motion[1][0], motion[1][1], motion[1][2], motion[1][3],\
535 motion[2][0], motion[2][1], motion[2][2], motion[2][3],\
536 motion[3][0], motion[3][1], motion[3][2], motion[3][3]))
537 file.write("\t\tCoordinateSystem \"%s\"\n"%(obj.getName()+"_motion"))
538 file.write("\tTransformEnd\n")
539 if mesh_name in self.meshes:
540 mesh.getFromObject(obj, 0, 1)
541 mats = getMaterials(obj)
542 print " blender-mesh: %s (%d vertices, %d faces)"%(mesh_name, len(mesh.verts), len(mesh.faces))
543 if (mesh_optimizing):
544 self.exportMeshOpt(file, mesh, mats, mesh_name)
546 self.exportMesh(file, mesh, mats, mesh_name)
548 print " instance %s"%(mesh_name)
550 file.write("\tMotionInstance \"%s\" 0.0 1.0 \"%s\"\n"%(mesh_name, obj.getName()+"_motion"))
552 file.write("\tObjectInstance \"%s\"\n"%mesh_name)
553 file.write("AttributeEnd\n\n")
556 #-------------------------------------------------
557 # exportPortals(self, file)
558 # exports portals objects to the file
559 #-------------------------------------------------
560 def exportPortals(self, file):
561 scn = Scene.GetCurrent()
562 mesh_optimizing = luxProp(scn, "mesh_optimizing", True).get()
564 for [obj, matrix] in self.portals:
565 print "portal: %s"%(obj.getName())
566 file.write("\tTransform [%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s]\n"\
567 %(matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3],\
568 matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3],\
569 matrix[2][0], matrix[2][1], matrix[2][2], matrix[2][3],\
570 matrix[3][0], matrix[3][1], matrix[3][2], matrix[3][3]))
571 mesh_name = obj.getData(name_only=True)
572 mesh.getFromObject(obj, 0, 1)
573 mats = getMaterials(obj) # mats = obj.getData().getMaterials()
574 if (mesh_optimizing):
575 self.exportMeshOpt(file, mesh, mats, mesh_name, True)
577 self.exportMesh(file, mesh, mats, mesh_name, True)
580 #-------------------------------------------------
581 # exportLights(self, file)
582 # exports lights to the file
583 #-------------------------------------------------
584 def exportLights(self, file):
585 for [obj, matrix] in self.lights:
586 ltype = obj.getData(mesh=1).getType() # data
587 if (ltype == Lamp.Types["Lamp"]) or (ltype == Lamp.Types["Spot"]) or (ltype == Lamp.Types["Area"]):
588 print "light: %s"%(obj.getName())
589 if ltype == Lamp.Types["Area"]:
590 (str, link) = luxLight("", "", obj, None, 0)
592 if ltype == Lamp.Types["Area"]: file.write("AttributeBegin # %s\n"%obj.getName())
593 else: file.write("TransformBegin # %s\n"%obj.getName())
594 file.write("\tTransform [%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s]\n"\
595 %(matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3],\
596 matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3],\
597 matrix[2][0], matrix[2][1], matrix[2][2], matrix[2][3],\
598 matrix[3][0], matrix[3][1], matrix[3][2], matrix[3][3]))
599 col = obj.getData(mesh=1).col # data
600 energy = obj.getData(mesh=1).energy # data
601 if ltype == Lamp.Types["Lamp"]:
602 lightgroup = luxProp(obj, "light.lightgroup", "default")
603 if luxProp(Scene.GetCurrent(), "nolg", "false").get()!="true":
604 file.write("LightGroup \"%s\"\n"%lightgroup.get())
605 (str, link) = luxLamp("", "", obj, None, 0)
606 file.write(str+"LightSource \"point\""+link+"\n")
607 if ltype == Lamp.Types["Spot"]:
608 (str, link) = luxSpot("", "", obj, None, 0)
610 proj = luxProp(obj, "light.usetexproj", "false")
611 if luxProp(Scene.GetCurrent(), "nolg", "false").get()!="true":
612 lightgroup = luxProp(obj, "light.lightgroup", "default")
613 file.write("LightGroup \"%s\"\n"%lightgroup.get())
614 if(proj.get() == "true"):
615 file.write("Rotate 180 0 1 0\n")
616 file.write("LightSource \"projection\" \"float fov\" [%f]"%(obj.getData(mesh=1).spotSize))
618 file.write("LightSource \"spot\" \"point from\" [0 0 0] \"point to\" [0 0 -1] \"float coneangle\" [%f] \"float conedeltaangle\" [%f]"\
619 %(obj.getData(mesh=1).spotSize*0.5, obj.getData(mesh=1).spotSize*0.5*obj.getData(mesh=1).spotBlend)) # data
620 file.write(link+"\n")
621 if ltype == Lamp.Types["Area"]:
622 lightgroup = luxProp(obj, "light.lightgroup", "default")
623 if luxProp(Scene.GetCurrent(), "nolg", "false").get()!="true":
624 file.write("LightGroup \"%s\"\n"%lightgroup.get())
625 file.write("\tAreaLightSource \"area\"")
627 # file.write(luxLight("", "", obj, None, 0))
629 areax = obj.getData(mesh=1).getAreaSizeX()
630 # lamps "getAreaShape()" not implemented yet - so we can't detect shape! Using square as default
632 if (True): areay = areax
633 else: areay = obj.getData(mesh=1).getAreaSizeY()
634 file.write('\tShape "trianglemesh" "integer indices" [0 1 2 0 2 3] "point P" [-%(x)f %(y)f 0.0 %(x)f %(y)f 0.0 %(x)f -%(y)f 0.0 -%(x)f -%(y)f 0.0]\n'%{"x":areax/2, "y":areay/2})
635 if ltype == Lamp.Types["Area"]: file.write("AttributeEnd # %s\n"%obj.getName())
636 else: file.write("TransformEnd # %s\n"%obj.getName())
640 #-------------------------------------------------
641 # exportVolumes(self, file)
642 # exports volumes to the file
643 #-------------------------------------------------
644 def exportVolumes(self, file):
645 for [obj, matrix] in self.volumes:
646 print "volume: %s"%(obj.getName())
647 file.write("# Volume: %s\n"%(obj.getName()))
649 # trickery to obtain objectspace boundingbox AABB
650 mat = obj.matrixWorld.copy().invert()
651 bb = [vec * mat for vec in obj.getBoundBox()]
652 minx = miny = minz = 100000000000000.0
653 maxx = maxy = maxz = -100000000000000.0
655 if (vec[0] < minx): minx = vec[0]
656 if (vec[1] < miny): miny = vec[1]
657 if (vec[2] < minz): minz = vec[2]
658 if (vec[0] > maxx): maxx = vec[0]
659 if (vec[1] > maxy): maxy = vec[1]
660 if (vec[2] > maxz): maxz = vec[2]
662 file.write("Transform [%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s]\n"\
663 %(matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3],\
664 matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3],\
665 matrix[2][0], matrix[2][1], matrix[2][2], matrix[2][3],\
666 matrix[3][0], matrix[3][1], matrix[3][2], matrix[3][3]))
668 str_opt = (" \"point p0\" [%f %f %f] \"point p1\" [%f %f %f]"%(minx, miny, minz, maxx, maxy, maxz))
669 mats = getMaterials(obj)
670 if (len(mats)>0) and (mats[0]!=None) and (luxProp(mats[0], "type", "").get()=="boundvolume"):
672 (str, link) = luxMaterialBlock("", "", "", mat, None, 0, str_opt)
673 file.write("%s"%link)
677 # Note - radiance - this is a work in progress
678 def luxFlashBlock(camObj):
680 str += "CoordSysTransform \"camera\"\n"
682 str += "Texture \"camflashtex\" \"color\" \"blackbody\" \"float temperature\" [5500.0]"
683 str += "AreaLightSource \"area\" \"texture L\" [\"camflashtex\"] \"float power\" [100.000000] \"float efficacy\" [17.000000] \"float gain\" [1.000000]\n"
687 str += "Shape \"trianglemesh\" \"integer indices\" [ 0 1 2 0 2 3 ] \"point P\" [ 0.014 0.012 0.0 0.006 0.012 0.0 0.006 0.008 0.0 0.014 0.008 0.0 ]\n"
692 ######################################################
694 ######################################################
696 def save_lux(filename, unindexedname):
698 export_total_steps = 12.0
700 global meshlist, matnames, lxs_filename, geom_filename, geom_pfilename, mat_filename, mat_pfilename, vol_filename, vol_pfilename, LuxIsGUI
702 print("Lux Render Export started...\n")
703 time1 = Blender.sys.time()
704 scn = Scene.GetCurrent()
706 filepath = os.path.dirname(filename)
707 filebase = os.path.splitext(os.path.basename(filename))[0]
709 lxs_filename = filename
711 geom_filename = os.path.join(filepath, filebase + "-geom.lxo")
712 geom_pfilename = filebase + "-geom.lxo"
714 mat_filename = os.path.join(filepath, filebase + "-mat.lxm")
715 mat_pfilename = filebase + "-mat.lxm"
717 vol_filename = os.path.join(filepath, filebase + "-vol.lxv")
718 vol_pfilename = filebase + "-vol.lxv"
720 ### Zuegs: initialization for export class
721 export = luxExport(Blender.Scene.GetCurrent())
723 # check if a light is present
724 envtype = luxProp(scn, "env.type", "infinite").get()
725 if envtype == "sunsky":
727 for obj in scn.objects:
728 if (obj.getType() == "Lamp") and ((obj.Layers & scn.Layers) > 0):
729 if obj.getData(mesh=1).getType() == 1: # sun object # data
731 if not(export.analyseScene()) and not(envtype == "infinite") and not((envtype == "sunsky") and (sun != None)):
732 print("ERROR: No light source found")
733 Draw.PupMenu("ERROR: No light source found%t|OK%x1")
736 if LuxIsGUI: DrawProgressBar(0.0/export_total_steps,'Setting up Scene file')
737 if luxProp(scn, "lxs", "true").get()=="true":
738 ##### Determine/open files
739 print("Exporting scene to '" + filename + "'...\n")
740 file = open(filename, 'w')
742 ##### Write Header ######
743 file.write("# Lux Render v0.6RC5 Scene File\n")
744 file.write("# Exported by LuxBlend Blender Exporter\n")
747 ##### Write camera ######
748 camObj = scn.getCurrentCamera()
750 if LuxIsGUI: DrawProgressBar(1.0/export_total_steps,'Exporting Camera')
752 print "processing Camera..."
754 cammblur = luxProp(cam, "cammblur", "true")
755 usemblur = luxProp(cam, "usemblur", "false")
757 matrix = camObj.getMatrix()
760 if(cammblur.get() == "true" and usemblur.get() == "true"):
762 frame = Blender.Get('curframe')
763 Blender.Set('curframe', frame+1)
764 m1 = 1.0*matrix # multiply by 1.0 to get a copy of original matrix (will be frame-independant)
765 Blender.Set('curframe', frame)
767 # Motion detected, write endtransform
772 target = pos + forwards
774 file.write("TransformBegin\n")
775 file.write(" LookAt %f %f %f \n %f %f %f \n %f %f %f\n" % ( pos[0], pos[1], pos[2], target[0], target[1], target[2], up[0], up[1], up[2] ))
776 file.write(" CoordinateSystem \"CameraEndTransform\"\n")
777 file.write("TransformEnd\n\n")
779 # Write original lookat transform
781 forwards = -matrix[2]
782 target = pos + forwards
784 file.write("LookAt %f %f %f \n %f %f %f \n %f %f %f\n\n" % ( pos[0], pos[1], pos[2], target[0], target[1], target[2], up[0], up[1], up[2] ))
785 file.write(luxCamera(camObj.data, scn.getRenderingContext()))
787 file.write("\n \"string endtransform\" [\"CameraEndTransform\"]")
791 if LuxIsGUI: DrawProgressBar(2.0/export_total_steps,'Exporting Film Settings')
792 ##### Write film ######
793 file.write(luxFilm(scn))
796 if LuxIsGUI: DrawProgressBar(3.0/export_total_steps,'Exporting Pixel Filter')
797 ##### Write Pixel Filter ######
798 file.write(luxPixelFilter(scn))
801 if LuxIsGUI: DrawProgressBar(4.0/export_total_steps,'Exporting Sampler')
802 ##### Write Sampler ######
803 file.write(luxSampler(scn))
806 if LuxIsGUI: DrawProgressBar(5.0/export_total_steps,'Exporting Surface Integrator')
807 ##### Write Surface Integrator ######
808 file.write(luxSurfaceIntegrator(scn))
811 if LuxIsGUI: DrawProgressBar(6.0/export_total_steps,'Exporting Volume Integrator')
812 ##### Write Volume Integrator ######
813 file.write(luxVolumeIntegrator(scn))
816 if LuxIsGUI: DrawProgressBar(7.0/export_total_steps,'Exporting Accelerator')
817 ##### Write Acceleration ######
818 file.write(luxAccelerator(scn))
821 ########## BEGIN World
823 file.write("WorldBegin\n")
826 ########## World scale
827 #scale = luxProp(scn, "global.scale", 1.0).get()
829 # # TODO: not working yet !!!
830 # # TODO: propabily scale needs to be applyed on camera coords too
831 # file.write("Transform [%s 0.0 0.0 0.0 0.0 %s 0.0 0.0 0.0 0.0 %s 0.0 0.0 0.0 0 1.0]\n"%(scale, scale, scale))
834 if LuxIsGUI: DrawProgressBar(8.0/export_total_steps,'Exporting Environment')
835 ##### Write World Background, Sunsky or Env map ######
836 env = luxEnvironment(scn)
838 file.write("AttributeBegin\n")
840 export.exportPortals(file)
841 file.write("AttributeEnd\n")
844 # Note - radiance - this is a work in progress
845 # flash = luxFlashBlock(camObj)
847 # file.write("# Camera flash lamp\n")
848 # file.write("AttributeBegin\n")
849 # #file.write("CoordSysTransform \"camera\"\n")
851 # file.write("AttributeEnd\n\n")
853 #### Write material & geometry file includes in scene file
854 file.write("Include \"%s\"\n\n" %(mat_pfilename))
855 file.write("Include \"%s\"\n\n" %(geom_pfilename))
856 file.write("Include \"%s\"\n\n" %(vol_pfilename))
859 file.write("WorldEnd\n\n")
862 if luxProp(scn, "lxm", "true").get()=="true":
863 if LuxIsGUI: DrawProgressBar(9.0/export_total_steps,'Exporting Materials')
864 ##### Write Material file #####
865 print("Exporting materials to '" + mat_filename + "'...\n")
866 mat_file = open(mat_filename, 'w')
868 export.exportMaterials(mat_file)
872 if luxProp(scn, "lxo", "true").get()=="true":
873 if LuxIsGUI: DrawProgressBar(10.0/export_total_steps,'Exporting Geometry')
874 ##### Write Geometry file #####
875 print("Exporting geometry to '" + geom_filename + "'...\n")
876 geom_file = open(geom_filename, 'w')
879 export.exportLights(geom_file)
880 export.exportMeshes(geom_file)
881 export.exportObjects(geom_file)
885 if luxProp(scn, "lxv", "true").get()=="true":
886 if LuxIsGUI: DrawProgressBar(11.0/export_total_steps,'Exporting Volumes')
887 ##### Write Volume file #####
888 print("Exporting volumes to '" + vol_filename + "'...\n")
889 vol_file = open(vol_filename, 'w')
892 export.exportVolumes(vol_file)
897 if LuxIsGUI: DrawProgressBar(12.0/export_total_steps,'Export Finished')
901 time2 = Blender.sys.time()
902 print("Processing time: %f\n" %(time2-time1))
905 ########################################################################
906 #### Construct server string argument
907 ########################################################################
909 def networkstring(scn):
911 if (luxProp(scn,"network","false").get() == "true"):
912 if (luxProp(scn,"network_use_file","false").get() == "true"):
913 print "read network servers from file: "+ luxProp(scn,"network_file_path","false").get()
914 f = open(luxProp(scn,"network_file_path","false").get())
917 print "add server :" + s
918 servers_string=servers_string+" -u "+ s
921 if luxProp(scn,"network_servers","").get():
922 for server in luxProp(scn,"network_servers","").get().split(","):
923 servers_string=servers_string+" -u "+ server
924 return servers_string
927 #########################################################################
928 ### LAUNCH LuxRender AND RENDER CURRENT SCENE
929 #########################################################################
931 def launchLux(filename):
932 ostype = osys.platform
933 #get blenders 'bpydata' directory
934 datadir=Blender.Get("datadir")
936 scn = Scene.GetCurrent()
937 ic = luxProp(scn, "lux", "").get()
938 ic = Blender.sys.dirname(ic) + os.sep + "luxrender"
940 servers_string = networkstring(scn)
941 update_int=luxProp(scn,"newtork_interval",180).get()
943 if ostype == "win32": ic = ic + ".exe"
944 if ostype == "darwin": ic = ic + ".app/Contents/MacOS/luxrender"
945 checkluxpath = luxProp(scn, "checkluxpath", True).get()
947 if sys.exists(ic) != 1:
948 Draw.PupMenu("Error: Lux renderer not found. Please set path on System page.%t|OK")
950 autothreads = luxProp(scn, "autothreads", "true").get()
951 threads = luxProp(scn, "threads", 1).get()
952 luxnice = luxProp(scn, "luxnice", 0).get()
953 noopengl = luxProp(scn, "noopengl", "false").get()
954 if noopengl == "true":
955 noopengl_str = " --noopengl"
959 if ostype == "win32":
961 if luxnice > 15: prio = "/low"
962 elif luxnice > 5: prio = "/belownormal"
963 elif luxnice > -5: prio = "/normal"
964 elif luxnice > -15: prio = "/abovenormal"
966 if(autothreads=="true"):
967 cmd = "start /b %s \"\" \"%s\" %s %s -i %d \"%s\" "%(prio, ic, noopengl_str, servers_string ,update_int, filename)
969 cmd = "start /b %s \"\" \"%s\" %s %s -i %d \"%s\" --threads=%d"%(prio, ic, noopengl_str, servers_string ,update_int ,filename, threads)
971 if ostype == "linux2" or ostype == "darwin":
972 if(autothreads=="true"):
973 cmd = "(nice -n %d \"%s\" %s %s -i %d \"%s\")&"%(luxnice, ic, noopengl_str, servers_string ,update_int, filename)
976 cmd = "(nice -n %d \"%s\" --threads=%d %s %s -i %d \"%s\")&"%(luxnice, ic, threads, noopengl_str, servers_string ,update_int, filename)
978 # call external shell script to start Lux
979 print("Running Luxrender:\n"+cmd)
982 def launchLuxPiped():
983 ostype = osys.platform
984 #get blenders 'bpydata' directory
985 datadir=Blender.Get("datadir")
987 scn = Scene.GetCurrent()
989 servers_string = networkstring(scn)
990 update_int=luxProp(scn,"newtork_interval",180).get()
992 ic = luxProp(scn, "lux", "").get()
993 ic = Blender.sys.dirname(ic) + os.sep + "luxrender"
994 if ostype == "win32": ic = ic + ".exe"
995 if ostype == "darwin": ic = ic + ".app/Contents/MacOS/luxrender"
996 checkluxpath = luxProp(scn, "checkluxpath", True).get()
998 if sys.exists(ic) != 1:
999 Draw.PupMenu("Error: Lux renderer not found. Please set path on System page.%t|OK")
1001 autothreads = luxProp(scn, "autothreads", "true").get()
1002 threads = luxProp(scn, "threads", 1).get()
1004 if ostype == "win32":
1005 if(autothreads=="true"):
1006 cmd = "\"%s\" - %s -i %d "%(ic,servers_string,update_int)
1008 cmd = "\"%s\" - %s -i %d --threads=%d"%(ic, threads)
1010 if ostype == "linux2" or ostype == "darwin":
1011 if(autothreads=="true"):
1012 cmd = "(\"%s -u %s -i %d\" \"%s\")&"%(ic,servers_string,update_int, filename)
1014 cmd = "(\"%s\" --threads=%d -u %s -i %d \"%s\")&"%(ic, threads,servers_string,update_int, filename)
1016 # call external shell script to start Lux
1017 print("Running Luxrender:\n"+cmd)
1019 import subprocess, os
1021 PIPE = subprocess.PIPE
1022 p = subprocess.Popen(cmd, stdin=PIPE)
1026 def launchLuxWait(filename):
1027 ostype = osys.platform
1028 #get blenders 'bpydata' directory
1029 datadir=Blender.Get("datadir")
1031 scn = Scene.GetCurrent()
1032 luxbatchconsolemode = luxProp(scn, "luxbatchc", "false")
1034 servers_string = networkstring(scn)
1035 update_int=luxProp(scn,"newtork_interval",180).get()
1037 ic = luxProp(scn, "lux", "").get()
1038 if luxbatchconsolemode.get() == "false":
1039 ic = Blender.sys.dirname(ic) + os.sep + "luxconsole"
1040 if ostype == "win32": ic = ic + ".exe"
1041 # radiance - comment out app install for luxconsole on OSX for jensverwiebe
1042 #if ostype == "darwin": ic = ic + ".app/Contents/MacOS/luxconsole"
1043 checkluxpath = luxProp(scn, "checkluxpath", True).get()
1045 if sys.exists(ic) != 1:
1046 Draw.PupMenu("Error: Lux renderer not found. Please set path on System page.%t|OK")
1048 autothreads = luxProp(scn, "autothreads", "true").get()
1049 threads = luxProp(scn, "threads", 1).get()
1051 if ostype == "win32":
1052 if(autothreads=="true"):
1053 cmd = "start /b /WAIT \"\" \"%s\" %s -i %d -f \"%s\" "%(ic,servers_string,update_int, filename)
1055 cmd = "start /b /WAIT \"\" \"%s\" %s -i %d -f \"%s\" --threads=%d"%(ic,servers_string,update_int, filename, threads)
1056 # call external shell script to start Lux
1057 #print("Running Luxrender:\n"+cmd)
1058 #os.spawnv(os.P_WAIT, cmd, 0)
1061 if ostype == "linux2" or ostype == "darwin":
1062 if(autothreads=="true"):
1063 cmd = "\"%s\" %s -i %d -f \"%s\""%(ic,servers_string,update_int, filename)
1065 cmd = "\"%s\" %s -i %d -f --threads=%d \"%s\""%(ic,servers_string,update_int, threads, filename)
1066 subprocess.call(cmd,shell=True)
1068 #### SAVE ANIMATION ####
1069 def save_anim(filename):
1073 startF = Blender.Get('staframe')
1074 endF = Blender.Get('endframe')
1075 scn = Scene.GetCurrent()
1077 Run = luxProp(scn, "run", "true").get()
1079 print("\n\nRendering animation (frame %i to %i)\n\n"%(startF, endF))
1081 for i in range (startF, endF+1):
1082 Blender.Set('curframe', i)
1083 print("Rendering frame %i"%(i))
1085 frameindex = ("-%05d" % (i)) + ".lxs"
1086 indexedname = sys.makename(filename, frameindex)
1087 unindexedname = filename
1088 luxProp(scn, "filename", Blender.Get("filename")).set(sys.makename(filename, "-%05d" % (Blender.Get('curframe'))))
1091 if save_lux(filename, unindexedname):
1092 launchLuxWait(filename)
1094 save_lux(indexedname, unindexedname)
1098 print("\n\nFinished Rendering animation\n")
1100 #### SAVE STILL (hackish...) ####
1101 def save_still(filename):
1103 scn = Scene.GetCurrent()
1104 luxProp(scn, "filename", Blender.Get("filename")).set(sys.makename(filename, ""))
1106 unindexedname = filename
1107 if save_lux(filename, unindexedname):
1108 if runRenderAfterExport: #(run == None and luxProp(scn, "run", "true").get() == "true") or run:
1112 ######################################################
1114 ######################################################
1116 def base64value(char):
1117 if 64 < ord(char) < 91: return ord(char)-65
1118 if 96 < ord(char) < 123: return ord(char)-97+26
1119 if 47 < ord(char) < 58: return ord(char)-48+52
1120 if char == '+': return 62
1123 def decodeIconStr(s):
1124 buf = BGL.Buffer(BGL.GL_BYTE, [16,16,4])
1129 buf[y][x][c] = int(base64value(s[offset])*4.048)
1133 def decodeLogoStr(s):
1134 buf = BGL.Buffer(BGL.GL_BYTE, [18,118,4])
1137 for x in range(118):
1139 buf[y][x][c] = int(base64value(s[offset])*4.048)
1143 def decodeArrowStr(s):
1144 buf = BGL.Buffer(BGL.GL_BYTE, [22,22,4])
1149 buf[y][x][c] = int(base64value(s[offset])*4.048)
1153 def decodeBarStr(s):
1154 buf = BGL.Buffer(BGL.GL_BYTE, [17,138,4])
1157 for x in range(138):
1159 buf[y][x][c] = int(base64value(s[offset])*4.048)
1163 arrow_down = decodeArrowStr("///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///Q///G///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///3///e///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///V///////7///D///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///1///////////e///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///a///////////////7///C///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///B///5///////////////////c///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///f///////////////////////7///C///A///A///A///A///A///A///A///A///A///A///A///A///A///C///6///////////////////////////c///A///A///A///A///A///A///A///A///A///A///A///A///A///i///////////////////////////////6///C///A///A///A///A///A///A///A///A///A///A///A///G///9///////////////////////////////////e///A///A///A///A///A///A///A///A///A///A///I///n///////////////////////////////////////6///N///A///A///A///A///A///A///A///A///A///L///b///e///e///e///e///e///e///e///e///e///g///O///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A")
1165 arrow_right = decodeArrowStr("///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///L///I///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///b///n///G///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///e///////9///i///C///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///e///////////////6///f///B///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///e///////////////////////5///a///A///A///A///A///A///A///A///A///A///A///A///A///A///A///e///////////////////////////////1///V///A///A///A///A///A///A///A///A///A///A///A///A///e///////////////////////////////////////3///Q///A///A///A///A///A///A///A///A///A///A///e///////////////////////////////////7///e///G///A///A///A///A///A///A///A///A///A///A///e///////////////////////////7///e///D///A///A///A///A///A///A///A///A///A///A///A///A///e///////////////////7///c///C///A///A///A///A///A///A///A///A///A///A///A///A///A///A///e///////////6///c///C///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///g///6///e///C///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///O///N///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A")
1167 icon_luxblend = decodeLogoStr("///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A/gAA/gAA/gAA/gAA/gAA/gAA/gAa/gA5/gAZ/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A/gAA/gAA/gAA/gAA/gAA/gAA/gAj/gA//gAh/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A/gAA/gAA/gAA/gAA/gAA/gAA/gAC/gAO/gAC/gAB/gAS/gAQ/gAA/gAA/gAA/gAA/gAA///A///A///A/gAA/gAZ/gAu/gA7/gA//gA//gA//gA//gA//gA//gA//gAd/gAA/gAZ/gAu/gA//gA//gA//gA//gA//gA//gA3/gAm/gAI/gAE/gAz/gA//gA//gAZ/gAA/gAA/gAA/gAZ/gA//gA//gAm/gAR/gA//gA//gA//gA//gA//gA//gA//gA//gA//gA//gAz/gAd/gAE/gAA/gA//gA//gAd/gAA/gAI/gAm/gA3/gA//gA//gA//gAR/gAA/gAA/gAA/gAA/gAA/gAu/gA//gAu/gAA/gAA/gAA/gAA/gAA/gAA/gAd/gA//gA//gAA/gAE/gAd/gAz/gA//gA//gA//gA//gA//gA7/gAq/gAV/gAA///A///A///A///A///A///A/gAA/gAA/gAA/gAI/gAK/gAA/gAA/gAA/gAA/gAn/gA//gA//gAc/gAA/gAA/gAA/gAA///A///A///A/gAi/gA//gA//gA//gA//gA//gA//gA//gA//gA//gA//gAd/gAZ/gA//gA//gA//gA//gA//gA//gA//gA//gA//gA//gA7/gAE/gAE/gAz/gA//gA//gAR/gAA/gAZ/gA//gA//gAm/gAA/gAR/gA//gA//gA//gA//gA//gA//gA//gA//gA//gA//gA//gA//gAz/gAA/gA//gA//gAd/gAI/gA7/gA//gA//gA//gA//gA//gAR/gAA/gAA/gAA/gAA/gAA/gAu/gA//gAu/gAA/gAA/gAA/gAA/gAA/gAA/gAd/gA//gA//gAA/gAu/gA//gA//gA//gA//gA//gA//gA//gA//gA//gA//gAi///A///A///A///A///A///A/gAA/gAA/gAA/gAv/gA4/gAA/gAA/gAA/gAD/gA9/gA//gA//gAz/gAA/gAA/gAA/gAA///A///A///A/gA//gA//gAq/gAI/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAu/gA//gA3/gAI/gAA/gAA/gAA/gAA/gAA/gAd/gA//gA//gAR/gAA/gAM/gA7/gA//gA7/gAZ/gA//gA//gAz/gAA/gAA/gAR/gA//gA//gAR/gAA/gAA/gAA/gAA/gAA/gAA/gAE/gAd/gA//gA//gAM/gA//gA//gAd/gAd/gA//gA//gAd/gAI/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAu/gA//gAu/gAA/gAA/gAA/gAA/gAA/gAA/gAd/gA//gA//gAA/gA//gA//gAq/gAA/gAA/gAA/gAA/gAA/gAE/gAq/gA//gA////A///A///A///A///A///A/gAA/gAA/gAA/gAN/gAQ/gAA/gAA/gAA/gAA/gAs/gA//gA//gA+/gAs/gAp/gAZ/gAA///A///A///A/gA//gA//gAd/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAu/gA//gAu/gAA/gAA/gAA/gAA/gAA/gAA/gAR/gA//gA//gAR/gAA/gAA/gAM/gA7/gA//gA//gA//gAz/gAE/gAA/gAA/gAR/gA//gA//gAR/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAR/gA//gA//gAR/gA//gA//gAd/gAd/gA//gA//gAu/gAu/gAu/gAu/gAu/gAu/gAu/gAu/gAu/gAM/gAu/gA//gAu/gAA/gAA/gAA/gAA/gAA/gAA/gAd/gA//gA//gAA/gA//gA//gAd/gAA/gAA/gAA/gAA/gAA/gAA/gAd/gA//gA////A///A///A///A///A///A/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAI/gAA/gAE/gAZ/gAw/gA//gA//gA//gA//gAh///A///A///A/gA//gA//gAd/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAu/gA//gAu/gAA/gAA/gAA/gAA/gAA/gAA/gAR/gA//gA//gAR/gAA/gAA/gAA/gAR/gA//gA//gA//gAI/gAA/gAA/gAA/gAR/gA//gA//gAm/gAd/gAd/gAd/gAd/gAd/gAd/gAd/gA3/gA//gA3/gAA/gA//gA//gAd/gAd/gA//gA//gA//gA//gA//gA//gA//gA//gA//gA//gA//gAR/gAu/gA//gAu/gAA/gAA/gAA/gAA/gAA/gAA/gAd/gA//gA//gAA/gA//gA//gAd/gAA/gAA/gAA/gAA/gAA/gAA/gAd/gA//gA////A///A///A///A///A///A/gAl/gAL/gAA/gAA/gAA/gAA/gAf/gA+/gAd/gAA/gAA/gAT/gA//gA//gA//gA//gA6///A///A///A/gA//gA//gAd/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAu/gA//gAu/gAA/gAA/gAA/gAA/gAA/gAA/gAR/gA//gA//gAR/gAA/gAA/gAE/gAz/gA//gA//gA//gAz/gAE/gAA/gAA/gAR/gA//gA//gA//gA//gA//gA//gA//gA//gA//gA//gA//gA//gAd/gAA/gA//gA//gAd/gAd/gA//gA//gAR/gAR/gAR/gAR/gAR/gAR/gAd/gA//gA//gAR/gAu/gA//gAu/gAA/gAA/gAA/gAA/gAA/gAA/gAd/gA//gA//gAA/gA//gA//gAd/gAA/gAA/gAA/gAA/gAA/gAA/gAd/gA//gA////A///A///A///A///A///A/gAl/gAK/gAA/gAA/gAA/gAA/gAf/gA+/gAd/gAA/gAA/gAT/gA//gA//gA//gA//gA6///A///A///A/gA//gA//gAd/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAu/gA//gAu/gAA/gAA/gAA/gAA/gAA/gAA/gAR/gA//gA//gAR/gAA/gAA/gAz/gA//gA7/gAd/gA//gA//gAm/gAA/gAA/gAR/gA//gA//gAm/gAd/gAd/gAd/gAd/gAd/gAd/gAd/gAu/gA//gA//gAI/gA//gA//gAd/gAd/gA//gA//gAd/gAR/gAR/gAR/gAR/gAR/gAq/gA//gA//gAR/gAu/gA//gA7/gAZ/gAR/gAR/gAR/gAR/gAV/gAz/gA//gA//gAA/gA3/gA//gA7/gAi/gAd/gAd/gAd/gAd/gAd/gAu/gA//gA////A///A///A///A///A///A/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAI/gAA/gAE/gAa/gAw/gA//gA//gA//gA//gAg///A///A///A/gA//gA//gAd/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAu/gA//gAu/gAA/gAA/gAA/gAA/gAA/gAA/gAR/gA//gA//gAR/gAA/gAm/gA//gA7/gAM/gAA/gAZ/gA//gA//gAm/gAA/gAR/gA//gA//gAR/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAR/gA//gA//gAR/gA//gA//gAd/gAE/gAz/gA//gA//gA//gA//gA//gA//gA//gA//gA//gAz/gAA/gAV/gA//gA//gA//gA//gA//gA//gA//gA//gA//gA//gAi/gAA/gAV/gA7/gA//gA//gA//gA//gA//gA//gA//gA//gA//gA////A///A///A///A///A///A/gAA/gAA/gAA/gAO/gAR/gAA/gAA/gAA/gAA/gAt/gA//gA//gA+/gAs/gAq/gAZ/gAA///A///A///A/gA//gA//gAd/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAi/gAu/gAi/gAA/gAA/gAA/gAA/gAA/gAA/gAM/gAu/gAu/gAM/gAm/gA//gA7/gAM/gAA/gAA/gAA/gAm/gA//gA//gAd/gAR/gA//gA//gAd/gAR/gAR/gAR/gAR/gAR/gAR/gAR/gAq/gA//gA//gAM/gA//gA//gAd/gAA/gAA/gAZ/gAm/gAu/gAu/gAu/gAu/gAu/gAq/gAZ/gAA/gAA/gAA/gAI/gAd/gAu/gAu/gAu/gAu/gAu/gAu/gAi/gAV/gAA/gAA/gAA/gAE/gAV/gAd/gAd/gAd/gAd/gAd/gAd/gAu/gA//gA////A///A///A///A///A///A/gAA/gAA/gAA/gAv/gA4/gAA/gAA/gAA/gAD/gA9/gA//gA//gAz/gAA/gAA/gAA/gAA///A///A///A/gA//gA//gAd/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAR/gA//gA//gA//gA//gA//gA//gA//gA//gA//gA//gA//gA//gAm/gAA/gA//gA//gAd/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAd/gA//gA////A///A///A///A///A///A/gAA/gAA/gAA/gAI/gAK/gAA/gAA/gAA/gAA/gAn/gA//gA//gAc/gAA/gAA/gAA/gAA///A///A///A/gA//gA//gAd/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAM/gAu/gAu/gAu/gAu/gAu/gAu/gAu/gAu/gAu/gAu/gAm/gAR/gAA/gAA/gA//gA//gAd/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAd/gA//gA////A///A///A///A///A///A/gAA/gAA/gAA/gAA/gAA/gAA/gAC/gAO/gAC/gAB/gAS/gAP/gAA/gAA/gAA/gAA/gAA///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A/gAA/gAA/gAA/gAA/gAA/gAA/gAj/gA//gAh/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A/gAA/gAA/gAA/gAA/gAA/gAA/gAa/gA5/gAY/gAA/gAA/gAA/gAA/gAA/gAA/gAA/gAA///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A")
1170 icon_blender = decodeIconStr("///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A27wA27wA27wA27wA27wAFFFGIIIsNNN5IIIsFFFG27wA27wA27wA27wA27wA///A27wA27wA27wA27wA27wAFFFmnnn9sss/kkk9FFFm27wA27wA27wA27wA27wA///A27wA27wA27wA27wA27wAEEEvwww/AAA/sss/EEEv27wA27wA27wA27wA27wA///A27wA27wA27wA27wA27wAFFFxzzz/xxx/vvv/FFFx27wA27wA27wA27wA27wA///A27wAGGGRLLLtKKK7KKK9JJJ/111/ppp/xxx/III/JJJ9JJJ7LLLtGGGR27wA///AGGGQPPP8xxx/444/vvv/555/333/999/zzz/xxx/jjj/nnn/nnn/OOO8GGGQ///ALLL2222/zzz/lll/+++/888/666/444/222/000/yyy/aaa/nnn/vvv/LLL2///AMMMxqqq/+++/ttt/////AAA/888/666/444/AAA/000/iii/zzz/nnn/MMMx///AGGGKLLLqKKK7ZZZ/yyy/yyy/yyy/888/vvv/ttt/rrr/VVV/JJJ7LLLqGGGK///A27wA27wA27wAJJJ1999+////sss5UUU8qqq5777/333+III127wA27wA27wA///A27wA27wA27wAHHHJMMMzUUU7GGGpHHHIGGGpSSS7MMMzHHHJ27wA27wA27wA///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A")
1171 icon_col = decodeIconStr("///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A27wA27wA27wA27wAVIAPXKB5VIAS27wA27wA27wA27wA///A///A///A///A///A27wA27wA27wAVIAPXKB8shU/XLC9VIAS27wA27wA27wA///A///A///A///A///A27wA27wAVIAPXKB8ymU/7xd/0qb/XLC9VIAS27wA27wA///A///A///A///A///A27wAVIAPXKA8xkO/7uW/7wa/7xd/0qb/XLC9VIAS27wA///A///A///A///A///AVIAPXKA8xiJ/6rO/6sS/7uW/7wZ/7xd/0qa/XLC9VIAS///A///A///A///A///AXKA1ypd/+6z/6rO/6rO/6sS/7uW/7vZ/7xd/shT/XKB5///A///A///A///A///AVJAMYMC873w/+6z/6rO/6rO/6sS/7uV/ymT/XKB8VIAP///A///A///A///A///A27wAVJAMYMC873w/+6z/6rO/6rO/xkN/XKB8VIAP27wA///A///A///A///A///A27wA27wAVJAMYMC873w/+6z/xiJ/XKA8VIAP27wA27wA///A///A///A///A///A27wA27wA27wAVJAMYMC8xpc/XKA8VIAP27wA27wA27wA///A///A///A///A///A27wA27wA27wA27wAVJAMXKA1VIAP27wA27wA27wA27wA///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A")
1172 icon_float = decodeIconStr("///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A27wA27wA27wA27wAMMMSOOO5MMMP27wA27wA27wA27wA///A///A///A///A///A27wA27wA27wAMMMSPPP9nnn/PPP8MMMP27wA27wA27wA///A///A///A///A///A27wA27wAMMMSPPP9ttt/333/vvv/PPP8MMMP27wA27wA///A///A///A///A///A27wAMMMSOOO9ppp/zzz/111/333/vvv/PPP8MMMP27wA///A///A///A///A///AMMMSOOO9lll/uuu/www/zzz/111/333/vvv/PPP8MMMP///A///A///A///A///AOOO5sss/666/sss/uuu/www/zzz/111/333/kkk/PPP1///A///A///A///A///AMMMPQQQ8444/666/ttt/uuu/www/zzz/ppp/OOO8MMMM///A///A///A///A///A27wAMMMPQQQ8444/666/ttt/uuu/mmm/OOO8MMMM27wA///A///A///A///A///A27wA27wAMMMPQQQ8444/555/jjj/OOO8MMMM27wA27wA///A///A///A///A///A27wA27wA27wAMMMPQQQ8ppp/OOO8MMMM27wA27wA27wA///A///A///A///A///A27wA27wA27wA27wAMMMPOOO1MMMM27wA27wA27wA27wA///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A")
1173 icon_map2d = decodeIconStr("///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A27wA27wA27wA27wA27wAMMMUMMMzMMMzMMMU27wA27wA27wA27wA27wA///A///A27wA27wA27wANNNPMMMyYVQ/wnV/bbb/RRR/MMMyNNNP27wA27wA27wA///A///A27wAMMMLMMMtWUQ/vnZ/7vY/6rP/aaa/eee/ZZZ/PPP/MMMtMMML27wA///A///AMMMfTSQ/tnc/7yg/7uV/6qN/6qM/YYY/ZZZ/ddd/fff/YYY/OOO/MMMf///A///AMMM/71o/7wb/6sQ/rgK/dVG/6qM/YYY/ZZZ/bbb/ccc/fff/ggg/MMM////A///AMMM/92q/AAA/6rP/dVH/AAA/6qM/YYY/ZZZ/bbb/ccc/eee/iii/MMM////A///AMMM/93r/dWI/6rP/dVH/AAA/6qM/XXX/ZZZ/bbb/ccc/eee/iii/MMM////A///AMMM/94t/6sR/6rQ/6rO/6qN/6qM/XXX/ZZZ/bbb/ccc/eee/jjj/MMM////A///AMMM/94u/dWI/dVI/6rP/6rN/6qM/XXX/ZZZ/bbb/ccc/eee/kkk/MMM////A///AMMM/+5v/AAA/AAA/6rP/7vX/94t/xxx/ggg/bbb/ccc/eee/lll/MMM////A///AMMM/+5x/6sR/7xd/+6y/////////////////111/mmm/eee/mmm/MMM////A///AMMM/+72//96/////////////////////////////////666/vvv/MMM////A///AMMMiTTS/wuq/986/////////////////////////555/ppp/SSS/MMMi///A///A27wAMMMHMMMdMMM0aZX/0yu/+97/888/uuu/XXX/MMM0MMMdMMMH27wA///A///A27wA27wA27wA27wANNNLMMMhMMM3MMM3MMMhNNNL27wA27wA27wA27wA///A")
1174 icon_map2dparam = decodeIconStr("///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A27wAQQQB27wA27wA27wA27wA27wA27wA27wA27wA27wA27wA27wA27wA///A///A27wAUUUwMMM9EEE3AAAvAAAlAAAbAAAI27wA27wA27wA27wA27wA27wA///A///A27wAeeeOVVV9OOO/MMM/CCC/AAA+AAA9AAAg27wA27wA27wA27wA27wA///A///A27wA27wAfffKWWW9ggg/mmm/TTT/AAA/AAA9AAAS27wA27wA27wA27wA///A///A27wA27wA27wAeeeXVVV9hhh/lll/TTT/BBB/BBB6AAAN27wA27wA27wA///A///A27wAAAAK27wA27wAdddgTTT8NNN/NNN/JJJ/VVV9EEE8AAAoAAAG27wA///A///A27wAAAAXAAAA27wA27wAeeeaVVV2QQQ/nnn+222/mmm/PPP9JGF8KGCX///A///A27wAAAAkAAAA27wA27wA27wA27wAVVVXYYY8+++/333/gec+ZPL+XOJq///A///A27wAAAAxAAAB27wA27wA27wA27wA27wAXXXiiii83219ofY8eUO/aQL2///A///A27wAAAA9AAAC27wA27wA27wA27wA27wAgggAWWVwmgc84yt/oeW/gWP1///A///ACCC6AAA/AAA/CCC627wA27wA27wA27wA27wAKFFDKGDzxsm52wq/peW2///A///AAAA/////////AAA/AAABAAAAAAAAAAAA27wA27wALFCFMHE31wr61uo5///A///AAAA/////////AAA/AAA+AAAzAAAmAAAZAAAM27wA27wAKFDJPLH6umez///A///ACCC6AAA/AAA/CCC627wA27wA27wA27wA27wA27wA27wA27wAKFCOOJFf///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A")
1175 icon_map3dparam = decodeIconStr("27wA27wA27wA27wA27wA27wA3nIC6pMJ6pMJ3nIC27wA27wA27wA27wA27wA27wA27wA27wA27wA27wA27wA3nIC6qMj6qM/6qM/6qMj3nIC27wA27wA27wA27wA27wA27wA27wA27wA27wA27wA6pMJ6qM/////////6qM/6pMJ27wA27wA27wA27wA27wA27wA27wA27wA27wANNNOSQMz5qM/////////5qM/SQMzNNNO27wA27wA27wA27wA27wA27wAMMMIMMMrXXX/www/5wg/6qM/5qM/vnX/bbb/PPP/MMMrMMMI27wA27wA27wA27wAMMM1xxx/777/222/yyy/zxu/caY/bbb/ggg/iii/YYY/MMM127wA27wA27wA27wAMMM/+++/zzz/yyy/yyy/yyy/ZZZ/bbb/ddd/fff/kkk/MMM/27wA27wA27wA27wAMMM/////yyy/yyy/yyy/yyy/ZZZ/bbb/ddd/eee/lll/MMM/27wA27wA27wA27wAMMM/////yyy/yyy/yyy/yyy/ZZZ/bbb/ddd/eee/nnn/MMM/27wA27wA27wA3nICRPM//97/yyy/yyy/yyy/yyy/ZZZ/bbb/ddd/eee/rpm/RPM/3nIC27wA3nIC6qMj5qM/6qM/2ue/zzz/444/999/666/rrr/fff/tkU/5qM/5qM/6qMj3nIC6pMJ6qM/////////6qM/+96/////////////////985/6qM/////////6qM/6pMJ6pMJ6qM/////////6qM/+86/////////////////974/6qM/////////6qM/6pMJ3nIC6qMj6qM/6qM/pfM2PPP+mmm/555/000/hhh/PPP+pfM26qM/6qM/6qMj3nIC27wA3nIC6pMJ6pMJ3nICMMMEMMMaMMMwMMMwMMMaMMME3nIC6pMJ6pMJ3nIC27wA///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A")
1176 icon_mat = decodeIconStr("///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A27wA27wA27wAVJAMXKBnXLB1WJA9XLB1XKBnVJAM27wA27wA27wA///A///A///A27wAVAAAWJBgYMD9ukW/1sc/5we/0qY/sgQ/XLB9WJBgVAAA27wA///A///A///A27wAWJBghXM96zk/8yf/7wa/7vY/7vZ/YUN/TQM/aPF9WJBg27wA///A///A///AVIALZNE970o/7wb/QNG/QNG/7vX/7vX/JHD/DDD/bXP/XKB9VIAL///A///A///AXKBpype/8zj/7vX/QNG/QNG/7vX/7vX/sjR/IGD/keS/rfQ/XKBp///A///A///AXLB36zp/7xc/7vX/7vX/7vX/7vX/7vX/7vX/7vX/7vZ/0qZ/XLB3///A///A///AVJA+95x/2rX/fYM/zoU/7vX/7vX/7vX/7vX/7vX/7vY/6wf/VJA+///A///A///AXKB361s/VTO/AAA/NKF/7vX/7vX/meP/IGD/JHD/tkU/1rc/XKB3///A///A///AXKBq0tj/cba/AAA/HGD/7vX/7vX/IGD/AAA/AAA/VTQ/ujW/XKBq///A///A///AVIAMaPG920w/RPN/meP/7vX/7vX/gaM/BAA/HHH/njd/YMD9VIAM///A///A///A27wAWKBilbS995y/91n/8xd/7vZ/7xc/4wh/4yn/iXM9WKBi27wA///A///A///A27wAQQABWKBiaOF9zsj/61s/95x/5zp/xpe/ZNE9WKBiQQAB27wA///A///A///A27wA27wA27wAVIAMXKBqXKB3VJA+XKB3XKBqVIAM27wA27wA27wA///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A")
1177 icon_matmix = decodeIconStr("27wA27wA27wA27wA27wA27wA27wAMIFdUMG7WNF+WNF+SLG5LHFS27wA27wA///A27wA27wA27wA27wA27wASLGAOJGziYN/xmV/wmT/pgQ/jaN/YPH/NJGm27wA///A27wA27wA27wA27wA27wAMIFjlbR/9ye/6sQ/zlJ/sgJ/ofM/ngT/YPH/MIGT///A27wA27wA27wA27wA27wAXQJ/6xk/9xZ/6sQ/5qM/zlK/sfI/ofM/jaN/SLG5///A27wA27wA27wA27wAHHHGgXQ//4r/8xc/7vX/7tR/5pM/zlK/sgJ/pgQ/WMF+///A27wA27wA27wA27wAJOVVYbf/58//y27/wz3/7vY/7tS/4pM/ykJ/vmU/WMF////A27wAAAAALIGkTMG+NQU/Qcu/Sfz/Sfz/Wi1/wz4/7vZ/7sR/6sR/wmW/UMH8///ASLGAOJG1iYN/xmV/kns/Rfz/99+/++//Rfz/z27/8ye/9yc/9zg/iYN/LIFh///AMHFilbR/9ye/6sQ/jns/Rfz/////////Rfz/57///4q/6xk/lbR/NJG227wA///AYQJ96xk/9xZ/6sQ/orw/Tgz/Rfz/Rez/Qdw/Xaf/gXP/XPI/MIGoAAAA27wA///AgXQ//4r/8xc/7vX/7tR/nrw/jms/dhn/ein/WNG/GGGRAAAA27wA27wA27wA///AhYR//7x/91m/8xe/7vY/7tS/4pM/ykJ/vmU/WMF/GGGH27wA27wA27wA27wA///AbTM995x//+6/80k/8ye/7vZ/7sR/6sR/wmW/TMG+27wA27wA27wA27wA27wA///APIEitld///7//+6/91n/8ye/9yc/9zg/iYN/LIGk27wA27wA27wA27wA27wA///ARKGCRKFyskc/94v//7w//4q/6xk/lbR/OJG0AAAA27wA27wA27wA27wA27wA///A27wAQJECPIEibTL9hYQ/gXP/YQJ9MHEi27wA27wA27wA27wA27wA27wA27wA///A")
1178 icon_tex = decodeIconStr("///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///AOOO6MMM/MMM/MMM/MMM/MMM/MMM/MMM/MMM/MMM/MMM/MMM/OOO6///A///A///AMMM/444/555/555/555/555/666/666/777/777/888/888/MMM////A///A///AMMM/555/mmm/TTT/aaa/xxx/111/222/222/QQQ/ZZZ/777/MMM////A///A///AMMM/333/DDD/AAA/AAA/YYY/zzz/111/xxx/AAA/AAA/nnn/MMM////A///A///AMMM/222/DDD/AAA/AAA/bbb/yyy/zzz/111/RRR/AAA/iii/MMM////A///A///AMMM/666/jjj/TTT/ddd/vvv/xxx/yyy/zzz/000/rrr/555/MMM////A///A///AMMM/666/rrr/sss/uuu/vvv/www/xxx/yyy/zzz/000/666/MMM////A///A///AMMM/666/qqq/iii/qqq/uuu/vvv/ppp/nnn/yyy/zzz/555/MMM////A///A///AMMM/777/jjj/AAA/RRR/sss/bbb/AAA/AAA/SSS/yyy/555/MMM////A///A///AMMM/888/mmm/LLL/ccc/rrr/QQQ/AAA/AAA/AAA/www/555/MMM////A///A///AMMM/888/nnn/ooo/ppp/qqq/jjj/HHH/DDD/XXX/www/555/MMM////A///A///AMMM/666/888/888/777/666/666/555/555/555/444/333/MMM////A///A///ANNN4NNN+NNN+NNN+NNN+NNN+NNN+NNN+NNN+NNN+NNN+NNN+OOO4///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A")
1179 icon_texcol = decodeIconStr("///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///AWKA4VJA+VJA+VJA+VJA+VJA+VJA+VJA+VJA+VJA+VJA+VJA+WKA4///A///A///AVIA/82p/93r/93r/93s/93s/93s/93t/94u/94u/94w/95w/VIA////A///A///AVIA/93s/xoV/ZVM/icR/6wf/8zi/80k/80l/USN/daU/94v/VIA////A///A///AVIA/72r/FDC/AAA/AAA/eZP/8yf/8zh/3vg/AAA/AAA/olf/VIA////A///A///AVIA/50p/DCB/AAA/AAA/faO/8xd/8yf/8zh/SPK/AAA/jga/VIA////A///A///AVIA/94t/rhO/WRI/haN/5uY/7wb/8xd/8yf/7yg/tma/72r/VIA////A///A///AVIA/94u/6sQ/6tT/7uV/7uX/7vY/7wa/7xc/8ye/8yg/93s/VIA////A///A///AVIA/94u/6rO/ylO/5sS/7uU/7uW/1qV/yoW/7xc/8ye/93s/VIA////A///A///AVIA/+5w/zlL/DDD/bVK/6tS/mdN/AAA/AAA/YTK/7xc/93r/VIA////A///A///AVIA/+5x/3oL/NKD/mcK/6sQ/WQG/AAA/AAA/BAA/5uZ/93r/VIA////A///A///AVIA/+6z/6qM/6qM/6qM/6rO/ujM/IGC/BBA/aUJ/7vX/93r/VIA////A///A///AVIA/+5w/+6y/+5w/+4v/94t/93s/82r/93r/93r/93r/92p/VIA////A///A///AWJA6VJA/WJB/WJB/WJB/WJB/WJB/WJB/WJB/WJB/WJB/VJA/WJA6///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A")
1180 icon_texmix = decodeIconStr("///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///APPP7ccc/ddd/ccc/bbb/bbb/ddd/eee/RRR9///A///A///A///A///A///A///AYYY+yyy/fff/qqq/000/111/jjj/sss/eee////A///A///A///A///A///A///Aaaa9XXX/AAA/III/rrr/xxx/LLL/GGG/VVV////A///A///A///A///A///A///AZZZ9hhh/JJJ/XXX/rrr/uuu/kkk/eee/YYY////A///A///A///A///A///A///AVYd/sv0/imq/nqu/rrr/ttt/vvv/000/bbb////A///APPP7ccc/ddd/ccc/Ycg/Qcu/Sfz/Sfz/Wi1/fin/RRR/bbb/yyy/bbb////A///AYYY+yyy/fff/qqq/x05/Rfz/99+/++//Rfz/PSX/AAA/AAA/uuu/bbb////A///Aaaa9XXX/AAA/III/orw/Rfz/////////Rfz/lpu/XXX/eee/000/ccc////A///AZZZ9hhh/JJJ/XXX/osw/Tgz/Rfz/Rez/Qdw/Wae/bbb9aaa9YYY9PPP7///A///AYYY9vvv/lll/ppp/rrr/pty/sw1/w06/Ych////A///A///A///A///A///A///AZZZ9sss/SSS/iii/hhh/RRR/bbb/yyy/bbb////A///A///A///A///A///A///AZZZ9rrr/JJJ/eee/SSS/AAA/AAA/uuu/bbb////A///A///A///A///A///A///AZZZ+111/ttt/uuu/ooo/XXX/eee/000/ccc////A///A///A///A///A///A///AOOO4aaa9aaa9ZZZ9ZZZ9bbb9aaa9YYY9PPP7///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A")
1181 icon_texmixcol = decodeIconStr("///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///AaOE7mcS/ndT/mcS/lbS/kbS/ndU/neV/bQH9///A///A///A///A///A///A///AiYP+92o/niY/0tg//4p//6s/pme/wun/neV////A///A///A///A///A///A///AkZP9aYT/AAA/LJF/5vd//2j/OMH/GHH/eVN////A///A///A///A///A///A///AjYP9qlZ/OKE/haO/7wb/+zf/voZ/jgY/hYP////A///A///A///A///A///A///AXae/z27/qty/ux2/9wZ/+yc//1f//5o/lbS////A///AaOE7mcS/ndT/mcS/adh/Qcu/Sfz/Sfz/Wi1/lot/ZUK/leQ//3l/kbR////A///AiYP+92o/niY/0tg/25+/Rfz/99+/++//Rfz/TXc/AAA/BAA/9zg/lbS////A///AkZP9aYT/AAA/LJF/tx2/Rfz/////////Rfz/quz/bZU/lhX//6o/lcS////A///AjYP9qlZ/OKE/haO/uy3/Tgz/Rfz/Rez/Qdw/Ybg/laQ9laQ9iYP9aOE7///A///AhXP9/1f/6sQ/8vW/9wZ/wz4/y28/26//aej////A///A///A///A///A///A///AhXQ98xd/eWH/znR/xmR/ZUK/leQ//3l/kbR////A///A///A///A///A///A///AhYR97xb/TMA/xkL/dVG/AAA/BAA/9zg/lbS////A///A///A///A///A///A///AiYR+/7q//zb//0d/1tb/bZU/lhX//6o/lcS////A///A///A///A///A///A///AZNE4iZS9iZS9iYR9jZQ9laQ9laQ9iYP9aOE7///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A")
1182 icon_texparam = decodeIconStr("///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A27wAOOO5GGG/BBB9AAA5AAAwAAAnAAAO27wA27wA27wA27wA27wA27wA///A875F27wAYYYZPPP/KKK/III/BBB/AAA/AAA/AAAxAAAB27wA27wA27wA27wA///AoooO875K27wAaaaTRRR/eee/lll/SSS/AAA/AAA/AAAk27wA27wA27wA27wA///AeeeX222V876J27wAbbbkSSS/iii/mmm/TTT/AAA/AAA/CCCW27wA27wA27wA///AXXXfxxxftttW887I27wAcccwSSS/OOO/PPP/III/RRR/CCC/CCC3CCCL27wA///ATTTmtttsQQQvbbbd887H27wAdddrVVV/PPP/hhh/222/lll/NNN/HFE/KFCo///APPPssss3HHH6NNNwZZZd988G27wA27wAXXXlXXX/999/333/jhg/ZPK/WOJ5///AMMMvsss/jjj1XXXxrrrf333R998F27xA27wAYYYvggg/554/meX/eUO/ZQL////AJJJyvvv/jjj/oooztttoyyyc444Q999E27xAfffAYXW7jeZ/4yt/pfX/gWP////AHHH0zzz/iii/jjj+oooytttnlllggggX+99D27xALFAFKGD9wql/2wr/peW////AFFF3333/HHH/QQQ/jjj9mmmyDDD8KKKxTTTe555D26xAIFDKMHE+0vq/1uo////ADDD6666/HHH/QQQ/jjj/kkk8DDD+BBB+JJJyrrrR+++C26xAKFDROKG/wog+///ABBB9555/777/333/000/www/rrr9bbb6fffv000Y555M///B26xAKFCYOKF0///ABBB5BBB9DDD6EEE4GGG1IIIzKKKxNNNtPPPmSSSfUUUXUUUODDDE26xA27wA///A")
1184 icon_emission = decodeIconStr("///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A27wA27wA27wAAAAgAAA/AAAg27wA27wA27wA///A///A///A///A///A///A///A27wAAAAFAAAxAAA/AAA/AAA/AAAxAAAF27wA///A///A///A///A///A///A///A27wAAAAZooo5////444/nnn/KKK2AAAZ27wA///A///A///A///A///A///A///A27wAAAALSSS/ggg/bbb/AAA/AAA/AAAL27wA///A///A///A///A///A///A///A27wAAAAYrrr/////777/nnn/KKJ+AAAZ27wA///A///A///A///A///A///A///A27wAPNBRTRI+kiX8ebQ+ebN8NLA+PNCP27wA///A///A///A///A///A///A///AQQABVRB1qlQ483g2qlR+81Z2pkO6VRB0QQAB///A///A///A///A///A///A///ATQBlieP685t361ezjcD+5ySx61c0dYG6TQBl///A///A///A///A///A///A///AVRA453x650gwhbB93vRthbB+4yXvwrX0VRA4///A///A///A///A///A///A///AVRA+++8941ow2xbs0tRp0tRp1vUr2yiyVRA+///A///A///A///A///A///A///AUQA48868/++999772yiszuYo2yhsvsdxVRA5///A///A///A///A///A///A///ATPBlqof6//////++64yy64yy7611cYK4TPBl///A///A///A///A///A///A///AKKABUQA1qnf59989//++6525ifT4UQA1KKAB///A///A///A///A///A///A///A27wAKKABSPBkUQA4VQA+UQA4SPBkKKAB27wA///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A")
1186 icon_spectex = decodeIconStr("///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///AAAATGGGzAAAiAAAA27wA27wA27wA27wA27wA27wA27wAAAADAAAjGGGxAAAT///AFFFy555/SBx/MA5+ASx9AhZ9ArC9AwA9WvA9xnA9/WA97AA/xBB/555/FFFz///AAAAUccc/ka1/MA6/ASx/AhZ/ArC/AwA/WvA/xnA//WA/9AA/1ff/SSS+AAAZ///A27wAMMM6ph2/MA6/Xi0/AhZ/ArC/AwA/WvA/xnA//WA/1bb/jjj/AAAY27wA///A27wABBBnpmv/ni6/lr1/AhZ/ArC/AwA/WvA/xnA//WA/6vv/SSS/AAAE27wA///A27wAAAAEGGG1PPP/SUY/Zsn/ArC/AwA/hyS/xnA//WA/5uu/DDDw27wA27wA///A27wA27wAAAABAAAEIII3oyw/ArC/WvW/syn/31u/3vr/nll/AAAa27wA27wA///A27wA27wA///A///AAAAnlus/BrE/v4v/TTT/kkk/444/PPP+AAAE27wA27wA///A27wA27wA27wA27wAAAAZnnn/444/555/GGG3AAAdEEExAAAM27wA27wA27wA///A27wA27wA27wA27wAAAAKaaa/555/zzz/AAAn27wA27wA27wA27wA27wA27wA///A27wA27wA27wA27wAAAAALLL8555/iii/AAAX27wA27wA27wA27wA27wA27wA///A27wA27wA27wA27wA27wAAAAPKKK6AAArAAAB27wA27wA27wA27wA27wA27wA///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A")
1188 icon_c_filter = decodeIconStr("///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///AAAASGGG1BBBsAAAW27wA27wA27wA27wA27wA27wA27wAAAAWBBBsGGGyAAAU///AHHHx555/333/ddd/AAAl27wA27wA27wA27wA27wAAAAlddd/333/555/FFFz///AAAAUMMM8eee/555/ccc/AAAT27wA27wA27wAAAATccc/555/eee/MMM8AAAV///A27wAAAAAAAAbfff/222/GGG1AAAA27wAAAAAGGG1222/fff/AAAbAAAA27wA///A27wA27wAAAAAFFFz222/hhh/AAAW27wAAAAWhhh/222/FFFzAAAA27wA27wA///A27wA27wA27wAAAAQccc/333/EEEz27wAEEEz333/ccc/AAAQ27wA27wA27wA///A27wA27wA27wA27wAGGG1444/aaa/AAAdaaa/444/GGG127wA27wA27wA27wA///A27wA27wA27wA27wAAAAakkk/000/UUU/000/kkk/AAAa27wA27wA27wA27wA///A27wA27wA27wA27wAAAACGGG1xxx/555/xxx/GGG1AAAC27wA27wA27wA27wA///A27wA27wA27wA27wA27wAAAAFAAAoJJJ1AAAoAAAF27wA27wA27wA27wA27wA///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A")
1190 icon_c_camera = decodeIconStr("///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A27wA27wA27wA27wAAAAAAAABAAABAAABAAABAAAA27wA27wA27wA27wA///A///ANNN6MMM/MMM/JJJ/MMM/LLL/LLL/LLL/LLL/MMM/MMM/MMM/MMM/OOO6///A///AMMM/vvv/ttt/ccc/mmm/jjj/ggg/hhh/jjj/ooo/sss/www/iii/MMM////A///AMMM/uuu/eee/RRR/XXX/ZZZ/mmm/xxx/ppp/ggg/jjj/ppp/eee/MMM////A///AMMM/ttt/aaa/OOO/WWW/rrr/aaa/TTT/jjj/zzz/hhh/lll/ccc/MMM////A///AMMM/sss/XXX/LLL/ggg/QQQ/HHH/KKK/QQQ/hhh/rrr/ggg/bbb/MMM////A///AMMM/rrr/VVV/JJJ/ooo/QQQ/TTT/III/JJJ/RRR/yyy/ddd/ZZZ/MMM////A///AMMM/sss/UUU/JJJ/eee/eee/www/RRR/EEE/VVV/ooo/ccc/ZZZ/MMM////A///AMMM/uuu/VVV/KKK/RRR/kkk/fff/QQQ/OOO/ooo/bbb/eee/ZZZ/MMM////A///AMMM/xxx/WWW/LLL/NNN/SSS/eee/ooo/hhh/YYY/YYY/ggg/ZZZ/MMM////A///AMMM/zzz/vvv/aaa/fff/VVV/OOO/PPP/RRR/bbb/mmm/sss/fff/NNN9///A///ANNN6MLJ/MJE/IHG/OOO+ggg/bbb/ccc/eee/jjj/NNN+MMM/NNN9MMMP///A///A27wAMHAl9jA/NIApMMMmWWW/888/////888/bbb/NNNmAAAA27wA27wA///A///A27wALGAPMHAoMHASMMMGSSS/777/////888/WWW/NNNF27wA27wA27wA///A///A27wA27wA27wA27wA27wARRRiPPP+QQQ/RRR+VVVi27wA27wA27wA27wA///A")
1192 icon_c_environment = decodeIconStr("///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///AGMV1HNV7HNV7HNV7HNV7HNV7HNV7HNV7HNV7HNV7HNV7GMV1///A///A///A///AHNV7y0u/z0u/y0t/xzs/wyr/wyq/vxp/uxo/twn/svm/HNV7///A///A///A///AIOW8341/tvm/qtj/qtj/qtj/qtj/qtj/qtj/qtj/two/HNV7///A///A///A///AINV8sts/cdc/qrp/uxp/qtj/qtj/qtj/qtj/qtj/tvo/HNU7///A///A///A///AGMV7svy/Ubh/VZb/ZZZ/xyt/ruk/qtj/qtj/rul/bcb/GLU7///A///A///A///AGMV7twz/Uci/Uci/Tbg/TUU/ssq/y0u/vxr/TVT/fko/GMV7///A///A///A///AGMV7vy0/Vdj/Zgl/Xfk/Uci/RWZ/TVV/PSU/Tag/hnr/GMV7///A///A///A///AGMV7wz1/gmq/023/txz/Xfk/Uci/Uci/Uci/Uci/jos/GMV7///A///A///A///AGMV7y02/jos/////023/Zgl/Uci/Uci/Uci/Uci/kpt/GMV7///A///A///A///AGMV7z23/ahm/jos/gmq/Vdj/Uci/Uci/Uci/Uci/mru/GMV7///A///A///A///AGMV7x02/023/y02/wz1/vy0/uxz/swy/rux/ptw/lqu/GMV7///A///A///A///AGMV1GMV7GMV7GMV7GMV7GMV7GMV7GMV7GMV7GMV7GMV7GMV1///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A")
1194 icon_c_sampler = decodeIconStr("///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A27wA27wA27wAMMMXSSS3MMMg27wA27wA27wA27wAMMMdTTT2MMMc27wA27wA27wA27wA27wAMMMSggg/////XXX+MMMB27wA27wA27wAUUU8////jjj/MMMT27wA27wA27wAMMMIYYY8+++/xxx/NNNuMMMCMMMCMMMCMMMCNNNqwww/////ZZZ9MMMJ27wAMMMASSS0666/+++/fff/bbb/bbb/eee/eee/bbb/bbb/ddd/999/777/SSS327wAMMMGjjj/////////////////////////////////////////////////lll/MMMI27wARRRz555/999/ccc/YYY/YYY+aaa+bbb+YYY+YYY+bbb/999/666/RRR2MMMB27wAMMMHWWW7999/yyy/NNNu27wA27wA27wA27wANNNtxxx/+++/YYY8MMMI27wAVVqARfzGOTZZeee/////WWW+QctHRfzLRfzLRfzGUUU8////hhh/OSYaRfzGVVqARfzGRezcRfz5PXj8STV5NPSiRezcRfz5Rfz5RezcNQThRST6PYk7Rfz5RezcRfzGRfzLRfz5////////Rfz5RfzMRfz5////////Rfz5RfzMRfz5////////Rfz5RfzLRfzLRfz5////////Rfz5RfzMRfz5////////Rfz5RfzMRfz5////////Rfz5RfzLRfzGRezcRfz5Rfz5RezcRfzKRezcRfz5Rfz5RezcRfzKRezcRfz5Rfz5RezcRfzGVVqARfzGRfzLRfzLRfzGVVqARfzGRfzLRfzLRfzGVVqARfzGRfzLRfzLRfzGVVqA///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A")
1196 icon_c_integrator = decodeIconStr("///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A27wA27wAAAAAEJPYHMT0MRY+GLS0EJPYAAAA27wA27wA27wA27wA27wA27wA27wA27wAAAVAEJPoVai/lr0/elv/Xeo/LRZ/EIPnDHOEAAVA27wA27wA27wA27wA27wA27wAEIPcZel/rw5/cir/NTb/SYi/PWh/MSb/QVd/KPW6EJPfAJSB27wA27wA27wAAAAAHMT4ty7/hmv/FKQyDGMXEJP7bhq/nt2/pv4/sy6/diq/EJQuIIQC27wA27wAFIQGRWd/u08/TYf/CFKQDGLfUai/flv/Zfp/SZj/bgp/rx6/fks/EJQuAJSB27wAAJSBINT7uz8/glt/EIOqGKQ4Xeo/SYi/KQY/SZk/IOW/Ydl/ty7/diq/EJPg27wA27wAEJPhflt/u08/Yel/JOW/QXi/HNV/TZi/Yfp/GLS6EJPuejr/tz8/HMT6AMMB27wAGGMCFLRxiow/u08/ciq/SZk/Yeo/gnw/Vaj/DINhDGJQQVd/u08/SXe/FIQG27wA27wAFJODFKRyhmu/u08/sy7/pv4/cir/FJQ7CGLTEIPudir/uz8/JOU6AMMB27wA27wA27wAFJODEJPjKPW8UZh/RXg/RYj/QXg/MSa/Zfo/pv4/diq/EJPg27wA27wA27wA27wA27wA27wAFKQDEIPLEJPtPVe/ahr/flv/jpz/diq/FJQtAJSB27wA27wA27wA27wA27wA27wA27wA27wAAMMBEJPeGLS5OUb/INU5EJPeAMMB27wA27wA27wA27wA27wA27wA27wA27wA27wA27wA27wAAAAAEIQEAAVA27wA27wA27wA27wA///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A")
1198 icon_c_volumeintegrator = decodeIconStr("///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A27wA27wA27wA27wAMMMAMMMWNNN8NNN9MMMWMMMA27wA27wA27wA27wA///A27wA27wAAAAAEJPYIMS3MRY/KOU/gik/ggg/TTT/MMMzMMMR27wA27wA27wA27wA27wAAAVAFJPtVai/lr0/elv/Xeo/LRZ/NQU/ggh/ddd/RRR/MMMvMMMN27wA27wA27wAHKOvZel/rw5/cir/NTb/SYi/PWh/MSb/QVd/LQW/TWZ/aaa/PPP/MMMh27wAAAAAIMS/ty7/hmv/OSX/gik/HMS/bhq/nt2/pv4/sy6/diq/MQV/hhh/MMM/27wAFIQGRWd/u08/TYf/lmn/bdf/Uai/flv/Zfp/SZj/bgp/rx6/fks/NRV/MMN/27wAAJSBINT/uz8/glt/TWa/LPU/Xeo/SYi/KQY/SZk/IOW/Ydl/ty7/diq/IKO/27wA27wAIKO/flt/u08/Yel/JOW/QXi/HNV/TZi/Yfp/INT/LOT/ejr/tz8/IMT/AMMB27wAMMM/SWb/iow/u08/ciq/SZk/Yeo/gnw/Vaj/PRU/XXY/QVd/u08/SXe/FIQG27wAMMM/899/PTY/hmu/u08/sy7/pv4/cir/HLR/UVX/KOT/dir/uz8/JOU/AMMB27wAMMM/////vww/WZd/MRX/UZh/RXg/RYj/QXg/MSa/Zfo/pv4/diq/IKO/27wA27wAMMM/////999/////999/123/VZd/PVe/ahr/flv/jpz/diq/RUa/MMN/27wA27wAMMMxRRR/rrr/888/////////+++/jmp/MRX/OUb/NRX/WYb/PQQ/MMMx27wA27wA27wANNNEMMMaMMMxWWW/www/+++/999/uuu/UUV/MMMxMMMaNNNE27wA27wA///A27wA27wA27wA27wANNNIMMMfMMM1MMM1MMMfNNNI27wA27wA27wA27wA///A")
1200 icon_help = decodeIconStr("///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A27wA27wA27wAAAAOGGGtFFF4HHH6GGG3GGGqAAAK27wA27wA27wA///A///A///A27wAAAABEEEnNNN7vvv/666/888/888/vvv/III7EEEgAAAA27wA///A///A///A27wAEEEmfff+333/333/333/lll/999/999/999/WWW8EEEd27wA///A///A///AAAAPSSS7333/zzz/111/xxx/III/+++/777/999/999/JJJ6AAAJ///A///A///AFFFtxxx/yyy/xxx/zzz/444/999/777/666/777/999/ppp/FFFh///A///A///AEEE4555/uuu/vvv/xxx/ttt/MMM/yyy/666/666/777/111/GGGy///A///A///AJJJ7666/sss/ttt/vvv/yyy/ttt/HHH/yyy/666/555/777/FFF5///A///A///ADDD3777/sss/qqq/lll/vvv/yyy/sss/EEE/777/444/xxx/GGGv///A///A///ADDDq000/xxx/iii/FFF/kkk/lll/hhh/HHH/555/333/kkk/DDDe///A///A///AAAAJNNN8999/rrr/iii/DDD/DDD/GGG/000/000/000/GGG6AAAE///A///A///A27wACCCcccc9999/yyy/ttt/sss/www/000/000/QQQ8CCCT27wA///A///A///A27wA27wACCCXMMM7www/444/777/000/ooo+III5BBBR27wA27wA///A///A///A27wA27wA27wAAAAFBBBbEEEsEEE1FFFqBBBZAAAD27wA27wA27wA///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A///A")
1203 bar_spectrum = decodeBarStr("AAA/AAA/AAB/AAC/AAD/BAF/CAH/DAK/EAN/GAQ/HAU/JAX/LAb/MAf/OAj/PAm/QAq/RAt/SAv/SAx/SAz/SA1/SA3/SA4/SA5/RA6/PA6/OA6/MA6/IA5/CA4/AA3/AD2/AJ1/AN0/AQy/ATw/AVu/AYr/AZo/Abl/Adj/Aeg/Agd/Ahb/AiY/AjW/AlT/AmR/AnO/AoL/AqI/AqE/ArA/AsA/AtA/AuA/AvA/AvA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/CwA/OvA/UvA/ZuA/euA/htA/lsA/orA/rqA/tpA/woA/ymA/0lA/2jA/4hA/5fA/7eA/8cA/9aA/+YA//VA//TA//QA//NA//KA//FA/+AA/+AA/8AA/7AA/6AA/5AA/3AA/2AA/0AA/yAA/wAA/uAA/sAA/qAA/oAA/lAA/jAA/hAA/fAA/dAA/bAA/ZAA/YAA/WAA/UAA/SAA/RAA/QAA/OAA/NAA/MAA/LAA/KAA/JAA/IAA/HAA/GAA/FAA/FAA/EAA/DAA/DAA/CAA/CAA/CAA/AAA/AAA/AAB/AAC/AAD/BAF/CAH/DAK/EAN/GAQ/HAU/JAX/LAb/MAf/OAj/PAm/QAq/RAt/SAv/SAx/SAz/SA1/SA3/SA4/SA5/RA6/PA6/OA6/MA6/IA5/CA4/AA3/AD2/AJ1/AN0/AQy/ATw/AVu/AYr/AZo/Abl/Adj/Aeg/Agd/Ahb/AiY/AjW/AlT/AmR/AnO/AoL/AqI/AqE/ArA/AsA/AtA/AuA/AvA/AvA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/CwA/OvA/UvA/ZuA/euA/htA/lsA/orA/rqA/tpA/woA/ymA/0lA/2jA/4hA/5fA/7eA/8cA/9aA/+YA//VA//TA//QA//NA//KA//FA/+AA/+AA/8AA/7AA/6AA/5AA/3AA/2AA/0AA/yAA/wAA/uAA/sAA/qAA/oAA/lAA/jAA/hAA/fAA/dAA/bAA/ZAA/YAA/WAA/UAA/SAA/RAA/QAA/OAA/NAA/MAA/LAA/KAA/JAA/IAA/HAA/GAA/FAA/FAA/EAA/DAA/DAA/CAA/CAA/CAA/AAA/AAA/AAB/AAC/AAD/BAF/CAH/DAK/EAN/GAQ/HAU/JAX/LAb/MAf/OAj/PAm/QAq/RAt/SAv/SAx/SAz/SA1/SA3/SA4/SA5/RA6/PA6/OA6/MA6/IA5/CA4/AA3/AD2/AJ1/AN0/AQy/ATw/AVu/AYr/AZo/Abl/Adj/Aeg/Agd/Ahb/AiY/AjW/AlT/AmR/AnO/AoL/AqI/AqE/ArA/AsA/AtA/AuA/AvA/AvA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/CwA/OvA/UvA/ZuA/euA/htA/lsA/orA/rqA/tpA/woA/ymA/0lA/2jA/4hA/5fA/7eA/8cA/9aA/+YA//VA//TA//QA//NA//KA//FA/+AA/+AA/8AA/7AA/6AA/5AA/3AA/2AA/0AA/yAA/wAA/uAA/sAA/qAA/oAA/lAA/jAA/hAA/fAA/dAA/bAA/ZAA/YAA/WAA/UAA/SAA/RAA/QAA/OAA/NAA/MAA/LAA/KAA/JAA/IAA/HAA/GAA/FAA/FAA/EAA/DAA/DAA/CAA/CAA/CAA/AAA/AAA/AAB/AAC/AAD/BAF/CAH/DAK/EAN/GAQ/HAU/JAX/LAb/MAf/OAj/PAm/QAq/RAt/SAv/SAx/SAz/SA1/SA3/SA4/SA5/RA6/PA6/OA6/MA6/IA5/CA4/AA3/AD2/AJ1/AN0/AQy/ATw/AVu/AYr/AZo/Abl/Adj/Aeg/Agd/Ahb/AiY/AjW/AlT/AmR/AnO/AoL/AqI/AqE/ArA/AsA/AtA/AuA/AvA/AvA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/CwA/OvA/UvA/ZuA/euA/htA/lsA/orA/rqA/tpA/woA/ymA/0lA/2jA/4hA/5fA/7eA/8cA/9aA/+YA//VA//TA//QA//NA//KA//FA/+AA/+AA/8AA/7AA/6AA/5AA/3AA/2AA/0AA/yAA/wAA/uAA/sAA/qAA/oAA/lAA/jAA/hAA/fAA/dAA/bAA/ZAA/YAA/WAA/UAA/SAA/RAA/QAA/OAA/NAA/MAA/LAA/KAA/JAA/IAA/HAA/GAA/FAA/FAA/EAA/DAA/DAA/CAA/CAA/CAA/AAA/AAA/AAB/AAC/AAD/BAF/CAH/DAK/EAN/GAQ/HAU/JAX/LAb/MAf/OAj/PAm/QAq/RAt/SAv/SAx/SAz/SA1/SA3/SA4/SA5/RA6/PA6/OA6/MA6/IA5/CA4/AA3/AD2/AJ1/AN0/AQy/ATw/AVu/AYr/AZo/Abl/Adj/Aeg/Agd/Ahb/AiY/AjW/AlT/AmR/AnO/AoL/AqI/AqE/ArA/AsA/AtA/AuA/AvA/AvA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/CwA/OvA/UvA/ZuA/euA/htA/lsA/orA/rqA/tpA/woA/ymA/0lA/2jA/4hA/5fA/7eA/8cA/9aA/+YA//VA//TA//QA//NA//KA//FA/+AA/+AA/8AA/7AA/6AA/5AA/3AA/2AA/0AA/yAA/wAA/uAA/sAA/qAA/oAA/lAA/jAA/hAA/fAA/dAA/bAA/ZAA/YAA/WAA/UAA/SAA/RAA/QAA/OAA/NAA/MAA/LAA/KAA/JAA/IAA/HAA/GAA/FAA/FAA/EAA/DAA/DAA/CAA/CAA/CAA/AAA/AAA/AAB/AAC/AAD/BAF/CAH/DAK/EAN/GAQ/HAU/JAX/LAb/MAf/OAj/PAm/QAq/RAt/SAv/SAx/SAz/SA1/SA3/SA4/SA5/RA6/PA6/OA6/MA6/IA5/CA4/AA3/AD2/AJ1/AN0/AQy/ATw/AVu/AYr/AZo/Abl/Adj/Aeg/Agd/Ahb/AiY/AjW/AlT/AmR/AnO/AoL/AqI/AqE/ArA/AsA/AtA/AuA/AvA/AvA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/CwA/OvA/UvA/ZuA/euA/htA/lsA/orA/rqA/tpA/woA/ymA/0lA/2jA/4hA/5fA/7eA/8cA/9aA/+YA//VA//TA//QA//NA//KA//FA/+AA/+AA/8AA/7AA/6AA/5AA/3AA/2AA/0AA/yAA/wAA/uAA/sAA/qAA/oAA/lAA/jAA/hAA/fAA/dAA/bAA/ZAA/YAA/WAA/UAA/SAA/RAA/QAA/OAA/NAA/MAA/LAA/KAA/JAA/IAA/HAA/GAA/FAA/FAA/EAA/DAA/DAA/CAA/CAA/CAA/AAA/AAA/AAB/AAC/AAD/BAF/CAH/DAK/EAN/GAQ/HAU/JAX/LAb/MAf/OAj/PAm/QAq/RAt/SAv/SAx/SAz/SA1/SA3/SA4/SA5/RA6/PA6/OA6/MA6/IA5/CA4/AA3/AD2/AJ1/AN0/AQy/ATw/AVu/AYr/AZo/Abl/Adj/Aeg/Agd/Ahb/AiY/AjW/AlT/AmR/AnO/AoL/AqI/AqE/ArA/AsA/AtA/AuA/AvA/AvA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/CwA/OvA/UvA/ZuA/euA/htA/lsA/orA/rqA/tpA/woA/ymA/0lA/2jA/4hA/5fA/7eA/8cA/9aA/+YA//VA//TA//QA//NA//KA//FA/+AA/+AA/8AA/7AA/6AA/5AA/3AA/2AA/0AA/yAA/wAA/uAA/sAA/qAA/oAA/lAA/jAA/hAA/fAA/dAA/bAA/ZAA/YAA/WAA/UAA/SAA/RAA/QAA/OAA/NAA/MAA/LAA/KAA/JAA/IAA/HAA/GAA/FAA/FAA/EAA/DAA/DAA/CAA/CAA/CAA/AAA/AAA/AAB/AAC/AAD/BAF/CAH/DAK/EAN/GAQ/HAU/JAX/LAb/MAf/OAj/PAm/QAq/RAt/SAv/SAx/SAz/SA1/SA3/SA4/SA5/RA6/PA6/OA6/MA6/IA5/CA4/AA3/AD2/AJ1/AN0/AQy/ATw/AVu/AYr/AZo/Abl/Adj/Aeg/Agd/Ahb/AiY/AjW/AlT/AmR/AnO/AoL/AqI/AqE/ArA/AsA/AtA/AuA/AvA/AvA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/CwA/OvA/UvA/ZuA/euA/htA/lsA/orA/rqA/tpA/woA/ymA/0lA/2jA/4hA/5fA/7eA/8cA/9aA/+YA//VA//TA//QA//NA//KA//FA/+AA/+AA/8AA/7AA/6AA/5AA/3AA/2AA/0AA/yAA/wAA/uAA/sAA/qAA/oAA/lAA/jAA/hAA/fAA/dAA/bAA/ZAA/YAA/WAA/UAA/SAA/RAA/QAA/OAA/NAA/MAA/LAA/KAA/JAA/IAA/HAA/GAA/FAA/FAA/EAA/DAA/DAA/CAA/CAA/CAA/AAA/AAA/AAB/AAC/AAD/BAF/CAH/DAK/EAN/GAQ/HAU/JAX/LAb/MAf/OAj/PAm/QAq/RAt/SAv/SAx/SAz/SA1/SA3/SA4/SA5/RA6/PA6/OA6/MA6/IA5/CA4/AA3/AD2/AJ1/AN0/AQy/ATw/AVu/AYr/AZo/Abl/Adj/Aeg/Agd/Ahb/AiY/AjW/AlT/AmR/AnO/AoL/AqI/AqE/ArA/AsA/AtA/AuA/AvA/AvA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/CwA/OvA/UvA/ZuA/euA/htA/lsA/orA/rqA/tpA/woA/ymA/0lA/2jA/4hA/5fA/7eA/8cA/9aA/+YA//VA//TA//QA//NA//KA//FA/+AA/+AA/8AA/7AA/6AA/5AA/3AA/2AA/0AA/yAA/wAA/uAA/sAA/qAA/oAA/lAA/jAA/hAA/fAA/dAA/bAA/ZAA/YAA/WAA/UAA/SAA/RAA/QAA/OAA/NAA/MAA/LAA/KAA/JAA/IAA/HAA/GAA/FAA/FAA/EAA/DAA/DAA/CAA/CAA/CAA/AAA4AAA/AAB/AAC/AAD/BAF/CAH/DAK/EAN/GAQ/HAU/JAX/LAb/MAf/OAj/PAm/QAq/RAt/SAv/SAx/SAz/SA1/SA3/SA4/SA5/RA6/PA6/OA6/MA6/IA5/CA4/AA3/AD2/AJ1/AN0/AQy/ATw/AVu/AYr/AZo/Abl/Adj/Aeg/Agd/Ahb/AiY/AjW/AlT/AmR/AnO/AoL/AqI/AqE/ArA/AsA/AtA/AuA/AvA/AvA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/CwA/OvA/UvA/ZuA/euA/htA/lsA/orA/rqA/tpA/woA/ymA/0lA/2jA/4hA/5fA/7eA/8cA/9aA/+YA//VA//TA//QA//NA//KA//FA/+AA/+AA/8AA/7AA/6AA/5AA/3AA/2AA/0AA/yAA/wAA/uAA/sAA/qAA/oAA/lAA/jAA/hAA/fAA/dAA/bAA/ZAA/YAA/WAA/UAA/SAA/RAA/QAA/OAA/NAA/MAA/LAA/KAA/JAA/IAA/HAA/GAA/FAA/FAA/EAA/DAA/DAA/CAA/CAA/CAA4AAAsAAA/AAB/AAC/AAD/BAF/CAH/DAK/EAN/GAQ/HAU/JAX/LAb/MAf/OAj/PAm/QAq/RAt/SAv/SAx/SAz/SA1/SA3/SA4/SA5/RA6/PA6/OA6/MA6/IA5/CA4/AA3/AD2/AJ1/AN0/AQy/ATw/AVu/AYr/AZo/Abl/Adj/Aeg/Agd/Ahb/AiY/AjW/AlT/AmR/AnO/AoL/AqI/AqE/ArA/AsA/AtA/AuA/AvA/AvA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/CwA/OvA/UvA/ZuA/euA/htA/lsA/orA/rqA/tpA/woA/ymA/0lA/2jA/4hA/5fA/7eA/8cA/9aA/+YA//VA//TA//QA//NA//KA//FA/+AA/+AA/8AA/7AA/6AA/5AA/3AA/2AA/0AA/yAA/wAA/uAA/sAA/qAA/oAA/lAA/jAA/hAA/fAA/dAA/bAA/ZAA/YAA/WAA/UAA/SAA/RAA/QAA/OAA/NAA/MAA/LAA/KAA/JAA/IAA/HAA/GAA/FAA/FAA/EAA/DAA/DAA/CAA/CAA/CAAsAAAcAAA/AAB/AAC/AAD/BAF/CAH/DAK/EAN/GAQ/HAU/JAX/LAb/MAf/OAj/PAm/QAq/RAt/SAv/SAx/SAz/SA1/SA3/SA4/SA5/RA6/PA6/OA6/MA6/IA5/CA4/AA3/AD2/AJ1/AN0/AQy/ATw/AVu/AYr/AZo/Abl/Adj/Aeg/Agd/Ahb/AiY/AjW/AlT/AmR/AnO/AoL/AqI/AqE/ArA/AsA/AtA/AuA/AvA/AvA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/CwA/OvA/UvA/ZuA/euA/htA/lsA/orA/rqA/tpA/woA/ymA/0lA/2jA/4hA/5fA/7eA/8cA/9aA/+YA//VA//TA//QA//NA//KA//FA/+AA/+AA/8AA/7AA/6AA/5AA/3AA/2AA/0AA/yAA/wAA/uAA/sAA/qAA/oAA/lAA/jAA/hAA/fAA/dAA/bAA/ZAA/YAA/WAA/UAA/SAA/RAA/QAA/OAA/NAA/MAA/LAA/KAA/JAA/IAA/HAA/GAA/FAA/FAA/EAA/DAA/DAA/CAA/CAA/CAAcAAAKAAAzAAB/AAC/AAD/BAF/CAH/DAK/EAN/GAQ/HAU/JAX/LAb/MAf/OAj/PAm/QAq/RAt/SAv/SAx/SAz/SA1/SA3/SA4/SA5/RA6/PA6/OA6/MA6/IA5/CA4/AA3/AD2/AJ1/AN0/AQy/ATw/AVu/AYr/AZo/Abl/Adj/Aeg/Agd/Ahb/AiY/AjW/AlT/AmR/AnO/AoL/AqI/AqE/ArA/AsA/AtA/AuA/AvA/AvA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/CwA/OvA/UvA/ZuA/euA/htA/lsA/orA/rqA/tpA/woA/ymA/0lA/2jA/4hA/5fA/7eA/8cA/9aA/+YA//VA//TA//QA//NA//KA//FA/+AA/+AA/8AA/7AA/6AA/5AA/3AA/2AA/0AA/yAA/wAA/uAA/sAA/qAA/oAA/lAA/jAA/hAA/fAA/dAA/bAA/ZAA/YAA/WAA/UAA/SAA/RAA/QAA/OAA/NAA/MAA/LAA/KAA/JAA/IAA/HAA/GAA/FAA/FAA/EAA/DAA/DAA/CAA/CAAzCAAK///AAAAaAAB/AAC/AAD/BAF/CAH/DAK/EAN/GAQ/HAU/JAX/LAb/MAf/OAj/PAm/QAq/RAt/SAv/SAx/SAz/SA1/SA3/SA4/SA5/RA6/PA6/OA6/MA6/IA5/CA4/AA3/AD2/AJ1/AN0/AQy/ATw/AVu/AYr/AZo/Abl/Adj/Aeg/Agd/Ahb/AiY/AjW/AlT/AmR/AnO/AoL/AqI/AqE/ArA/AsA/AtA/AuA/AvA/AvA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/CwA/OvA/UvA/ZuA/euA/htA/lsA/orA/rqA/tpA/woA/ymA/0lA/2jA/4hA/5fA/7eA/8cA/9aA/+YA//VA//TA//QA//NA//KA//FA/+AA/+AA/8AA/7AA/6AA/5AA/3AA/2AA/0AA/yAA/wAA/uAA/sAA/qAA/oAA/lAA/jAA/hAA/fAA/dAA/bAA/ZAA/YAA/WAA/UAA/SAA/RAA/QAA/OAA/NAA/MAA/LAA/KAA/JAA/IAA/HAA/GAA/FAA/FAA/EAA/DAA/DAA/CAA/CAAa///A///A///AAABfAAC/AAD/BAF/CAH/DAK/EAN/GAQ/HAU/JAX/LAb/MAf/OAj/PAm/QAq/RAt/SAv/SAx/SAz/SA1/SA3/SA4/SA5/RA6/PA6/OA6/MA6/IA5/CA4/AA3/AD2/AJ1/AN0/AQy/ATw/AVu/AYr/AZo/Abl/Adj/Aeg/Agd/Ahb/AiY/AjW/AlT/AmR/AnO/AoL/AqI/AqE/ArA/AsA/AtA/AuA/AvA/AvA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/CwA/OvA/UvA/ZuA/euA/htA/lsA/orA/rqA/tpA/woA/ymA/0lA/2jA/4hA/5fA/7eA/8cA/9aA/+YA//VA//TA//QA//NA//KA//FA/+AA/+AA/8AA/7AA/6AA/5AA/3AA/2AA/0AA/yAA/wAA/uAA/sAA/qAA/oAA/lAA/jAA/hAA/fAA/dAA/bAA/ZAA/YAA/WAA/UAA/SAA/RAA/QAA/OAA/NAA/MAA/LAA/KAA/JAA/IAA/HAA/GAA/FAA/FAA/EAA/DAA/DAA/CAAf///A///A///A///A///AAACaAADzBAF/CAH/DAK/EAN/GAQ/HAU/JAX/LAb/MAf/OAj/PAm/QAq/RAt/SAv/SAx/SAz/SA1/SA3/SA4/SA5/RA6/PA6/OA6/MA6/IA5/CA4/AA3/AD2/AJ1/AN0/AQy/ATw/AVu/AYr/AZo/Abl/Adj/Aeg/Agd/Ahb/AiY/AjW/AlT/AmR/AnO/AoL/AqI/AqE/ArA/AsA/AtA/AuA/AvA/AvA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/CwA/OvA/UvA/ZuA/euA/htA/lsA/orA/rqA/tpA/woA/ymA/0lA/2jA/4hA/5fA/7eA/8cA/9aA/+YA//VA//TA//QA//NA//KA//FA/+AA/+AA/8AA/7AA/6AA/5AA/3AA/2AA/0AA/yAA/wAA/uAA/sAA/qAA/oAA/lAA/jAA/hAA/fAA/dAA/bAA/ZAA/YAA/WAA/UAA/SAA/RAA/QAA/OAA/NAA/MAA/LAA/KAA/JAA/IAA/HAA/GAA/FAA/FAA/EAA/DAAzDAAa///A///A///A///A///A///A///AAADKBAFcCAHsDAK4EAN/GAQ/HAU/JAX/LAb/MAf/OAj/PAm/QAq/RAt/SAv/SAx/SAz/SA1/SA3/SA4/SA5/RA6/PA6/OA6/MA6/IA5/CA4/AA3/AD2/AJ1/AN0/AQy/ATw/AVu/AYr/AZo/Abl/Adj/Aeg/Agd/Ahb/AiY/AjW/AlT/AmR/AnO/AoL/AqI/AqE/ArA/AsA/AtA/AuA/AvA/AvA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/AwA/CwA/OvA/UvA/ZuA/euA/htA/lsA/orA/rqA/tpA/woA/ymA/0lA/2jA/4hA/5fA/7eA/8cA/9aA/+YA//VA//TA//QA//NA//KA//FA/+AA/+AA/8AA/7AA/6AA/5AA/3AA/2AA/0AA/yAA/wAA/uAA/sAA/qAA/oAA/lAA/jAA/hAA/fAA/dAA/bAA/ZAA/YAA/WAA/UAA/SAA/RAA/QAA/OAA/NAA/MAA/LAA/KAA/JAA/IAA/HAA/GAA/FAA4FAAsEAAcDAAK///A///A///A///A")
1205 bar_blackbody = decodeBarStr("+LA/+LA/+MA/+NA/+OA/+QA/+RA/+SA/+TA/+VA/+WA/+XA/+ZA/+aA//bA//cA//eA//fA//gA//hA//iA//kA//lA//mA//nA//oA//oB//pD//pE//qF//qG//qH//rI//rJ//sK//sM//sN//tO//tP//uQ//uR//vS//vT//vU//wW//wX//xY//xZ//xa//yb//yc//zd//ze//zg//0h//0i//1j//1k//1l//2m//2n//3p//3q//4r//4s//4t//5u//5v//6w//6y//6y//70//71//82//83//84//95//96//+7//+9///9/////////////////+///++//++//++//++//9+//9+//99//99//89//89//89//88//88//78//78//78//78//67//67//67//67//57//57//56//56//56//46//46//46//45//35//35//35//35//24//24//24//24//24//13//13//13//13//03//03//03//02//z2//z2//z2//z2//02//+LA/+LA/+MA/+NA/+OA/+QA/+RA/+SA/+TA/+VA/+WA/+XA/+ZA/QQQ//bA//cA//eA//fA//gA//hA//iA//kA//lA//mA//nA//oA//oB//pD//pE//qF//qG//qH//rI//rJ/QQQ//sM//sN//tO//tP//uQ//uR//vS//vT//vU//wW//wX//xY//xZ//xa//yb//yc//zd//ze//zg//0h//0i//1j//1k//1l//2m//2n//3p//3q//4r//4s//4t//5u//5v//6w//6y//6y//70//71//82//83//84//95//96//+7//+9///9/////////////////QQQ/++//++//++//++//9+//9+//99//99//89//89//89//88//88//78//78//78//78//67//67//67//67//57//57//56//56//56//46//46//46//45//35//35//35//35//24//24//24//24//24//13//13//13//13//03//03//03//02//z2//z2//z2//z2//02//+LA/+LA/+MA/+NA/+OA/+QA/+RA/+SA/+TA/+VA/+WA/+XA/+ZA/QQQ//bA//cA//eA//fA//gA//hA//iA//kA//lA//mA//nA//oA//oB//pD//pE//qF//qG//qH//rI//rJ/QQQ//sM//sN//tO//tP//uQ//uR//vS//vT//vU//wW//wX//xY//xZ//xa//yb//yc//zd//ze//zg//0h//0i//1j//1k//1l//2m//2n//3p//3q//4r//4s//4t//5u//5v//6w//6y//6y//70//71//82//83//84//95//96//+7//+9///9/////////////////QQQ/++//++//++//++//9+//9+//99//99//89//89//89//88//88//78//78//78//78//67//67//67//67//57//57//56//56//56//46//46//46//45//35//35//35//35//24//24//24//24//24//13//13//13//13//03//03//03//02//z2//z2//z2//z2//02//+LA/+LA/+MA/+NA/+OA/+QA/+RA/+SA/+TA/+VA/+WA/+XA/+ZA/QQQ//bA//cA//eA//fA//gA//hA//iA//kA//lA//mA//nA//oA//oB//pD//pE//qF//qG//qH//rI//rJ/QQQ//sM//sN//tO//tP//uQ//uR//vS//vT//vU//wW//wX//xY//xZ//xa//yb//yc//zd//ze//zg//0h//0i//1j//1k//1l//2m//2n//3p//3q//4r//4s//4t//5u//5v//6w//6y//6y//70//71//82//83//84//95//96//+7//+9///9/////////////////QQQ/++//++//++//++//9+//9+//99//99//89//89//89//88//88//78//78//78//78//67//67//67//67//57//57//56//56//56//46//46//46//45//35//35//35//35//24//24//24//24//24//13//13//13//13//03//03//03//02//z2//z2//z2//z2//02//+LA/+LA/+MA/+NA/+OA/+QA/+RA/+SA/+TA/+VA/+WA/+XA/+ZA/QQQ//bA//cA//eA//fA//gA//hA//iA//kA//lA//mA//nA//oA//oB//pD//pE//qF//qG//qH//rI//rJ/QQQ//sM//sN//tO//tP//uQ//uR//vS//vT//vU//wW//wX//xY//xZ//xa//yb//yc//zd//ze//zg//0h//0i//1j//1k//1l//2m//2n//3p//3q//4r//4s//4t//5u//5v//6w//6y//6y//70//71//82//83//84//95//96//+7//+9///9/////////////////QQQ/++//++//++//++//9+//9+//99//99//89//89//89//88//88//78//78//78//78//67//67//67//67//57//57//56//56//56//46//46//46//45//35//35//35//35//24//24//24//24//24//13//13//13//13//03//03//03//02//z2//z2//z2//z2//02//+LA/+LA/+MA/+NA/+OA/+QA/+RA/+SA/+TA/+VA/+WA/+XA/+ZA/+aA//bA//cA//eA//fA//gA//hA//iA//kA//lA//mA//nA//oA//oB//pD//pE//qF//qG//qH//rI//rJ//sK//sM//sN//tO//tP//uQ//uR//vS//vT//vU//wW//wX//xY//xZ//xa//yb//yc//zd//ze//zg//0h//0i//1j//1k//1l//2m//2n//3p//3q//4r//4s//4t//5u//5v//6w//6y//6y//70//71//82//83//84//95//96//+7//+9///9/////////////////+///++//++//++//++//9+//9+//99//99//89//89//89//88//88//78//78//78//78//67//67//67//67//57//57//56//56//56//46//46//46//45//35//35//35//35//24//24//24//24//24//13//13//13//13//03//03//03//02//z2//z2//z2//z2//02//+LA/+LA/+MA/+NA/+OA/+QA/+RA/+SA/+TA/+VA/+WA/+XA/+ZA/QQQ/QQQ/QQQ//eA//fA//gA//hA//iA//kA//lA//mA//nA//oA//oB//pD//pE//qF//qG//qH//rI//rJ/QQQ//sM//sN//tO//tP//uQ//uR//vS//vT//vU//wW//wX//xY//xZ//xa//yb//yc//zd//ze//zg//0h//0i//1j//1k//1l//2m//2n//3p//3q//4r//4s//4t//5u//5v//6w//6y//6y//70//71//82//83//84//95//96//+7//+9///9/////////////////QQQ/QQQ/QQQ/++//++//9+//9+//99//99//89//89//89//88//88//78//78//78//78//67//67//67//67//57//57//56//56//56//46//46//46//45//35//35//35//35//24//24//24//24//24//13//13//13//13//03//03//03//02//z2//z2//z2//z2//02//+LA/+LA/+MA/+NA/+OA/+QA/+RA/+SA/+TA/+VA/+WA/+XA/+ZA/QQQ//bA//cA//eA//fA//gA//hA//iA//kA//lA//mA//nA//oA//oB//pD//pE//qF//qG//qH//rI//rJ/QQQ//sM//sN//tO//tP//uQ//uR//vS//vT//vU//wW//wX//xY//xZ//xa//yb//yc//zd//ze//zg//0h//0i//1j//1k//1l//2m//2n//3p//3q//4r//4s//4t//5u//5v//6w//6y//6y//70//71//82//83//84//95//96//+7//+9///9/////////////////QQQ/++//QQQ/++//++//9+//9+//99//99//89//89//89//88//88//78//78//78//78//67//67//67//67//57//57//56//56//56//46//46//46//45//35//35//35//35//24//24//24//24//24//13//13//13//13//03//03//03//02//z2//z2//z2//z2//02//+LA/+LA/+MA/+NA/+OA/+QA/+RA/+SA/+TA/+VA/+WA/+XA/+ZA/QQQ//bA//cA//eA//fA//gA//hA//iA//kA//lA//mA//nA//oA//oB//pD//pE//qF//qG//qH//rI//rJ/QQQ//sM//sN//tO//tP//uQ//uR//vS//vT//vU//wW//wX//xY//xZ//xa//yb//yc//zd//ze//zg//0h//0i//1j//1k//1l//2m//2n//3p//3q//4r//4s//4t//5u//5v//6w//6y//6y//70//71//82//83//84//95//96//+7//+9///9/////////////////QQQ/++//QQQ/++//++//9+//9+//99//99//89//89//89//88//88//78//78//78//78//67//67//67//67//57//57//56//56//56//46//46//46//45//35//35//35//35//24//24//24//24//24//13//13//13//13//03//03//03//02//z2//z2//z2//z2//02//+LA4+LA/+MA/+NA/+OA/+QA/+RA/+SA/+TA/+VA/+WA/+XA/+ZA/+aA/QQQ/QQQ//eA//fA//gA//hA//iA//kA//lA//mA//nA//oA//oB//pD//pE//qF//qG//qH//rI//rJ/QQQ//sM//sN//tO//tP//uQ//uR//vS//vT//vU//wW//wX//xY//xZ//xa//yb//yc//zd//ze//zg//0h//0i//1j//1k//1l//2m//2n//3p//3q//4r//4s//4t//5u//5v//6w//6y//6y//70//71//82//83//84//95//96//+7//+9///9/////////////////QQQ/QQQ/++//++//++//9+//9+//99//99//89//89//89//88//88//78//78//78//78//67//67//67//67//57//57//56//56//56//46//46//46//45//35//35//35//35//24//24//24//24//24//13//13//13//13//03//03//03//02//z2//z2//z2//z2//02//+LAs+LA/+MA/+NA/+OA/+QA/+RA/+SA/+TA/+VA/+WA/+XA/+ZA/+aA//bA//cA//eA//fA//gA//hA//iA//kA//lA//mA//nA//oA//oB//pD//pE//qF//qG//qH//rI//rJ//sK//sM//sN//tO//tP//uQ//uR//vS//vT//vU//wW//wX//xY//xZ//xa//yb//yc//zd//ze//zg//0h//0i//1j//1k//1l//2m//2n//3p//3q//4r//4s//4t//5u//5v//6w//6y//6y//70//71//82//83//84//95//96//+7//+9///9/////////////////+///++//++//++//++//9+//9+//99//99//89//89//89//88//88//78//78//78//78//67//67//67//67//57//57//56//56//56//46//46//46//45//35//35//35//35//24//24//24//24//24//13//13//13//13//03//03//03//02//z2//z2//z2//z2//02//+LAc+LA/+MA/+NA/+OA/+QA/+RA/+SA/+TA/+VA/+WA/+XA/+ZA/+aA//bA//cA//eA//fA//gA//hA//iA//kA//lA//mA//nA//oA//oB//pD//pE//qF//qG//qH//rI//rJ//sK//sM//sN//tO//tP//uQ//uR//vS//vT//vU//wW//wX//xY//xZ//xa//yb//yc//zd//ze//zg//0h//0i//1j//1k//1l//2m//2n//3p//3q//4r//4s//4t//5u//5v//6w//6y//6y//70//71//82//83//84//95//96//+7//+9///9/////////////////+///++//++//++//++//9+//9+//99//99//89//89//89//88//88//78//78//78//78//67//67//67//67//57//57//56//56//56//46//46//46//45//35//35//35//35//24//24//24//24//24//13//13//13//13//03//03//03//02//z2//z2//z2//z2//02//+LAK+LAz+MA/+NA/+OA/+QA/+RA/+SA/+TA/+VA/+WA/+XA/+ZA/+aA//bA//cA//eA//fA//gA//hA//iA//kA//lA//mA//nA//oA//oB//pD//pE//qF//qG//qH//rI//rJ//sK//sM//sN//tO//tP//uQ//uR//vS//vT//vU//wW//wX//xY//xZ//xa//yb//yc//zd//ze//zg//0h//0i//1j//1k//1l//2m//2n//3p//3q//4r//4s//4t//5u//5v//6w//6y//6y//70//71//82//83//84//95//96//+7//+9///9/////////////////+///++//++//++//++//9+//9+//99//99//89//89//89//88//88//78//78//78//78//67//67//67//67//57//57//56//56//56//46//46//46//45//35//35//35//35//24//24//24//24//24//13//13//13//13//03//03//03//02//z2//z2//z2//z2//02//+LAA+LAa+MA/+NA/+OA/+QA/+RA/+SA/+TA/+VA/+WA/+XA/+ZA/+aA//bA//cA//eA//fA//gA//hA//iA//kA//lA//mA//nA//oA//oB//pD//pE//qF//qG//qH//rI//rJ//sK//sM//sN//tO//tP//uQ//uR//vS//vT//vU//wW//wX//xY//xZ//xa//yb//yc//zd//ze//zg//0h//0i//1j//1k//1l//2m//2n//3p//3q//4r//4s//4t//5u//5v//6w//6y//6y//70//71//82//83//84//95//96//+7//+9///9/////////////////+///++//++//++//++//9+//9+//99//99//89//89//89//88//88//78//78//78//78//67//67//67//67//57//57//56//56//56//46//46//46//45//35//35//35//35//24//24//24//24//24//13//13//13//13//03//03//03//02//z2//z2//z2//z2//02//+LAA+LAA+MAf+NA/+OA/+QA/+RA/+SA/+TA/+VA/+WA/+XA/+ZA/+aA//bA//cA//eA//fA//gA//hA//iA//kA//lA//mA//nA//oA//oB//pD//pE//qF//qG//qH//rI//rJ//sK//sM//sN//tO//tP//uQ//uR//vS//vT//vU//wW//wX//xY//xZ//xa//yb//yc//zd//ze//zg//0h//0i//1j//1k//1l//2m//2n//3p//3q//4r//4s//4t//5u//5v//6w//6y//6y//70//71//82//83//84//95//96//+7//+9///9/////////////////+///++//++//++//++//9+//9+//99//99//89//89//89//88//88//78//78//78//78//67//67//67//67//57//57//56//56//56//46//46//46//45//35//35//35//35//24//24//24//24//24//13//13//13//13//03//03//03//02//z2//z2//z2//z2//02//+LAA+LAA+MAA+NAa+OAz+QA/+RA/+SA/+TA/+VA/+WA/+XA/+ZA/+aA//bA//cA//eA//fA//gA//hA//iA//kA//lA//mA//nA//oA//oB//pD//pE//qF//qG//qH//rI//rJ//sK//sM//sN//tO//tP//uQ//uR//vS//vT//vU//wW//wX//xY//xZ//xa//yb//yc//zd//ze//zg//0h//0i//1j//1k//1l//2m//2n//3p//3q//4r//4s//4t//5u//5v//6w//6y//6y//70//71//82//83//84//95//96//+7//+9///9/////////////////+///++//++//++//++//9+//9+//99//99//89//89//89//88//88//78//78//78//78//67//67//67//67//57//57//56//56//56//46//46//46//45//35//35//35//35//24//24//24//24//24//13//13//13//13//03//03//03//02//z2//z2//z2//z2//02//+LAA+LAA+MAA+NAA+OAK+QAc+RAs+SA4+TA/+VA/+WA/+XA/+ZA/+aA//bA//cA//eA//fA//gA//hA//iA//kA//lA//mA//nA//oA//oB//pD//pE//qF//qG//qH//rI//rJ//sK//sM//sN//tO//tP//uQ//uR//vS//vT//vU//wW//wX//xY//xZ//xa//yb//yc//zd//ze//zg//0h//0i//1j//1k//1l//2m//2n//3p//3q//4r//4s//4t//5u//5v//6w//6y//6y//70//71//82//83//84//95//96//+7//+9///9/////////////////+///++//++//++//++//9+//9+//99//99//89//89//89//88//88//78//78//78//78//67//67//67//67//57//57//56//56//56//46//46//46//45//35//35//35//35//24//24//24//24//24//13//13//13//13//03//03//03//02//z2//z2//z2//z2//02//")
1207 bar_equalenergy = decodeBarStr("AAA/AAA/AAA/AAA/BBB/BBB/BBB/BBB/CCC/CCC/CDC/DDD/DDD/DDD/EEE/EEE/EFF/FFF/FFF/GGG/GGG/HGG/HHH/HHH/III/III/JJJ/JJJ/KJK/KKK/KKK/LLL/LLL/MMM/MMM/NNN/NNN/OOO/OOO/PPP/PPP/QQQ/QQQ/RRR/RRR/SSS/TSS/TTT/UUU/UUU/VVV/VVV/WWW/WWW/XXX/XXY/YYY/ZZZ/ZZZ/aaa/aaa/bbb/cbb/ccc/ddd/ddd/eee/eee/fff/ffg/ggg/hhh/hhh/iii/iii/jjj/kkk/kkk/lll/lll/mmm/mnm/nnn/ono/ooo/ppp/ppp/qqq/qqq/rrr/rrr/sss/sss/ttt/utu/uuu/vvv/vvv/www/www/xxx/xxx/yyy/yyy/zzz/zzz/000/000/111/111/122/222/222/333/333/444/444/545/555/555/666/666/667/777/777/788/888/888/999/999/999/9++/+++/+++/+++/////////////AAA/AAA/AAA/AAA/BBB/BBB/BBB/BBB/CCC/CCC/CCC/DDD/DDD/DDD/EEE/EEE/EEF/FFF/FFF/GGG/GGG/GGH/HHH/HHH/III/III/JJJ/JJJ/KJJ/KKK/KKK/LLL/LLL/MMM/MMM/NNN/NNN/OOO/OOO/PPP/PPP/QQQ/QQQ/RRR/RSR/SSS/TTT/TTT/UUU/UUU/VVV/VVV/WWW/WWW/XXX/YXX/YYY/ZZZ/ZZZ/aaa/aaa/bbb/cbb/ccc/ddd/ddd/eee/eee/fff/ffg/ggg/hhh/hhh/iii/iii/jjj/kkj/kkk/lll/lll/mmm/mmn/nnn/ono/ooo/ppp/ppp/qqq/qqq/rrr/rrr/sss/stt/ttt/tuu/uuu/vvv/vvv/www/www/xxx/xxx/yyy/yyy/zzz/zzz/000/000/111/111/111/222/222/333/333/444/444/554/555/555/666/666/766/777/777/777/888/888/999/999/999/9++/+++/+++/+++/////////////AAA/AAA/AAA/AAA/BBB/BBB/BBB/BCC/CCC/CCC/DCC/DDD/DDD/DDD/EEE/EEE/FEF/FFF/FFF/GGG/GGG/GGG/HHH/HHH/III/III/JJJ/JJJ/KJJ/KKK/KLK/LLL/LLL/MMM/MMM/NNN/NNN/OOO/OOO/PPP/PPP/QQQ/RQQ/RRR/SRR/SSS/STT/TTT/UTU/UUU/VVV/VVV/WWW/WWW/XXX/XXX/YYY/ZZZ/ZZZ/aaa/aaa/bbb/cbb/ccc/ddd/ddd/eee/eee/fff/ggg/ggg/hhh/hhh/iii/iii/jjj/jjk/kkk/lll/lll/mmm/mmm/nnn/ooo/ooo/ppp/ppp/qqq/qqq/rrr/rrr/sss/tst/ttt/utt/uuu/vvv/vvv/www/www/xxx/xxx/yyy/yyy/zzz/zzz/000/000/111/111/122/222/222/333/333/444/444/555/555/555/666/666/667/777/777/888/888/888/999/999/999/++9/+++/+++/+++/////////////AAA/AAA/AAA/AAA/BBB/BBB/BBB/BBB/CCC/CCC/CCC/DDD/DDD/DDD/EEE/EEE/FEE/FFF/FFF/GGG/GGG/HGG/HHH/HHH/III/III/JJJ/JJJ/JKJ/KKK/KKK/LLL/LLL/MMM/MMM/NNN/NNN/OOO/OOO/PPP/PPP/QQQ/QRQ/RRR/RRS/SSS/TST/TTT/UUU/UUU/VVV/VVV/WWW/WWW/XXX/XYY/YYY/ZZZ/ZZZ/aaa/aaa/bbb/bcc/ccc/ddd/ddd/eee/eee/fff/gfg/ggg/hhh/hhh/iii/iii/jjj/jjk/kkk/lll/lll/mmm/mmm/nnn/onn/ooo/ppp/ppp/qqq/qqq/rrr/rrr/sss/tst/ttt/uuu/uuu/vvv/vvv/www/www/xxx/xxx/yyy/yyy/zzz/zzz/000/000/111/111/211/222/222/333/333/444/444/455/555/555/666/666/776/777/777/887/888/888/899/999/999/999/+++/+++/+++/////////////AAA/AAA/AAA/AAA/BBB/BBB/BBB/CBC/CCC/CCC/CCC/DDD/DDD/DDD/EEE/EEE/EEF/FFF/FFF/GGG/GGG/HHG/HHH/HHH/III/III/JJJ/JJJ/KKJ/KKK/KKK/LLL/LLL/MMM/MMM/NNN/NNN/OOO/OOO/PPP/PPP/QQQ/QQR/RRR/RRR/SSS/STT/TTT/UUU/UUU/VVV/VVV/WWW/WWW/XXX/XXX/YYY/ZZZ/ZZZ/aaa/aaa/bbb/bcb/ccc/ddd/ddd/eee/eee/fff/gff/ggg/hhh/hhh/iii/iii/jjj/jkk/kkk/lll/lll/mmm/mmm/nnn/noo/ooo/ppp/ppp/qqq/qqq/rrr/rrr/sss/sss/ttt/uuu/uuu/vvv/vvv/www/www/xxx/xxx/yyy/yyy/zzz/zzz/000/000/111/111/211/222/322/333/333/444/444/554/555/555/666/666/766/777/777/878/888/888/999/999/999/+9+/+++/+++/+++/////////////AAA/AAA/AAA/AAA/BBB/BBB/BBB/BBB/CCC/CCC/CCC/DDD/DDD/DDD/EEE/EEE/EEF/FFF/FFF/GGG/GGG/GGH/HHH/HHH/III/III/JJJ/JJJ/KJJ/KKK/KKK/LLL/LLL/MMM/MMM/NNN/NNN/OOO/OOO/PPP/PPP/QQQ/QQQ/RRR/RSR/SSS/TTT/TTT/UUU/UUU/VVV/VVV/WWW/WWW/XXX/YXX/YYY/ZZZ/ZZZ/aaa/aaa/bbb/cbb/ccc/ddd/ddd/eee/eee/fff/ffg/ggg/hhh/hhh/iii/iii/jjj/kkj/kkk/lll/lll/mmm/mmn/nnn/ono/ooo/ppp/ppp/qqq/qqq/rrr/rrr/sss/stt/ttt/tuu/uuu/vvv/vvv/www/www/xxx/xxx/yyy/yyy/zzz/zzz/000/000/111/111/111/222/222/333/333/444/444/554/555/555/666/666/766/777/777/777/888/888/999/999/999/9++/+++/+++/+++/////////////AAA/AAA/AAA/AAA/BBB/BBB/BBB/BCC/CCC/CCC/DCC/DDD/DDD/DDD/EEE/EEE/FEF/FFF/FFF/GGG/GGG/GGG/HHH/HHH/III/III/JJJ/JJJ/KJJ/KKK/KLK/LLL/LLL/MMM/MMM/NNN/NNN/OOO/OOO/PPP/PPP/QQQ/RQQ/RRR/SRR/SSS/STT/TTT/UTU/UUU/VVV/VVV/WWW/WWW/XXX/XXX/YYY/ZZZ/ZZZ/aaa/aaa/bbb/cbb/ccc/ddd/ddd/eee/eee/fff/ggg/ggg/hhh/hhh/iii/iii/jjj/jjk/kkk/lll/lll/mmm/mmm/nnn/ooo/ooo/ppp/ppp/qqq/qqq/rrr/rrr/sss/tst/ttt/utt/uuu/vvv/vvv/www/www/xxx/xxx/yyy/yyy/zzz/zzz/000/000/111/111/122/222/222/333/333/444/444/555/555/555/666/666/667/777/777/888/888/888/999/999/999/++9/+++/+++/+++/////////////AAA/AAA/AAA/AAA/BBB/BBB/BBB/BBB/CCC/CCC/CCC/DDD/DDD/DDD/EEE/EEE/FEE/FFF/FFF/GGG/GGG/HGG/HHH/HHH/III/III/JJJ/JJJ/JKJ/KKK/KKK/LLL/LLL/MMM/MMM/NNN/NNN/OOO/OOO/PPP/PPP/QQQ/QRQ/RRR/RRS/SSS/TST/TTT/UUU/UUU/VVV/VVV/WWW/WWW/XXX/XYY/YYY/ZZZ/ZZZ/aaa/aaa/bbb/bcc/ccc/ddd/ddd/eee/eee/fff/gfg/ggg/hhh/hhh/iii/iii/jjj/jjk/kkk/lll/lll/mmm/mmm/nnn/onn/ooo/ppp/ppp/qqq/qqq/rrr/rrr/sss/tst/ttt/uuu/uuu/vvv/vvv/www/www/xxx/xxx/yyy/yyy/zzz/zzz/000/000/111/111/211/222/222/333/333/444/444/455/555/555/666/666/776/777/777/887/888/888/899/999/999/999/+++/+++/+++/////////////AAA/AAA/AAA/AAA/BBB/BBB/BBB/CBC/CCC/CCC/CCC/DDD/DDD/DDD/EEE/EEE/EEF/FFF/FFF/GGG/GGG/HHG/HHH/HHH/III/III/JJJ/JJJ/KKJ/KKK/KKK/LLL/LLL/MMM/MMM/NNN/NNN/OOO/OOO/PPP/PPP/QQQ/QQR/RRR/RRR/SSS/STT/TTT/UUU/UUU/VVV/VVV/WWW/WWW/XXX/XXX/YYY/ZZZ/ZZZ/aaa/aaa/bbb/bcb/ccc/ddd/ddd/eee/eee/fff/gff/ggg/hhh/hhh/iii/iii/jjj/jkk/kkk/lll/lll/mmm/mmm/nnn/noo/ooo/ppp/ppp/qqq/qqq/rrr/rrr/sss/sss/ttt/uuu/uuu/vvv/vvv/www/www/xxx/xxx/yyy/yyy/zzz/zzz/000/000/111/111/211/222/322/333/333/444/444/554/555/555/666/666/766/777/777/878/888/888/999/999/999/+9+/+++/+++/+++/////////////GBA+AAA/AAA/AAA/BBB/BBB/BBB/BBB/CCC/CCC/CCC/DDD/DDD/DDD/EEE/EEE/EEF/FFF/FFF/GGG/GGG/GGH/HHH/HHH/III/III/JJJ/JJJ/KJJ/KKK/KKK/LLL/LLL/MMM/MMM/NNN/NNN/OOO/OOO/PPP/PPP/QQQ/QQQ/RRR/RSR/SSS/TTT/TTT/UUU/UUU/VVV/VVV/WWW/WWW/XXX/YXX/YYY/ZZZ/ZZZ/aaa/aaa/bbb/cbb/ccc/ddd/ddd/eee/eee/fff/ffg/ggg/hhh/hhh/iii/iii/jjj/kkj/kkk/lll/lll/mmm/mmn/nnn/ono/ooo/ppp/ppp/qqq/qqq/rrr/rrr/sss/stt/ttt/tuu/uuu/vvv/vvv/www/www/xxx/xxx/yyy/yyy/zzz/zzz/000/000/111/111/111/222/222/333/333/444/444/554/555/555/666/666/766/777/777/777/888/888/999/999/999/9++/+++/+++/+++/////////++/+OCA5AAA/AAA/AAA/BBB/BBB/BBB/BCC/CCC/CCC/DCC/DDD/DDD/DDD/EEE/EEE/FEF/FFF/FFF/GGG/GGG/GGG/HHH/HHH/III/III/JJJ/JJJ/KJJ/KKK/KLK/LLL/LLL/MMM/MMM/NNN/NNN/OOO/OOO/PPP/PPP/QQQ/RQQ/RRR/SRR/SSS/STT/TTT/UTU/UUU/VVV/VVV/WWW/WWW/XXX/XXX/YYY/ZZZ/ZZZ/aaa/aaa/bbb/cbb/ccc/ddd/ddd/eee/eee/fff/ggg/ggg/hhh/hhh/iii/iii/jjj/jjk/kkk/lll/lll/mmm/mmm/nnn/ooo/ooo/ppp/ppp/qqq/qqq/rrr/rrr/sss/tst/ttt/utt/uuu/vvv/vvv/www/www/xxx/xxx/yyy/yyy/zzz/zzz/000/000/111/111/122/222/222/333/333/444/444/555/555/555/666/666/667/777/777/888/888/888/999/999/999/++9/+++/+++/+++/////////89/5WEAsAAA/AAA/AAA/BBB/BBB/BBB/BBB/CCC/CCC/CCC/DDD/DDD/DDD/EEE/EEE/FEE/FFF/FFF/GGG/GGG/HGG/HHH/HHH/III/III/JJJ/JJJ/JKJ/KKK/KKK/LLL/LLL/MMM/MMM/NNN/NNN/OOO/OOO/PPP/PPP/QQQ/QRQ/RRR/RRS/SSS/TST/TTT/UUU/UUU/VVV/VVV/WWW/WWW/XXX/XYY/YYY/ZZZ/ZZZ/aaa/aaa/bbb/bcc/ccc/ddd/ddd/eee/eee/fff/gfg/ggg/hhh/hhh/iii/iii/jjj/jjk/kkk/lll/lll/mmm/mmm/nnn/onn/ooo/ppp/ppp/qqq/qqq/rrr/rrr/sss/tst/ttt/uuu/uuu/vvv/vvv/www/www/xxx/xxx/yyy/yyy/zzz/zzz/000/000/111/111/211/222/222/333/333/444/444/455/555/555/666/666/776/777/777/887/888/888/899/999/999/999/+++/+++/+++/////////78/scFASKCA9AAA/AAA/BBB/BBB/BBB/CBC/CCC/CCC/CCC/DDD/DDD/DDD/EEE/EEE/EEF/FFF/FFF/GGG/GGG/HHG/HHH/HHH/III/III/JJJ/JJJ/KKJ/KKK/KKK/LLL/LLL/MMM/MMM/NNN/NNN/OOO/OOO/PPP/PPP/QQQ/QQR/RRR/RRR/SSS/STT/TTT/UUU/UUU/VVV/VVV/WWW/WWW/XXX/XXX/YYY/ZZZ/ZZZ/aaa/aaa/bbb/bcb/ccc/ddd/ddd/eee/eee/fff/gff/ggg/hhh/hhh/iii/iii/jjj/jkk/kkk/lll/lll/mmm/mmm/nnn/noo/ooo/ppp/ppp/qqq/qqq/rrr/rrr/sss/sss/ttt/uuu/uuu/vvv/vvv/www/www/xxx/xxx/yyy/yyy/zzz/zzz/000/000/111/111/211/222/322/333/333/444/444/554/555/555/666/666/766/777/777/878/888/888/999/999/999/+9+/+++/+++/+++/////99/967/S///AXEApBAA/AAA/BBB/BBB/BBB/BBB/CCC/CCC/CCC/DDD/DDD/DDD/EEE/EEE/EEF/FFF/FFF/GGG/GGG/GGH/HHH/HHH/III/III/JJJ/JJJ/KJJ/KKK/KKK/LLL/LLL/MMM/MMM/NNN/NNN/OOO/OOO/PPP/PPP/QQQ/QQQ/RRR/RSR/SSS/TTT/TTT/UUU/UUU/VVV/VVV/WWW/WWW/XXX/YXX/YYY/ZZZ/ZZZ/aaa/aaa/bbb/cbb/ccc/ddd/ddd/eee/eee/fff/ffg/ggg/hhh/hhh/iii/iii/jjj/kkj/kkk/lll/lll/mmm/mmn/nnn/ono/ooo/ppp/ppp/qqq/qqq/rrr/rrr/sss/stt/ttt/tuu/uuu/vvv/vvv/www/www/xxx/xxx/yyy/yyy/zzz/zzz/000/000/111/111/111/222/222/333/333/444/444/554/555/555/666/666/766/777/777/777/888/888/999/999/999/9++/+++/+++/+++/////67/p///A///A///AVEAvBAA/BBB/BBB/BBB/BCC/CCC/CCC/DCC/DDD/DDD/DDD/EEE/EEE/FEF/FFF/FFF/GGG/GGG/GGG/HHH/HHH/III/III/JJJ/JJJ/KJJ/KKK/KLK/LLL/LLL/MMM/MMM/NNN/NNN/OOO/OOO/PPP/PPP/QQQ/RQQ/RRR/SRR/SSS/STT/TTT/UTU/UUU/VVV/VVV/WWW/WWW/XXX/XXX/YYY/ZZZ/ZZZ/aaa/aaa/bbb/cbb/ccc/ddd/ddd/eee/eee/fff/ggg/ggg/hhh/hhh/iii/iii/jjj/jjk/kkk/lll/lll/mmm/mmm/nnn/ooo/ooo/ppp/ppp/qqq/qqq/rrr/rrr/sss/tst/ttt/utt/uuu/vvv/vvv/www/www/xxx/xxx/yyy/yyy/zzz/zzz/000/000/111/111/122/222/222/333/333/444/444/555/555/555/666/666/667/777/777/888/888/888/999/999/999/++9/+++/+++/+++/78/v///A///A///A///A///AXFApKDA9BBB/BBB/BBB/CCC/CCC/CCC/DDD/DDD/DDD/EEE/EEE/FEE/FFF/FFF/GGG/GGG/HGG/HHH/HHH/III/III/JJJ/JJJ/JKJ/KKK/KKK/LLL/LLL/MMM/MMM/NNN/NNN/OOO/OOO/PPP/PPP/QQQ/QRQ/RRR/RRS/SSS/TST/TTT/UUU/UUU/VVV/VVV/WWW/WWW/XXX/XYY/YYY/ZZZ/ZZZ/aaa/aaa/bbb/bcc/ccc/ddd/ddd/eee/eee/fff/gfg/ggg/hhh/hhh/iii/iii/jjj/jjk/kkk/lll/lll/mmm/mmm/nnn/onn/ooo/ppp/ppp/qqq/qqq/rrr/rrr/sss/tst/ttt/uuu/uuu/vvv/vvv/www/www/xxx/xxx/yyy/yyy/zzz/zzz/000/000/111/111/211/222/222/333/333/444/444/455/555/555/666/666/776/777/777/887/888/888/899/999/999/999/+++/89+967/p///A///A///A///A///A///A///AdHASXGAsQFB5IDB+CCC/CCC/CCC/DDD/DDD/DDD/EEE/EEE/EEF/FFF/FFF/GGG/GGG/HHG/HHH/HHH/III/III/JJJ/JJJ/KKJ/KKK/KKK/LLL/LLL/MMM/MMM/NNN/NNN/OOO/OOO/PPP/PPP/QQQ/QQR/RRR/RRR/SSS/STT/TTT/UUU/UUU/VVV/VVV/WWW/WWW/XXX/XXX/YYY/ZZZ/ZZZ/aaa/aaa/bbb/bcb/ccc/ddd/ddd/eee/eee/fff/gff/ggg/hhh/hhh/iii/iii/jjj/jkk/kkk/lll/lll/mmm/mmm/nnn/noo/ooo/ppp/ppp/qqq/qqq/rrr/rrr/sss/sss/ttt/uuu/uuu/vvv/vvv/www/www/xxx/xxx/yyy/yyy/zzz/zzz/000/000/111/111/211/222/322/333/333/444/444/554/555/555/666/666/766/777/777/878/888/888/999/999/88++78+567+s56/S///A///A///A///A")
1209 def drawIcon(icon, x, y):
1210 BGL.glEnable(BGL.GL_BLEND)
1211 BGL.glBlendFunc(BGL.GL_SRC_ALPHA, BGL.GL_ONE_MINUS_SRC_ALPHA)
1212 BGL.glRasterPos2f(int(x)+0.5, int(y)+0.5)
1213 BGL.glDrawPixels(16, 16, BGL.GL_RGBA, BGL.GL_UNSIGNED_BYTE, icon)
1214 BGL.glDisable(BGL.GL_BLEND)
1216 def drawArrow(icon, x, y):
1217 BGL.glEnable(BGL.GL_BLEND)
1218 BGL.glBlendFunc(BGL.GL_SRC_ALPHA, BGL.GL_ONE_MINUS_SRC_ALPHA)
1219 BGL.glRasterPos2f(int(x)+0.5, int(y)+0.5)
1220 BGL.glDrawPixels(22, 22, BGL.GL_RGBA, BGL.GL_UNSIGNED_BYTE, icon)
1221 BGL.glDisable(BGL.GL_BLEND)
1223 def drawLogo(icon, x, y):
1224 BGL.glEnable(BGL.GL_BLEND)
1225 BGL.glBlendFunc(BGL.GL_SRC_ALPHA, BGL.GL_ONE_MINUS_SRC_ALPHA)
1226 BGL.glRasterPos2f(int(x)+0.5, int(y)+0.5)
1227 BGL.glDrawPixels(118, 18, BGL.GL_RGBA, BGL.GL_UNSIGNED_BYTE, icon)
1228 BGL.glDisable(BGL.GL_BLEND)
1230 def drawBar(icon, x, y):
1231 BGL.glEnable(BGL.GL_BLEND)
1232 BGL.glBlendFunc(BGL.GL_SRC_ALPHA, BGL.GL_ONE_MINUS_SRC_ALPHA)
1233 BGL.glRasterPos2f(int(x)+0.5, int(y)+0.5)
1234 BGL.glDrawPixels(138, 17, BGL.GL_RGBA, BGL.GL_UNSIGNED_BYTE, icon)
1235 BGL.glDisable(BGL.GL_BLEND)
1239 #-------------------------------------------------
1241 # helper class to handle images and icons for the GUI
1242 #-------------------------------------------------
1245 def resize(self, width, height):
1247 self.height = height
1248 self.buf = BGL.Buffer(BGL.GL_BYTE, [width,height,4]) # GL buffer
1249 def __init__(self, width=0, height=0):
1250 self.resize(width, height)
1251 def draw(self, x, y):
1252 BGL.glEnable(BGL.GL_BLEND)
1253 BGL.glBlendFunc(BGL.GL_SRC_ALPHA, BGL.GL_ONE_MINUS_SRC_ALPHA)
1254 BGL.glRasterPos2f(int(x)+0.5, int(y)+0.5)
1255 BGL.glDrawPixels(self.width, self.height, BGL.GL_RGBA, BGL.GL_UNSIGNED_BYTE, self.buf)
1256 BGL.glDisable(BGL.GL_BLEND)
1257 def decodeStr(self, width, height, s):
1258 self.resize(width, height)
1260 for y in range(self.height):
1261 for x in range(self.width):
1263 self.buf[y][x][c] = int(base64value(s[offset])*4.048)
1266 def decodeLuxConsole(self, width, height, data):
1267 self.resize(width, height)
1269 for y in range(self.height-1,-1,-1):
1270 for x in range(self.width):
1272 self.buf[y][x][c] = ord(data[offset])
1274 self.buf[y][x][3] = 255
1277 previewCache = {} # dictionary that will hold all preview images
1280 ######################################################
1282 ######################################################
1288 evtDeletePreset = 97
1289 evtSaveMaterial = 96
1290 evtLoadMaterial = 95
1291 evtDeleteMaterial = 94
1292 evtConvertMaterial = 92
1293 evtSaveMaterial2 = 91
1294 evtLoadMaterial2 = 90
1298 defaultsExclude = ['preset','filename','page','link']
1300 luxdefaults = Blender.Registry.GetKey('luxblend', True)
1301 if not(type(luxdefaults) is DictType):
1305 newluxdefaults = luxdefaults.copy()
1308 def saveluxdefaults():
1309 try: del newluxdefaults['page']
1311 try: Blender.Registry.SetKey('luxblend', newluxdefaults, True)
1318 # *** PRESETS **************************************
1319 presetsExclude = ['preset','lux','datadir','threads','filename','page','RGC','film.gamma','colorclamp','link']
1320 def getPresets(key):
1321 presets = Blender.Registry.GetKey(key, True)
1322 if not(type(presets) is DictType):
1325 def getScenePresets():
1326 presets = getPresets('luxblend_presets').copy()
1328 # radiance's hardcoded render presets:
1330 presets['0 Preview - Direct Lighting'] = {
1331 'film.displayinterval': 4,
1333 'useparamkeys': 'false',
1334 'sampler.showadvanced': 'false',
1335 'sintegrator.showadvanced': 'false',
1336 'pixelfilter.showadvanced': 'false',
1338 'sampler.type': 'lowdiscrepancy',
1339 'sampler.lowdisc.pixelsamples': 1,
1340 'sampler.lowdisc.pixelsampler': 'lowdiscrepancy',
1342 'sintegrator.type': 'directlighting',
1343 'sintegrator.dlighting.maxdepth': 5,
1345 'pixelfilter.type': 'mitchell',
1346 'pixelfilter.mitchell.sharp': 0.250,
1347 'pixelfilter.mitchell.xwidth': 2.0,
1348 'pixelfilter.mitchell.ywidth': 2.0,
1349 'pixelfilter.mitchell.optmode': "slider" }
1351 presets['1 Final - MLT/Bidir Path Tracing (interior) (recommended)'] = {
1352 'film.displayinterval': 8,
1354 'useparamkeys': 'false',
1355 'sampler.showadvanced': 'false',
1356 'sintegrator.showadvanced': 'false',
1357 'pixelfilter.showadvanced': 'false',
1359 'sampler.type': 'metropolis',
1360 'sampler.metro.strength': 0.6,
1361 'sampler.metro.lmprob': 0.4,
1362 'sampler.metro.maxrejects': 512,
1363 'sampler.metro.initsamples': 262144,
1364 'sampler.metro.usevariance': "false",
1366 'sintegrator.type': 'bidirectional',
1367 'sintegrator.bidir.bounces': 16,
1368 'sintegrator.bidir.eyedepth': 16,
1369 'sintegrator.bidir.lightdepth': 16,
1371 'pixelfilter.type': 'mitchell',
1372 'pixelfilter.mitchell.sharp': 0.250,
1373 'pixelfilter.mitchell.xwidth': 2.0,
1374 'pixelfilter.mitchell.ywidth': 2.0,
1375 'pixelfilter.mitchell.optmode': "slider" }
1377 presets['2 Final - MLT/Path Tracing (exterior)'] = {
1378 'film.displayinterval': 8,
1380 'useparamkeys': 'false',
1381 'sampler.showadvanced': 'false',
1382 'sintegrator.showadvanced': 'false',
1383 'pixelfilter.showadvanced': 'false',
1385 'sampler.type': 'metropolis',
1386 'sampler.metro.strength': 0.6,
1387 'sampler.metro.lmprob': 0.4,
1388 'sampler.metro.maxrejects': 512,
1389 'sampler.metro.initsamples': 262144,
1390 'sampler.metro.usevariance': "false",
1392 'sintegrator.type': 'path',
1393 'sintegrator.bidir.bounces': 10,
1394 'sintegrator.bidir.maxdepth': 10,
1396 'pixelfilter.type': 'mitchell',
1397 'pixelfilter.mitchell.sharp': 0.250,
1398 'pixelfilter.mitchell.xwidth': 2.0,
1399 'pixelfilter.mitchell.ywidth': 2.0,
1400 'pixelfilter.mitchell.optmode': "slider" }
1404 presets['5 Progressive - Bidir Path Tracing (interior)'] = {
1405 'film.displayinterval': 8,
1407 'useparamkeys': 'false',
1408 'sampler.showadvanced': 'false',
1409 'sintegrator.showadvanced': 'false',
1410 'pixelfilter.showadvanced': 'false',
1412 'sampler.type': 'lowdiscrepancy',
1413 'sampler.lowdisc.pixelsamples': 1,
1414 'sampler.lowdisc.pixelsampler': 'lowdiscrepancy',
1416 'sintegrator.type': 'bidirectional',
1417 'sintegrator.bidir.bounces': 16,
1418 'sintegrator.bidir.eyedepth': 16,
1419 'sintegrator.bidir.lightdepth': 16,
1421 'pixelfilter.type': 'mitchell',
1422 'pixelfilter.mitchell.sharp': 0.250,
1423 'pixelfilter.mitchell.xwidth': 2.0,
1424 'pixelfilter.mitchell.ywidth': 2.0,
1425 'pixelfilter.mitchell.optmode': "slider" }
1427 presets['6 Progressive - Path Tracing (exterior)'] = {
1428 'film.displayinterval': 8,
1430 'useparamkeys': 'false',
1431 'sampler.showadvanced': 'false',
1432 'sintegrator.showadvanced': 'false',
1433 'pixelfilter.showadvanced': 'false',
1435 'sampler.type': 'lowdiscrepancy',
1436 'sampler.lowdisc.pixelsamples': 1,
1437 'sampler.lowdisc.pixelsampler': 'lowdiscrepancy',
1439 'sintegrator.type': 'path',
1440 'sintegrator.bidir.bounces': 10,
1441 'sintegrator.bidir.maxdepth': 10,
1443 'pixelfilter.type': 'mitchell',
1444 'pixelfilter.mitchell.sharp': 0.250,
1445 'pixelfilter.mitchell.xwidth': 2.0,
1446 'pixelfilter.mitchell.ywidth': 2.0,
1447 'pixelfilter.mitchell.optmode': "slider" }
1451 presets['8 Bucket - Bidir Path Tracing (interior)'] = {
1452 'film.displayinterval': 8,
1454 'useparamkeys': 'false',
1455 'sampler.showadvanced': 'false',
1456 'sintegrator.showadvanced': 'false',
1457 'pixelfilter.showadvanced': 'false',
1459 'sampler.type': 'lowdiscrepancy',
1460 'sampler.lowdisc.pixelsamples': 64,
1461 'sampler.lowdisc.pixelsampler': 'hilbert',
1463 'sintegrator.type': 'bidirectional',
1464 'sintegrator.bidir.bounces': 8,
1465 'sintegrator.bidir.eyedepth': 8,
1466 'sintegrator.bidir.lightdepth': 10,
1468 'pixelfilter.type': 'mitchell',
1469 'pixelfilter.mitchell.sharp': 0.250,
1470 'pixelfilter.mitchell.xwidth': 2.0,
1471 'pixelfilter.mitchell.ywidth': 2.0,
1472 'pixelfilter.mitchell.optmode': "slider" }
1474 presets['9 Bucket - Path Tracing (exterior)'] = {
1475 'film.displayinterval': 8,
1477 'useparamkeys': 'false',
1478 'sampler.showadvanced': 'false',
1479 'sintegrator.showadvanced': 'false',
1480 'pixelfilter.showadvanced': 'false',
1482 'sampler.type': 'lowdiscrepancy',
1483 'sampler.lowdisc.pixelsamples': 64,
1484 'sampler.lowdisc.pixelsampler': 'hilbert',
1486 'sintegrator.type': 'path',
1487 'sintegrator.bidir.bounces': 8,
1488 'sintegrator.bidir.maxdepth': 8,
1490 'pixelfilter.type': 'mitchell',
1491 'pixelfilter.mitchell.sharp': 0.333,
1492 'pixelfilter.mitchell.xwidth': 2.0,
1493 'pixelfilter.mitchell.ywidth': 2.0,
1494 'pixelfilter.mitchell.optmode': "slider" }
1498 presets['B Anim - Distributed/GI low Q'] = {
1499 'film.displayinterval': 8,
1501 'useparamkeys': 'false',
1502 'sampler.showadvanced': 'false',
1503 'sintegrator.showadvanced': 'false',
1504 'pixelfilter.showadvanced': 'false',
1506 'sampler.type': 'lowdiscrepancy',
1507 'sampler.lowdisc.pixelsamples': 16,
1508 'sampler.lowdisc.pixelsampler': 'hilbert',
1510 'sintegrator.type': 'distributedpath',
1511 'sintegrator.distributedpath.causticsonglossy': 'true',
1512 'sintegrator.distributedpath.diffuserefractdepth': 5,
1513 'sintegrator.distributedpath.indirectglossy': 'true',
1514 'sintegrator.distributedpath.directsamples': 1,
1515 'sintegrator.distributedpath.diffuserefractsamples': 1,
1516 'sintegrator.distributedpath.glossyreflectdepth': 2,
1517 'sintegrator.distributedpath.causticsondiffuse': 'false',
1518 'sintegrator.distributedpath.directsampleall': 'true',
1519 'sintegrator.distributedpath.indirectdiffuse': 'true',
1520 'sintegrator.distributedpath.specularreflectdepth': 3,
1521 'sintegrator.distributedpath.diffusereflectsamples': 1,
1522 'sintegrator.distributedpath.glossyreflectsamples': 1,
1523 'sintegrator.distributedpath.glossyrefractdepth': 5,
1524 'sintegrator.distributedpath.diffusereflectdepth': '2',
1525 'sintegrator.distributedpath.indirectsamples': 1,
1526 'sintegrator.distributedpath.indirectsampleall': 'false',
1527 'sintegrator.distributedpath.glossyrefractsamples': 1,
1528 'sintegrator.distributedpath.directdiffuse': 'true',
1529 'sintegrator.distributedpath.directglossy': 'true',
1530 'sintegrator.distributedpath.strategy': 'auto',
1531 'sintegrator.distributedpath.specularrefractdepth': 5,
1533 'pixelfilter.type': 'mitchell',
1534 'pixelfilter.mitchell.sharp': 0.333,
1535 'pixelfilter.mitchell.xwidth': 2.0,
1536 'pixelfilter.mitchell.ywidth': 2.0,
1537 'pixelfilter.mitchell.optmode': "slider" }
1539 presets['C Anim - Distributed/GI medium Q'] = {
1540 'film.displayinterval': 8,
1542 'useparamkeys': 'false',
1543 'sampler.showadvanced': 'false',
1544 'sintegrator.showadvanced': 'false',
1545 'pixelfilter.showadvanced': 'false',
1547 'sampler.type': 'lowdiscrepancy',
1548 'sampler.lowdisc.pixelsamples': 64,
1549 'sampler.lowdisc.pixelsampler': 'hilbert',
1551 'sintegrator.type': 'distributedpath',
1552 'sintegrator.distributedpath.causticsonglossy': 'true',
1553 'sintegrator.distributedpath.diffuserefractdepth': 5,
1554 'sintegrator.distributedpath.indirectglossy': 'true',
1555 'sintegrator.distributedpath.directsamples': 1,
1556 'sintegrator.distributedpath.diffuserefractsamples': 1,
1557 'sintegrator.distributedpath.glossyreflectdepth': 2,
1558 'sintegrator.distributedpath.causticsondiffuse': 'false',
1559 'sintegrator.distributedpath.directsampleall': 'true',
1560 'sintegrator.distributedpath.indirectdiffuse': 'true',
1561 'sintegrator.distributedpath.specularreflectdepth': 3,
1562 'sintegrator.distributedpath.diffusereflectsamples': 1,
1563 'sintegrator.distributedpath.glossyreflectsamples': 1,
1564 'sintegrator.distributedpath.glossyrefractdepth': 5,
1565 'sintegrator.distributedpath.diffusereflectdepth': '2',
1566 'sintegrator.distributedpath.indirectsamples': 1,
1567 'sintegrator.distributedpath.indirectsampleall': 'false',
1568 'sintegrator.distributedpath.glossyrefractsamples': 1,
1569 'sintegrator.distributedpath.directdiffuse': 'true',
1570 'sintegrator.distributedpath.directglossy': 'true',
1571 'sintegrator.distributedpath.strategy': 'auto',
1572 'sintegrator.distributedpath.specularrefractdepth': 5,
1574 'pixelfilter.type': 'mitchell',
1575 'pixelfilter.mitchell.sharp': 0.333,
1576 'pixelfilter.mitchell.xwidth': 2.0,
1577 'pixelfilter.mitchell.ywidth': 2.0,
1578 'pixelfilter.mitchell.optmode': "slider" }
1580 presets['D Anim - Distributed/GI high Q'] = {
1581 'film.displayinterval': 8,
1583 'useparamkeys': 'false',
1584 'sampler.showadvanced': 'false',
1585 'sintegrator.showadvanced': 'false',
1586 'pixelfilter.showadvanced': 'false',
1588 'sampler.type': 'lowdiscrepancy',
1589 'sampler.lowdisc.pixelsamples': 256,
1590 'sampler.lowdisc.pixelsampler': 'hilbert',
1592 'sintegrator.type': 'distributedpath',
1593 'sintegrator.distributedpath.causticsonglossy': 'true',
1594 'sintegrator.distributedpath.diffuserefractdepth': 5,
1595 'sintegrator.distributedpath.indirectglossy': 'true',
1596 'sintegrator.distributedpath.directsamples': 1,
1597 'sintegrator.distributedpath.diffuserefractsamples': 1,
1598 'sintegrator.distributedpath.glossyreflectdepth': 2,
1599 'sintegrator.distributedpath.causticsondiffuse': 'false',
1600 'sintegrator.distributedpath.directsampleall': 'true',
1601 'sintegrator.distributedpath.indirectdiffuse': 'true',
1602 'sintegrator.distributedpath.specularreflectdepth': 3,
1603 'sintegrator.distributedpath.diffusereflectsamples': 1,
1604 'sintegrator.distributedpath.glossyreflectsamples': 1,
1605 'sintegrator.distributedpath.glossyrefractdepth': 5,
1606 'sintegrator.distributedpath.diffusereflectdepth': '2',
1607 'sintegrator.distributedpath.indirectsamples': 1,
1608 'sintegrator.distributedpath.indirectsampleall': 'false',
1609 'sintegrator.distributedpath.glossyrefractsamples': 1,
1610 'sintegrator.distributedpath.directdiffuse': 'true',
1611 'sintegrator.distributedpath.directglossy': 'true',
1612 'sintegrator.distributedpath.strategy': 'auto',
1613 'sintegrator.distributedpath.specularrefractdepth': 5,
1615 'pixelfilter.type': 'mitchell',
1616 'pixelfilter.mitchell.sharp': 0.333,
1617 'pixelfilter.mitchell.xwidth': 2.0,
1618 'pixelfilter.mitchell.ywidth': 2.0,
1619 'pixelfilter.mitchell.optmode': "slider" }
1621 presets['E Anim - Distributed/GI very high Q'] = {
1622 'film.displayinterval': 8,
1624 'useparamkeys': 'false',
1625 'sampler.showadvanced': 'false',
1626 'sintegrator.showadvanced': 'false',
1627 'pixelfilter.showadvanced': 'false',
1629 'sampler.type': 'lowdiscrepancy',
1630 'sampler.lowdisc.pixelsamples': 512,
1631 'sampler.lowdisc.pixelsampler': 'hilbert',
1633 'sintegrator.type': 'distributedpath',
1634 'sintegrator.distributedpath.causticsonglossy': 'true',
1635 'sintegrator.distributedpath.diffuserefractdepth': 5,
1636 'sintegrator.distributedpath.indirectglossy': 'true',
1637 'sintegrator.distributedpath.directsamples': 1,
1638 'sintegrator.distributedpath.diffuserefractsamples': 1,
1639 'sintegrator.distributedpath.glossyreflectdepth': 2,
1640 'sintegrator.distributedpath.causticsondiffuse': 'false',
1641 'sintegrator.distributedpath.directsampleall': 'true',
1642 'sintegrator.distributedpath.indirectdiffuse': 'true',
1643 'sintegrator.distributedpath.specularreflectdepth': 3,
1644 'sintegrator.distributedpath.diffusereflectsamples': 1,
1645 'sintegrator.distributedpath.glossyreflectsamples': 1,
1646 'sintegrator.distributedpath.glossyrefractdepth': 5,
1647 'sintegrator.distributedpath.diffusereflectdepth': '2',
1648 'sintegrator.distributedpath.indirectsamples': 1,
1649 'sintegrator.distributedpath.indirectsampleall': 'false',
1650 'sintegrator.distributedpath.glossyrefractsamples': 1,
1651 'sintegrator.distributedpath.directdiffuse': 'true',
1652 'sintegrator.distributedpath.directglossy': 'true',
1653 'sintegrator.distributedpath.strategy': 'auto',
1654 'sintegrator.distributedpath.specularrefractdepth': 5,
1656 'pixelfilter.type': 'mitchell',
1657 'pixelfilter.mitchell.sharp': 0.333,
1658 'pixelfilter.mitchell.xwidth': 2.0,
1659 'pixelfilter.mitchell.ywidth': 2.0,
1660 'pixelfilter.mitchell.optmode': "slider" }
1664 def getMaterialPresets():
1665 return getPresets('luxblend_materials')
1667 def savePreset(key, name, d):
1669 presets = getPresets(key)
1671 presets[name] = d.copy()
1674 Blender.Registry.SetKey(key, presets, True)
1676 def saveScenePreset(name, d):
1678 for n in presetsExclude:
1681 savePreset('luxblend_presets', name, d)
1683 def saveMaterialPreset(name, d):
1685 for n in presetsExclude:
1688 savePreset('luxblend_materials', name, d)
1692 # **************************************************
1698 usedproperties = {} # global variable to collect used properties for storing presets
1699 usedpropertiesfilterobj = None # assign a object to only collect the properties that are assigned to this object
1701 # class to access properties (for lux settings)
1703 def __init__(self, obj, name, default):
1706 # if len(name)>31: print "Warning: property-name \"%s\" has more than 31 chars."%(name)
1707 self.hashmode = len(name)>31 # activate hash mode for keynames longer 31 chars (limited by blenders ID-prop)
1708 self.hashname = "__hash:%x"%(name.__hash__())
1709 self.default = default
1710 def parseassignment(self, s, name):
1712 if l[0] != name: print "Warning: property-name \"%s\" has hash-collide with \"%s\"."%(name, l[0])
1714 def createassignment(self, name, value):
1715 return "%s = %s"%(name, value)
1717 global usedproperties, usedpropertiesfilterobj, luxdefaults
1720 value = self.obj.properties['luxblend'][self.name]
1721 if not(usedpropertiesfilterobj) or (usedpropertiesfilterobj == self.obj):
1722 usedproperties[self.name] = value
1726 value = self.parseassignment(self.obj.properties['luxblend'][self.hashname], self.name)
1727 if not(usedpropertiesfilterobj) or (usedpropertiesfilterobj == self.obj):
1728 usedproperties[self.name] = value
1731 if self.obj.__class__.__name__ == "Scene": # luxdefaults only for global setting
1733 value = luxdefaults[self.name]
1734 if not(usedpropertiesfilterobj) or (usedpropertiesfilterobj == self.obj):
1735 usedproperties[self.name] = value
1738 if not(usedpropertiesfilterobj) or (usedpropertiesfilterobj == self.obj):
1739 usedproperties[self.name] = self.default
1741 if not(usedpropertiesfilterobj) or (usedpropertiesfilterobj == self.obj):
1742 usedproperties[self.name] = self.default
1755 def set(self, value):
1756 global newluxdefaults
1758 if self.hashmode: n, v = self.hashname, self.createassignment(self.name, value)
1759 else: n, v = self.name, value
1760 if value is not None:
1761 try: self.obj.properties['luxblend'][n] = v
1762 except (KeyError, TypeError):
1763 self.obj.properties['luxblend'] = {}
1764 self.obj.properties['luxblend'][n] = v
1766 try: del self.obj.properties['luxblend'][n]
1768 if self.obj.__class__.__name__ == "Scene": # luxdefaults only for global setting
1769 # value has changed, so this are user settings, remove preset reference
1770 if not(self.name in defaultsExclude):
1771 newluxdefaults[self.name] = value
1772 try: self.obj.properties['luxblend']['preset']=""
1776 try: del self.obj.properties['luxblend'][self.name]
1778 try: del self.obj.properties['luxblend'][self.hashname]
1782 if type(v) == types.FloatType: return float(v)
1784 if type(v) == types.StringType: return float(v.split(" ")[0])
1787 if type(v) == types.FloatType: return float(v)
1789 if type(v) == types.StringType: return float(v.split(" ")[0])
1793 try: return int(self.get())
1794 except: return int(self.default)
1796 return self.getVector()
1797 def getVector(self):
1799 if type(v) in [types.FloatType, types.IntType]: return (float(v), float(v), float(v))
1802 if type(v) == types.StringType: l = self.get().split(" ")
1805 if (l==None) or (len(l) != 3): l = self.default.split(" ")
1806 return (float(l[0]), float(l[1]), float(l[2]))
1807 except AttributeError:
1808 return (float(l[0]), float(l[0]), float(l[0]))
1810 def getVectorStr(self):
1811 return "%f %f %f"%self.getVector()
1813 return type(self.get()) == types.FloatType
1816 return "%f %f %f"%(rg(col[0]), rg(col[1]),rg(col[2]))
1817 def setRGB(self, value):
1818 self.set("%f %f %f"%(value[0], value[1], value[2]))
1819 def setVector(self, value):
1820 self.set("%f %f %f"%(value[0], value[1], value[2]))
1823 # class to access blender attributes (for lux settings)
1825 def __init__(self, obj, name):
1830 return getattr(self.obj, self.name)
1834 return float(self.get())
1836 return int(self.get())
1847 def set(self, value):
1849 setattr(self.obj, self.name, value)
1853 # class for dynamic gui
1855 def __init__(self, y=200):
1856 self.x = 110 # left start position after captions
1857 self.xmax = 110+2*(140+4)
1859 self.w = 140 # default element width in pixels
1860 self.h = 18 # default element height in pixels
1864 self.resethmax = False
1865 def getRect(self, wu, hu):
1866 w = int(self.w * wu + self.xgap * (wu-1))
1867 h = int(self.h * hu + self.ygap * (hu-1))
1868 if self.x + w > self.xmax: self.newline()
1869 if self.resethmax: self.hmax = 0; self.resethmax = False
1870 rect = [int(self.x), int(self.y-h), int(w), int(h)]
1871 self.x += int(w + self.xgap)
1872 if h+self.ygap > self.hmax: self.hmax = int(h+self.ygap)
1874 def newline(self, title="", distance=0, level=0, icon=None, color=None):
1876 if not(self.resethmax): self.y -= int(self.hmax + distance)
1877 if color!=None: BGL.glColor3f(color[0],color[1],color[2]); BGL.glRectf(0,self.y-self.hmax,self.xmax,self.y+distance); BGL.glColor3f(0.9, 0.9, 0.9)
1878 if icon!=None: drawIcon(icon, 2+level*10, self.y-16)
1879 self.resethmax = True
1882 BGL.glColor3f(0.9,0.9,0.9); BGL.glRasterPos2i(20+level*10,self.y-self.h+5); Draw.Text(title)
1884 def luxHelp(name, lux, caption, hint, gui, width=1.0):
1886 r = gui.getRect(width, 1)
1887 Draw.Toggle(caption, evtLuxGui, r[0], r[1], r[2], r[3], lux.get()=="true", hint, lambda e,v: lux.set(["false","true"][bool(v)]))
1888 drawIcon(icon_help, r[0], r[1])
1890 return "\n \"bool %s\" [\"%s\"]"%(name, lux.get())
1892 # lux parameter types
1893 def luxOption(name, lux, options, caption, hint, gui, width=1.0):
1895 menustr = caption+": %t"
1896 for i, v in enumerate(options): menustr = "%s %%x%d|%s"%(v, i, menustr)
1898 i = options.index(lux.get())
1901 lux.set(lux.default) # not found, so try default value
1902 i = options.index(lux.get())
1904 print "value %s not found in options list"%(lux.get())
1906 r = gui.getRect(width, 1)
1907 Draw.Menu(menustr, evtLuxGui, r[0], r[1], r[2], r[3], i, hint, lambda e,v: lux.set(options[v]))
1908 return "\n \"string %s\" [\"%s\"]"%(name, lux.get())
1910 def luxOptionRect(name, lux, options, caption, hint, gui, x, y, xx, yy):
1912 menustr = caption+": %t"
1913 for i, v in enumerate(options): menustr = "%s %%x%d|%s"%(v, i, menustr)
1915 i = options.index(lux.get())
1918 lux.set(lux.default) # not found, so try default value
1919 i = options.index(lux.get())
1921 print "value %s not found in options list"%(lux.get())
1923 Draw.Menu(menustr, evtLuxGui, x, y, xx, yy, i, hint, lambda e,v: lux.set(options[v]))
1924 return "\n \"string %s\" [\"%s\"]"%(name, lux.get())
1926 def luxIdentifier(name, lux, options, caption, hint, gui, icon=None, width=1.0):
1927 if gui: gui.newline(caption+":", 8, 0, icon, [0.75,0.5,0.25])
1928 luxOption(name, lux, options, caption, hint, gui, width)
1929 return "\n%s \"%s\""%(name, lux.get())
1931 def luxFloat(name, lux, min, max, caption, hint, gui, width=1.0, useslider=0):
1933 if (luxProp(Scene.GetCurrent(), "useparamkeys", "false").get()=="true"):
1934 r = gui.getRect(width-0.12, 1)
1936 r = gui.getRect(width, 1)
1940 Draw.Slider(caption+": ", evtLuxGui, r[0], r[1], r[2], r[3], lux.getFloat(), min, max, 0, hint, lambda e,v: lux.set(v))
1942 Draw.Number(caption+": ", evtLuxGui, r[0], r[1], r[2], r[3], lux.getFloat(), min, max, hint, lambda e,v: lux.set(v))
1943 if (luxProp(Scene.GetCurrent(), "useparamkeys", "false").get()=="true"):
1946 keyname = lux.getname()
1948 useipo = luxProp(obj, keyname+".IPOuse", "false")
1949 i = gui.getRect(0.12, 1)
1950 Draw.Toggle("I", evtLuxGui, i[0], i[1], i[2], i[3], useipo.get()=="true", "Use IPO Curve", lambda e,v: useipo.set(["false","true"][bool(v)]))
1952 if useipo.get() == "true":
1953 if gui: gui.newline(caption+"IPO:", 8, 0, None, [0.5,0.45,0.35])
1954 curve = luxProp(obj, keyname+".IPOCurveName", "")
1955 if curve.get() == "":
1956 c = gui.getRect(2.0, 1)
1958 c = gui.getRect(1.1, 1)
1960 Draw.String("Ipo:", evtLuxGui, c[0], c[1], c[2], c[3], curve.get(), 250, "Set IPO Name", lambda e,v: curve.set(v))
1962 usemapping = luxProp(obj, keyname+".IPOmap", "false")
1965 # Apply IPO to value
1966 if curve.get() != "":
1968 ipoob = Blender.Ipo.Get(curve.get())
1972 if curve.get() != "":
1973 names = list([x[0] for x in ipoob.curveConsts.items()])
1974 ipotype = luxProp(obj, keyname+".IPOCurveType", "OB_LOCZ")
1975 luxOption("ipocurve", ipotype, names, "IPO Curve", "Set IPO Curve", gui, 0.6)
1977 icu = ipoob[eval("Blender.Ipo.%s" % (ipotype.get()))]
1978 icu_value = icu[Blender.Get('curframe')]
1979 if usemapping.get() == "false": # if true is set during mapping below
1983 m = gui.getRect(0.3, 1)
1984 Draw.Toggle("Map", evtLuxGui, m[0], m[1], m[2], m[3], usemapping.get()=="true", "Edit Curve mapping", lambda e,v: usemapping.set(["false","true"][bool(v)]))
1985 if usemapping.get() == "true":
1986 if gui: gui.newline(caption+"IPO:", 8, 0, None, [0.5,0.45,0.35])
1987 fmin = luxProp(obj, keyname+".IPOCurvefmin", 0.0)
1988 luxFloatNoIPO("ipofmin", fmin, -100, 100, "fmin", "Map minimum value from Curve", gui, 0.5)
1989 fmax = luxProp(obj, keyname+".IPOCurvefmax", 1.0)
1990 luxFloatNoIPO("ipofmax", fmax, -100, 100, "fmax", "Map maximum value from Curve", gui, 0.5)
1991 tmin = luxProp(obj, keyname+".IPOCurvetmin", min)
1992 luxFloatNoIPO("ipotmin", tmin, min, max, "tmin", "Map miminum value to", gui, 0.5)
1993 tmax = luxProp(obj, keyname+".IPOCurvetmax", max)
1994 luxFloatNoIPO("ipotmax", tmax, min, max, "tmax", "Map maximum value to", gui, 0.5)
1996 sval = (icu_value - fmin.getFloat()) / (fmax.getFloat() - fmin.getFloat())
1997 lux.set(tmin.getFloat() + (sval * (tmax.getFloat() - tmin.getFloat())))
2000 #v = gui.getRect(0.5, 1)
2001 #Draw.Toggle("Invert", evtLuxGui, v[0], v[1], v[2], v[3], useipo.get()=="true", "Invert Curve values", lambda e,v: useipo.set(["false","true"][bool(v)]))
2003 if (luxProp(Scene.GetCurrent(), "useparamkeys", "false").get()=="true"):
2005 keyname = lux.getname()
2006 useipo = luxProp(obj, keyname+".IPOuse", "false")
2007 if useipo.get() == "true":
2008 curve = luxProp(obj, keyname+".IPOCurveName", "")
2010 ipoob = Blender.Ipo.Get(curve.get())
2014 usemapping = luxProp(obj, keyname+".IPOmap", "false")
2016 if curve.get() != "":
2017 names = list([x[0] for x in ipoob.curveConsts.items()])
2018 ipotype = luxProp(obj, keyname+".IPOCurveType", "OB_LOCZ")
2020 icu = ipoob[eval("Blender.Ipo.%s" % (ipotype.get()))]
2021 icu_value = icu[Blender.Get('curframe')]
2022 if usemapping.get() == "false": # if true is set during mapping below
2025 if usemapping.get() == "true":
2026 if gui: gui.newline(caption+"IPO:", 8, 0, None, [0.5,0.45,0.35])
2027 fmin = luxProp(obj, keyname+".IPOCurvefmin", 0.0)
2028 fmax = luxProp(obj, keyname+".IPOCurvefmax", 1.0)
2029 tmin = luxProp(obj, keyname+".IPOCurvetmin", min)
2030 tmax = luxProp(obj, keyname+".IPOCurvetmax", max)
2031 sval = (icu_value - fmin.getFloat()) / (fmax.getFloat() - fmin.getFloat())
2032 lux.set(tmin.getFloat() + (sval * (tmax.getFloat() - tmin.getFloat())))
2034 return "\n \"float %s\" [%f]"%(name, lux.getFloat())
2036 def luxFloatNoIPO(name, lux, min, max, caption, hint, gui, width=1.0, useslider=0):
2038 r = gui.getRect(width, 1)
2040 Draw.Slider(caption+": ", evtLuxGui, r[0], r[1], r[2], r[3], lux.getFloat(), min, max, 0, hint, lambda e,v: lux.set(v))
2042 Draw.Number(caption+": ", evtLuxGui, r[0], r[1], r[2], r[3], lux.getFloat(), min, max, hint, lambda e,v: lux.set(v))
2043 return "\n \"float %s\" [%f]"%(name, lux.getFloat())
2047 def luxInt(name, lux, min, max, caption, hint, gui, width=1.0):
2049 r = gui.getRect(width, 1)
2050 Draw.Number(caption+": ", evtLuxGui, r[0], r[1], r[2], r[3], lux.getInt(), min, max, hint, lambda e,v: lux.set(v))
2051 return "\n \"integer %s\" [%d]"%(name, lux.getInt())
2053 def luxBool(name, lux, caption, hint, gui, width=1.0):
2055 r = gui.getRect(width, 1)
2056 Draw.Toggle(caption, evtLuxGui, r[0], r[1], r[2], r[3], lux.get()=="true", hint, lambda e,v: lux.set(["false","true"][bool(v)]))
2057 return "\n \"bool %s\" [\"%s\"]"%(name, lux.get())
2059 def luxCollapse(name, lux, caption, hint, gui, width=1.0):
2061 r = gui.getRect(width, 1)
2062 if lux.get() == "true":
2063 drawArrow(arrow_down, r[0]-22, r[1]-2)
2065 drawArrow(arrow_right, r[0]-22, r[1]-2)
2066 Draw.Toggle(caption, evtLuxGui, r[0], r[1], r[2], r[3], lux.get()=="true", hint, lambda e,v: lux.set(["false","true"][bool(v)]))
2067 return "\n \"bool %s\" [\"%s\"]"%(name, lux.get())
2069 def luxString(name, lux, caption, hint, gui, width=1.0):
2071 r = gui.getRect(width, 1)
2072 Draw.String(caption+": ", evtLuxGui, r[0], r[1], r[2], r[3], lux.get(), 250, hint, lambda e,v: lux.set(v))
2073 if lux.get()==lux.default: return ""
2074 else: return "\n \"string %s\" [\"%s\"]"%(name, luxstr(lux.get()))
2076 def luxFile(name, lux, caption, hint, gui, width=1.0):
2078 r = gui.getRect(width, 1)
2079 Draw.String(caption+": ", evtLuxGui, r[0], r[1], r[2]-r[3]-2, r[3], lux.get(), 250, hint, lambda e,v: lux.set(v))
2080 Draw.Button("...", 0, r[0]+r[2]-r[3], r[1], r[3], r[3], "click to open file selector", lambda e,v:Window.FileSelector(lambda s:lux.set(s), "Select %s"%(caption), lux.get()))
2081 return "\n \"string %s\" [\"%s\"]"%(name, luxstr(luxFilePath(lux.get())))
2083 def luxPath(name, lux, caption, hint, gui, width=1.0):
2085 r = gui.getRect(width, 1)
2086 Draw.String(caption+": ", evtLuxGui, r[0], r[1], r[2]-r[3]-2, r[3], lux.get(), 250, hint, lambda e,v: lux.set(Blender.sys.dirname(v)+os.sep))
2087 Draw.Button("...", 0, r[0]+r[2]-r[3], r[1], r[3], r[3], "click to open file selector", lambda e,v:Window.FileSelector(lambda s:lux.set(s), "Select %s"%(caption), lux.get()))
2088 return "\n \"string %s\" [\"%s\"]"%(name, luxstr(lux.get()))
2090 def luxRGB(name, lux, max, caption, hint, gui, width=2.0):
2092 r = gui.getRect(width, 1)
2097 if rgb[i] > scale: scale = rgb[i]
2098 rgb = (rgb[0]/scale, rgb[1]/scale, rgb[2]/scale)
2099 Draw.ColorPicker(evtLuxGui, r[0], r[1], r[3], r[3], rgb, "click to select color", lambda e,v: lux.setRGB((v[0]*scale,v[1]*scale,v[2]*scale)))
2100 w = int((r[2]-r[3])/3); m = max
2102 w = int((r[2]-r[3])/4); m = 1.0
2103 drawR, drawG, drawB, drawS = Draw.Create(rgb[0]), Draw.Create(rgb[1]), Draw.Create(rgb[2]), Draw.Create(scale)
2104 drawR = Draw.Number("R:", evtLuxGui, r[0]+r[3], r[1], w, r[3], drawR.val, 0.0, m, "red", lambda e,v: lux.setRGB((v*scale,drawG.val*scale,drawB.val*scale)))
2105 drawG = Draw.Number("G:", evtLuxGui, r[0]+r[3]+w, r[1], w, r[3], drawG.val, 0.0, m, "green", lambda e,v: lux.setRGB((drawR.val*scale,v*scale,drawB.val*scale)))
2106 drawB = Draw.Number("B:", evtLuxGui, r[0]+r[3]+2*w, r[1], w, r[3], drawB.val, 0.0, m, "blue", lambda e,v: lux.setRGB((drawR.val*scale,drawG.val*scale,v*scale)))
2108 Draw.Number("s:", evtLuxGui, r[0]+r[3]+3*w, r[1], w, r[3], drawS.val, 0.0, max, "color scale", lambda e,v: lux.setRGB((drawR.val*v,drawG.val*v,drawB.val*v)))
2110 return "\n \"color %s\" [%s]"%(name, lux.getRGC())
2111 return "\n \"color %s\" [%s]"%(name, lux.get())
2113 def luxVector(name, lux, min, max, caption, hint, gui, width=2.0):
2115 r = gui.getRect(width, 1)
2116 vec = lux.getVector()
2118 drawX, drawY, drawZ = Draw.Create(vec[0]), Draw.Create(vec[1]), Draw.Create(vec[2])
2119 drawX = Draw.Number("x:", evtLuxGui, r[0], r[1], w, r[3], drawX.val, min, max, "", lambda e,v: lux.setVector((v,drawY.val,drawZ.val)))
2120 drawY = Draw.Number("y:", evtLuxGui, r[0]+w, r[1], w, r[3], drawY.val, min, max, "", lambda e,v: lux.setVector((drawX.val,v,drawZ.val)))
2121 drawZ = Draw.Number("z:", evtLuxGui, r[0]+2*w, r[1], w, r[3], drawZ.val, min, max, "", lambda e,v: lux.setVector((drawX.val,drawY.val,v)))
2122 return "\n \"vector %s\" [%s]"%(name, lux.get())
2124 def luxVectorUniform(name, lux, min, max, caption, hint, gui, width=2.0):
2125 def setUniform(lux, value):
2126 if value: lux.set(lux.getFloat())
2127 else: lux.setVector(lux.getVector())
2129 r = gui.getRect(width, 1)
2130 vec = lux.getVector()
2131 Draw.Toggle("U", evtLuxGui, r[0], r[1], gui.h, gui.h, lux.isFloat(), "uniform", lambda e,v: setUniform(lux, v))
2133 Draw.Number("v:", evtLuxGui, r[0]+gui.h, r[1], r[2]-gui.h, r[3], lux.getFloat(), min, max, "", lambda e,v: lux.set(v))
2135 w = int((r[2]-gui.h)/3)
2136 drawX, drawY, drawZ = Draw.Create(vec[0]), Draw.Create(vec[1]), Draw.Create(vec[2])
2137 drawX = Draw.Number("x:", evtLuxGui, r[0]+gui.h, r[1], w, r[3], drawX.val, min, max, "", lambda e,v: lux.setVector((v,drawY.val,drawZ.val)))
2138 drawY = Draw.Number("y:", evtLuxGui, r[0]+w+gui.h, r[1], w, r[3], drawY.val, min, max, "", lambda e,v: lux.setVector((drawX.val,v,drawZ.val)))
2139 drawZ = Draw.Number("z:", evtLuxGui, r[0]+2*w+gui.h, r[1], w, r[3], drawZ.val, min, max, "", lambda e,v: lux.setVector((drawX.val,drawY.val,v)))
2140 return "\n \"vector %s\" [%s]"%(name, lux.getVectorStr())
2143 # lux individual identifiers
2144 def luxCamera(cam, context, gui=None):
2145 global icon_c_camera
2148 camtype = luxProp(cam, "camera.type", "perspective")
2149 # Radiance - remarked 'realistic' for v0.6 release
2150 #str = luxIdentifier("Camera", camtype, ["perspective","orthographic","environment","realistic"], "CAMERA", "select camera type", gui, icon_c_camera)
2151 str = luxIdentifier("Camera", camtype, ["perspective","orthographic","environment"], "CAMERA", "select camera type", gui, icon_c_camera)
2153 if camtype.get() == "perspective":
2154 if gui: gui.newline(" View:")
2155 str += luxFloat("fov", luxAttr(cam, "angle"), 8.0, 170.0, "fov", "camera field-of-view angle", gui)
2156 fl = luxAttr(cam, "lens")
2158 luxFloat("lens", fl, 1.0, 250.0, "focallength", "camera focal length", gui)
2160 if camtype.get() == "orthographic" :
2161 str += luxFloat("scale", luxAttr(cam, "scale"), 0.01, 1000.0, "scale", "orthographic camera scale", gui)
2162 scale = cam.scale / 2
2163 if camtype.get() == "realistic":
2165 if gui: gui.newline(" View:")
2166 fov = luxAttr(cam, "angle")
2167 str += luxFloat("fov", fov, 8.0, 170.0, "fov", "camera field-of-view angle", gui)
2168 if gui: luxFloat("lens", luxAttr(cam, "lens"), 1.0, 250.0, "focallength", "camera focal length", gui)
2171 if gui: gui.newline()
2172 str += luxFile("specfile", luxProp(cam, "camera.realistic.specfile", ""), "spec-file", "", gui, 1.0)
2173 # if gui: gui.newline()
2174 # auto calc str += luxFloat("filmdistance", luxProp(cam, "camera.realistic.filmdistance", 70.0), 0.1, 1000.0, "film-dist", "film-distance [mm]", gui)
2175 filmdiag = luxProp(cam, "camera.realistic.filmdiag", 35.0)
2176 str += luxFloat("filmdiag", filmdiag, 0.1, 1000.0, "film-diag", "[mm]", gui)
2177 if gui: gui.newline()
2178 fstop = luxProp(cam, "camera.realistic.fstop", 1.0)
2179 luxFloat("aperture_diameter", fstop, 0.1, 100.0, "f-stop", "", gui)
2180 dofdist = luxAttr(cam, "dofDist")
2181 luxFloat("focaldistance", dofdist, 0.0, 10000.0, "distance", "Distance from the camera at which objects will be in focus. Has no effect if Lens Radius is 0", gui)
2183 Draw.Button("S", evtLuxGui, gui.x, gui.y-gui.h, gui.h, gui.h, "focus selected object", lambda e,v:setFocus("S"))
2184 Draw.Button("C", evtLuxGui, gui.x+gui.h, gui.y-gui.h, gui.h, gui.h, "focus cursor", lambda e,v:setFocus("C"))
2185 focal = filmdiag.get()*0.001 / math.tan(fov.get() * math.pi / 360.0) / 2.0
2186 print "calculated focal length: %f mm"%(focal * 1000.0)
2187 aperture_diameter = focal / fstop.get()
2188 print "calculated aperture diameter: %f mm"%(aperture_diameter * 1000.0)
2189 str += "\n \"float aperture_diameter\" [%f]"%(aperture_diameter*1000.0)
2190 filmdistance = dofdist.get() * focal / (dofdist.get() - focal)
2191 print "calculated film distance: %f mm"%(filmdistance * 1000.0)
2192 str += "\n \"float filmdistance\" [%f]"%(filmdistance*1000.0)
2195 useclip = luxProp(cam, "useclip", "false")
2196 luxCollapse("useclip", useclip, "Near & Far Clipping", "Enable Camera near and far clipping options", gui, 2.0)
2197 if(useclip.get() == "true"):
2198 if gui: gui.newline(" Clipping:")
2199 str += luxFloat("hither", luxAttr(cam, "clipStart"), 0.0, 100.0, "start", "near clip distance", gui)
2200 str += luxFloat("yon", luxAttr(cam, "clipEnd"), 1.0, 10000.0, "end", "far clip distance", gui)
2203 usedof = luxProp(cam, "usedof", "false")
2205 if camtype.get() in ["perspective", "orthographic"]:
2206 luxCollapse("usedof", usedof, "Depth of Field & Bokeh", "Enable Depth of Field & Aperture options", gui, 2.0)
2209 if usedof.get() == "true":
2211 if gui: gui.newline(" DOF:")
2213 lr = luxProp(cam, "camera.lensradius", 0.01)
2214 fs = luxProp(cam, "camera.fstop", 2.8)
2216 if camtype.get() == "perspective":
2218 usefstop = luxProp(cam, "usefstop", "false")
2219 luxBool("usefstop", usefstop, "Use f/stop", "Use f/stop to define DOF effect", gui, 1.0)
2221 LR_SCALE = 1000.0 # lr in metres -> mm
2222 FL_SCALE = 1.0 # fl in mm -> mm
2224 def lr_2_fs(fl, lr):
2226 return fl / ( 2.0 * lr )
2228 def fs_2_lr(fl, fs):
2229 return fl / ( 2.0 * fs )
2231 if usefstop.get() == 'true':
2232 lr.set(fs_2_lr(fl.get() * FL_SCALE, fs.get()) / LR_SCALE)
2233 luxFloat("fstop", fs, 0.9, 64.0, "fstop", "Defines the lens aperture.", gui)
2234 str += luxFloat("lensradius", lr, 0.0, 1.0, "", "", None)
2236 fs.set(lr_2_fs(fl.get() * FL_SCALE, lr.get() * LR_SCALE))
2237 str += luxFloat("lensradius", lr, 0.0, 1.0, "lens-radius", "Defines the lens radius. Values higher than 0. enable DOF and control the amount", gui)
2239 str += luxFloat("lensradius", lr, 0.0, 1.0, "lens-radius", "Defines the lens radius. Values higher than 0. enable DOF and control the amount", gui)
2241 focustype = luxProp(cam, "camera.focustype", "autofocus")
2242 luxOption("focustype", focustype, ["autofocus", "manual", "object"], "Focus Type", "Choose the focus behaviour", gui)
2245 if focustype.get() == "autofocus":
2246 str += luxBool("autofocus",luxProp(cam, "camera.autofocus", "true"), "autofocus", "Enable automatic focus", gui)
2247 if focustype.get() == "object":
2248 objectfocus = luxProp(cam, "camera.objectfocus", "")
2249 luxString("objectfocus", objectfocus, "object", "Always focus camera on named object", gui, 1.0)
2250 dofdist = luxAttr(cam, "dofDist")
2251 str += luxFloat("focaldistance", dofdist, 0.0, 100.0, "distance", "Distance from the camera at which objects will be in focus. Has no effect if Lens Radius is 0", gui)
2252 if objectfocus.get() != "":
2253 setFocus(objectfocus.get())
2254 if focustype.get() == "manual":
2255 dofdist = luxAttr(cam, "dofDist")
2256 str += luxFloat("focaldistance", dofdist, 0.0, 100.0, "distance", "Distance from the camera at which objects will be in focus. Has no effect if Lens Radius is 0", gui)
2258 Draw.Button("S", evtLuxGui, gui.x, gui.y-gui.h, gui.h, gui.h, "focus selected object", lambda e,v:setFocus("S"))
2259 Draw.Button("C", evtLuxGui, gui.x+gui.h, gui.y-gui.h, gui.h, gui.h, "focus cursor", lambda e,v:setFocus("C"))
2261 if camtype.get() == "perspective" and usedof.get() == "true":
2262 str += luxInt("blades", luxProp(cam, "camera.blades", 6), 0, 16, "aperture blades", "Number of blade edges of the aperture, values 0 to 2 defaults to a circle", gui)
2263 str += luxOption("distribution", luxProp(cam, "camera.distribution", "uniform"), ["uniform", "exponential", "inverse exponential", "gaussian", "inverse gaussian"], "distribution", "Choose the lens sampling distribution. Non-uniform distributions allow for ring effects.", gui)
2264 str += luxInt("power", luxProp(cam, "camera.power", 1), 0, 512, "power", "Exponent for the expression in exponential distribution. Higher value gives a more pronounced ring effect.", gui)
2266 useaspect = luxProp(cam, "useaspectratio", "false")
2267 aspectratio = luxProp(cam, "ratio", 1.3333)
2268 if camtype.get() in ["perspective", "orthographic"]:
2269 useshift = luxProp(cam, "camera.useshift", "false")
2270 luxCollapse("useshift", useshift, "Architectural (Lens Shift) & Aspect Ratio", "Enable Lens Shift and Aspect Ratio options", gui, 2.0)
2271 if(useshift.get() == "true"):
2272 if gui: gui.newline(" Shift:")
2273 luxFloat("X", luxAttr(cam, "shiftX"), -2.0, 2.0, "X", "horizontal lens shift", gui)
2274 luxFloat("Y", luxAttr(cam, "shiftY"), -2.0, 2.0, "Y", "vertical lens shift", gui)
2276 if gui: gui.newline(" AspectRatio:")
2277 luxBool("useaspectratio", useaspect, "Custom", "Define a custom frame aspect ratio", gui)
2278 if useaspect.get() == "true":
2279 str += luxFloat("frameaspectratio", aspectratio, 0.0001, 3.0, "aspectratio", "Frame aspect ratio", gui)
2281 if useaspect.get() == "true":
2282 ratio = 1./aspectratio.get()
2284 ratio = float(context.sizeY)/float(context.sizeX)
2286 screenwindow = [(2*cam.shiftX-1)*scale, (2*cam.shiftX+1)*scale, (2*cam.shiftY-ratio)*scale, (2*cam.shiftY+ratio)*scale]
2288 screenwindow = [(2*cam.shiftX-1/ratio)*scale, (2*cam.shiftX+1/ratio)*scale, (2*cam.shiftY-1)*scale, (2*cam.shiftY+1)*scale]
2289 # render region option
2290 if context.borderRender:
2291 (x1,y1,x2,y2) = context.border
2292 screenwindow = [screenwindow[0]*(1-x1)+screenwindow[1]*x1, screenwindow[0]*(1-x2)+screenwindow[1]*x2,\
2293 screenwindow[2]*(1-y1)+screenwindow[3]*y1, screenwindow[2]*(1-y2)+screenwindow[3]*y2]
2294 str += "\n \"float screenwindow\" [%f %f %f %f]"%(screenwindow[0], screenwindow[1], screenwindow[2], screenwindow[3])
2296 # Note - radiance - this is a work in progress
2297 # Flash lamp option for perspective and ortho cams
2298 # if camtype.get() in ["perspective", "orthographic"]:
2299 # useflash = luxProp(cam, "useflash", "false")
2300 # luxBool("useflash", useflash, "Flash Lamp", "Enable Camera mounted flash lamp options", gui, 2.0)
2302 # Motion Blur Options (common to all cameras)
2303 usemblur = luxProp(cam, "usemblur", "false")
2304 luxCollapse("usemblur", usemblur, "Motion Blur", "Enable Motion Blur", gui, 2.0)
2305 if(usemblur.get() == "true"):
2306 if gui: gui.newline(" Shutter:")
2307 mblurpreset = luxProp(cam, "mblurpreset", "true")
2308 luxBool("mblurpreset", mblurpreset, "Preset", "Enable use of Shutter Presets", gui, 0.4)
2309 if(mblurpreset.get() == "true"):
2310 shutterpresets = ["full frame", "half frame", "quarter frame", "1/25", "1/30", "1/45", "1/60", "1/85", "1/125", "1/250", "1/500"]
2311 shutterpreset = luxProp(cam, "camera.shutterspeedpreset", "full frame")
2312 luxOption("shutterpreset", shutterpreset, shutterpresets, "shutterspeed", "Choose the Shutter speed preset.", gui, 1.0)
2314 fpspresets = ["10 FPS", "12 FPS", "20 FPS", "25 FPS", "29.99 FPS", "30 FPS", "50 FPS", "60 FPS"]
2315 shutfps = luxProp(cam, "camera.shutfps", "25 FPS")
2316 luxOption("shutfps", shutfps, fpspresets, "@", "Choose the number of frames per second as the time base.", gui, 0.6)
2318 sfps = shutfps.get()
2320 if sfps == "10 FPS": fps = 10
2321 elif sfps == "12 FPS": fps = 12
2322 elif sfps == "20 FPS": fps = 20
2323 elif sfps == "25 FPS": fps = 25
2324 elif sfps == "29.99 FPS": fps = 29.99
2325 elif sfps == "30 FPS": fps = 30
2326 elif sfps == "50 FPS": fps = 50
2327 elif sfps == "60 FPS": fps = 60
2329 spre = shutterpreset.get()
2332 if spre == "full frame": close = 1.0
2333 elif spre == "half frame": close = 0.5
2334 elif spre == "quarter frame": close = 0.25
2335 elif spre == "1/25": close = 1.0 / 25.0 * fps
2336 elif spre == "1/30": close = 1.0 / 30.0 * fps
2337 elif spre == "1/45": close = 1.0 / 45.0 * fps
2338 elif spre == "1/60": close = 1.0 / 60.0 * fps
2339 elif spre == "1/85": close = 1.0 / 85.0 * fps
2340 elif spre == "1/125": close = 1.0 / 125.0 * fps
2341 elif spre == "1/250": close = 1.0 / 250.0 * fps
2342 elif spre == "1/500": close = 1.0 / 500.0 * fps
2344 str += "\n \"float shutteropen\" [%f]\n \"float shutterclose\" [%f] "%(open,close)
2347 str += luxFloat("shutteropen", luxProp(cam, "camera.shutteropen", 0.0), 0.0, 100.0, "open", "time in seconds when shutter opens", gui, 0.8)
2348 str += luxFloat("shutterclose", luxProp(cam, "camera.shutterclose", 1.0), 0.0, 100.0, "close", "time in seconds when shutter closes", gui, 0.8)
2350 str += luxOption("shutterdistribution", luxProp(cam, "camera.shutterdistribution", "uniform"), ["uniform", "gaussian"], "distribution", "Choose the shutter sampling distribution.", gui, 2.0)
2351 objectmblur = luxProp(cam, "objectmblur", "true")
2352 luxBool("objectmblur", objectmblur, "Object", "Enable Motion Blur for scene object motions", gui, 1.0)
2353 cammblur = luxProp(cam, "cammblur", "true")
2354 luxBool("cammblur", cammblur, "Camera", "Enable Motion Blur for Camera motion", gui, 1.0)
2358 def luxFilm(scn, gui=None):
2361 filmtype = luxProp(scn, "film.type", "fleximage")
2362 str = luxIdentifier("Film", filmtype, ["fleximage"], "FILM", "select film type", gui)
2363 if filmtype.get() == "fleximage":
2364 context = scn.getRenderingContext()
2366 if gui: gui.newline(" Resolution:")
2367 luxInt("xresolution", luxAttr(context, "sizeX"), 0, 8192, "X", "width of the render", gui, 0.666)
2368 luxInt("yresolution", luxAttr(context, "sizeY"), 0, 8192, "Y", "height of the render", gui, 0.666)
2369 scale = luxProp(scn, "film.scale", "100 %")
2370 luxOption("", scale, ["400 %", "200 %", "100 %", "75 %", "50 %", "25 %"], "scale", "scale resolution", gui, 0.666)
2371 scale = int(scale.get()[:-1])
2372 # render region option
2373 if context.borderRender:
2374 (x1,y1,x2,y2) = context.border
2375 if (x1==x2) and (y1==y2): print "WARNING: empty render-region, use SHIFT-B to set render region in Blender."
2376 str += "\n \"integer xresolution\" [%d] \n \"integer yresolution\" [%d]"%(luxAttr(context, "sizeX").get()*scale/100*(x2-x1), luxAttr(context, "sizeY").get()*scale/100*(y2-y1))
2378 str += "\n \"integer xresolution\" [%d] \n \"integer yresolution\" [%d]"%(luxAttr(context, "sizeX").get()*scale/100, luxAttr(context, "sizeY").get()*scale/100)
2380 if gui: gui.newline(" Halt:")
2381 str += luxInt("haltspp", luxProp(scn, "haltspp", 0), 0, 32768, "haltspp", "Stop rendering after specified amount of samples per pixel / 0 = never halt", gui)
2382 palpha = luxProp(scn, "film.premultiplyalpha", "false")
2383 str += luxBool("premultiplyalpha", palpha, "premultiplyalpha", "Pre multiply film alpha channel during normalization", gui)
2385 if gui: gui.newline(" Tonemap:")
2386 tonemapkernel = luxProp(scn, "film.tonemapkernel", "reinhard")
2387 str += luxOption("tonemapkernel", tonemapkernel, ["reinhard", "linear", "contrast", "maxwhite"], "Tonemapping Kernel", "Select the tonemapping kernel to use", gui, 2.0)
2388 if tonemapkernel.get() == "reinhard":
2389 autoywa = luxProp(scn, "film.reinhard.autoywa", "true")
2390 #str += luxBool("reinhard_autoywa", autoywa, "auto Ywa", "Automatically determine World Adaption Luminance", gui)
2391 if autoywa.get() == "false":
2392 str += luxFloat("reinhard_ywa", luxProp(scn, "film.reinhard.ywa", 0.1), 0.001, 1.0, "Ywa", "Display/World Adaption Luminance", gui)
2393 str += luxFloat("reinhard_prescale", luxProp(scn, "film.reinhard.prescale", 1.0), 0.0, 10.0, "preScale", "Image scale before tonemap operator", gui)
2394 str += luxFloat("reinhard_postscale", luxProp(scn, "film.reinhard.postscale", 1.2), 0.0, 10.0, "postScale", "Image scale after tonemap operator", gui)
2395 str += luxFloat("reinhard_burn", luxProp(scn, "film.reinhard.burn", 6.0), 0.1, 12.0, "burn", "12.0: no burn out, 0.1 lot of burn out", gui)
2396 elif tonemapkernel.get() == "linear":
2397 str += luxFloat("linear_sensitivity", luxProp(scn, "film.linear.sensitivity", 50.0), 0.0, 1000.0, "sensitivity", "Adaption/Sensitivity", gui)
2398 str += luxFloat("linear_exposure", luxProp(scn, "film.linear.exposure", 1.0), 0.001, 1.0, "exposure", "Exposure duration in seconds", gui)
2399 str += luxFloat("linear_fstop", luxProp(scn, "film.linear.fstop", 2.8), 0.1, 64.0, "Fstop", "F-Stop", gui)
2400 str += luxFloat("linear_gamma", luxProp(scn, "film.linear.gamma", 1.0), 0.0, 8.0, "gamma", "Tonemap operator gamma correction", gui)
2401 elif tonemapkernel.get() == "contrast":
2402 str += luxFloat("contrast_ywa", luxProp(scn, "film.contrast.ywa", 0.1), 0.001, 1.0, "Ywa", "Display/World Adaption Luminance", gui)
2404 if gui: gui.newline(" Display:")
2405 str += luxInt("displayinterval", luxProp(scn, "film.displayinterval", 12), 4, 3600, "interval", "Set display Interval (seconds)", gui)
2407 if gui: gui.newline(" Write:")
2408 str += luxInt("writeinterval", luxProp(scn, "film.writeinterval", 120), 12, 3600, "interval", "Set display Interval (seconds)", gui)
2410 # Image File Outputs
2412 # LDR clamping method
2413 if gui: gui.newline(" Clamping:")
2414 ldrclampmethod = luxProp(scn, "film.ldr_clamp_method", "lum")
2415 str += luxOption("ldr_clamp_method", ldrclampmethod, ["lum", "hue", "cut"], "LDR clamping", "Method to clamp high luminance values for LDR output", gui, 0.5)
2416 if gui: gui.newline()
2419 saveexr = luxProp(scn, "film.write_exr", "false")
2420 str += luxCollapse("write_exr", saveexr, "OpenEXR Output", "Enable OpenEXR output", gui, 2.0)
2422 if saveexr.get() == "true":
2423 if gui: gui.newline(" OpenEXR:")
2425 exrchannels = luxProp(scn, "film.write_exr_channels", "RGBA")
2426 str += luxOption("write_exr_channels", exrchannels, ["Y", "YA", "RGB", "RGBA"], "Channels", "Select channels type to write", gui, 0.5)
2427 exrres = luxProp(scn, "film.write_exr_halftype", "true")
2428 str += luxBool("write_exr_halftype", exrres, "16bit Half", "Enable 16bit Half resolution output, otherwise 32bit float", gui, 0.5)
2429 exrcompression = luxProp(scn, "film.write_exr_compression", "PIZ (lossless)")
2430 str += luxOption("write_exr_compressiontype", exrcompression, ["RLE (lossless)", "PIZ (lossless)", "ZIP (lossless)", "Pxr24 (lossy)", "None"], "Compression", "Select OpenEXR Compression algorithm to use", gui, 1.0)
2432 exrimaging = luxProp(scn, "film.write_exr_imaging", "true")
2433 str += luxBool("write_exr_applyimaging", exrimaging, "Apply Imaging/Tonemapping", "Apply Imaging and Tonemapping pipeline", gui, 1.2)
2435 if exrimaging.get()=="true":
2436 exrgamutclamp = luxProp(scn, "film.write_exr_gamutclamp", "true")
2437 str += luxBool("write_exr_gamutclamp", exrgamutclamp, "Gamut Clamp", "Clamp out of gamut (bright) pixel values", gui, 0.8)
2439 if gui: gui.newline()
2441 exrZ = luxProp(scn, "film.write_exr_Z", "true")
2442 str += luxBool("write_exr_ZBuf", exrZ, "ZBuf", "Enable Z Depth Buffer channel", gui, 0.8)
2443 if exrZ.get() == "true":
2444 exrZNormalize = luxProp(scn, "film.write_exr_ZNorm", "None")
2445 str += luxOption("write_exr_zbuf_normalizationtype", exrZNormalize, ["Camera Start/End clip", "Min/Max", "None"], "ZBuf Normalization", "Select type of normalization to use for Zbuf Depth Map", gui, 1.2)
2448 savepng = luxProp(scn, "film.write_png", "true")
2449 str += luxCollapse("write_png", savepng, "PNG Output", "Enable PNG (Portable Network Graphics) output", gui, 2.0)
2451 if savepng.get() == "true":
2452 if gui: gui.newline(" PNG:")
2453 pngchannels = luxProp(scn, "film.write_png_channels", "RGB")
2454 str += luxOption("write_png_channels", pngchannels, ["Y", "YA", "RGB", "RGBA"], "Channels", "Select channels type to write", gui, 0.5)
2455 png16bit = luxProp(scn, "film.write_png_16bit", "false")
2456 str += luxBool("write_png_16bit", png16bit, "16bit", "Enable 16bits per channel resolution PNG output", gui, 0.5)
2457 pnggamutclamp = luxProp(scn, "film.write_png_gamutclamp", "true")
2458 str += luxBool("write_png_gamutclamp", pnggamutclamp, "Gamut Clamp", "Clamp out of gamut (bright) pixel values", gui, 1.0)
2461 #pngZ = luxProp(scn, "film.write_png_ZBuf", "false")
2462 #str += luxBool("write_png_ZBuf", pngZ, "ZBuf (Separate)", "Enable Z Depth Buffer channel", gui, 0.8)
2463 #if pngZ.get() == "true":
2464 # pngZNormalize = luxProp(scn, "film.write_png_ZNorm", "Min/Max")
2465 # str += luxOption("write_png_zbuf_normalizationtype", pngZNormalize, ["Camera Start/End clip", "Min/Max", "None"], "ZBuf Normalization", "Select type of normalization to use for Zbuf Depth Map", gui, 1.2)
2468 savetga = luxProp(scn, "film.write_tga", "false")
2469 str += luxCollapse("write_tga", savetga, "TGA Output", "Enable TGA output", gui, 2.0)
2471 if savetga.get() == "true":
2472 if gui: gui.newline(" TGA:")
2473 tgachannels = luxProp(scn, "film.write_tga_channels", "RGB")
2474 str += luxOption("write_tga_channels", tgachannels, ["Y", "RGB", "RGBA"], "Channels", "Select channels type to write", gui, 0.5)
2475 tgagamutclamp = luxProp(scn, "film.write_tga_gamutclamp", "true")
2476 str += luxBool("write_tga_gamutclamp", tgagamutclamp, "Gamut Clamp", "Clamp out of gamut (bright) pixel values", gui, 1.5)
2479 #tgaZ = luxProp(scn, "film.write_tga_ZBuf", "false")
2480 #str += luxBool("write_tga_ZBuf", tgaZ, "ZBuf (Separate)", "Enable Z Depth Buffer channel", gui, 0.8)
2481 #if tgaZ.get() == "true":
2482 # tgaZNormalize = luxProp(scn, "film.write_tga_ZNorm", "Min/Max")
2483 # str += luxOption("write_tga_zbuf_normalizationtype", tgaZNormalize, ["Camera Start/End clip", "Min/Max", "None"], "ZBuf Normalization", "Select type of normalization to use for Zbuf Depth Map", gui, 1.2)
2486 # override output image dir in case of command line batch mode
2487 overrideop = luxProp(scn, "overrideoutputpath", "")
2488 if overrideop.get() != "":
2489 filebase = os.path.splitext(os.path.basename(Blender.Get('filename')))[0]
2490 filename = overrideop.get() + "/" + filebase + "-%05d" % (Blender.Get('curframe'))
2491 str += "\n \"string filename\" [\"%s\"]"%(filename)
2493 fn = luxProp(scn, "filename", "default-%05d" % (Blender.Get('curframe')))
2494 str += luxString("filename", fn, "File name", "save file name", None)
2496 if gui: gui.newline(" Resume:")
2497 resumeflm = luxProp(scn, "film.write_resume_flm", "false")
2498 str += luxBool("write_resume_flm", resumeflm, "Write/Use FLM", "Write a resume fleximage .flm file, or resume rendering if it already exists", gui)
2499 restartflm = luxProp(scn, "film.restart_resume_flm", "true")
2500 str += luxBool("restart_resume_flm", restartflm, "Restart/Erase", "Restart with a black flm, even it a previous flm exists", gui)
2501 if gui: gui.newline(" Reject:")
2502 str += luxInt("reject_warmup", luxProp(scn, "film.reject_warmup", 128), 0, 32768, "warmup_spp", "Specify amount of samples per pixel for high intensity rejection", gui)
2503 debugmode = luxProp(scn, "film.debug", "false")
2504 str += luxBool("debug", debugmode, "debug", "Turn on debug reporting and switch off reject", gui)
2507 if gui: gui.newline(" Colorspace:")
2509 cspaceusepreset = luxProp(scn, "film.colorspaceusepreset", "true")
2510 luxBool("colorspaceusepreset", cspaceusepreset, "Preset", "Select from a list of predefined presets", gui, 0.4)
2512 # Default values for 'sRGB - HDTV (ITU-R BT.709-5)'
2513 cspacewhiteX = luxProp(scn, "film.cspacewhiteX", 0.314275)
2514 cspacewhiteY = luxProp(scn, "film.cspacewhiteY", 0.329411)
2515 cspaceredX = luxProp(scn, "film.cspaceredX", 0.63)
2516 cspaceredY = luxProp(scn, "film.cspaceredY", 0.34)
2517 cspacegreenX = luxProp(scn, "film.cspacegreenX", 0.31)
2518 cspacegreenY = luxProp(scn, "film.cspacegreenY", 0.595)
2519 cspaceblueX = luxProp(scn, "film.cspaceblueX", 0.155)
2520 cspaceblueY = luxProp(scn, "film.cspaceblueY", 0.07)
2521 gamma = luxProp(scn, "film.gamma", 2.2)
2523 if(cspaceusepreset.get() == "true"):
2525 cspace = luxProp(scn, "film.colorspace", "sRGB - HDTV (ITU-R BT.709-5)")
2526 cspaces = ["sRGB - HDTV (ITU-R BT.709-5)", "ROMM RGB", "Adobe RGB 98", "Apple RGB", "NTSC (FCC 1953, ITU-R BT.470-2 System M)", "NTSC (1979) (SMPTE C, SMPTE-RP 145)", "PAL/SECAM (EBU 3213, ITU-R BT.470-6)", "CIE (1931) E"]
2527 luxOption("colorspace", cspace, cspaces, "Colorspace", "select output working colorspace", gui, 1.6)
2529 if cspace.get()=="ROMM RGB":
2530 cspacewhiteX.set(0.346); cspacewhiteY.set(0.359) # D50
2531 cspaceredX.set(0.7347); cspaceredY.set(0.2653)
2532 cspacegreenX.set(0.1596); cspacegreenY.set(0.8404)
2533 cspaceblueX.set(0.0366); cspaceblueY.set(0.0001)
2534 elif cspace.get()=="Adobe RGB 98":
2535 cspacewhiteX.set(0.313); cspacewhiteY.set(0.329) # D65
2536 cspaceredX.set(0.64); cspaceredY.set(0.34)
2537 cspacegreenX.set(0.21); cspacegreenY.set(0.71)
2538 cspaceblueX.set(0.15); cspaceblueY.set(0.06)
2539 elif cspace.get()=="Apple RGB":
2540 cspacewhiteX.set(0.313); cspacewhiteY.set(0.329) # D65
2541 cspaceredX.set(0.625); cspaceredY.set(0.34)
2542 cspacegreenX.set(0.28); cspacegreenY.set(0.595)
2543 cspaceblueX.set(0.155); cspaceblueY.set(0.07)
2544 elif cspace.get()=="NTSC (FCC 1953, ITU-R BT.470-2 System M)":
2545 cspacewhiteX.set(0.310); cspacewhiteY.set(0.316) # C
2546 cspaceredX.set(0.67); cspaceredY.set(0.33)
2547 cspacegreenX.set(0.21); cspacegreenY.set(0.71)
2548 cspaceblueX.set(0.14); cspaceblueY.set(0.08)
2549 elif cspace.get()=="NTSC (1979) (SMPTE C, SMPTE-RP 145)":
2550 cspacewhiteX.set(0.313); cspacewhiteY.set(0.329) # D65
2551 cspaceredX.set(0.63); cspaceredY.set(0.34)
2552 cspacegreenX.set(0.31); cspacegreenY.set(0.595)
2553 cspaceblueX.set(0.155); cspaceblueY.set(0.07)
2554 elif cspace.get()=="PAL/SECAM (EBU 3213, ITU-R BT.470-6)":
2555 cspacewhiteX.set(0.313); cspacewhiteY.set(0.329) # D65
2556 cspaceredX.set(0.64); cspaceredY.set(0.33)
2557 cspacegreenX.set(0.29); cspacegreenY.set(0.60)
2558 cspaceblueX.set(0.15); cspaceblueY.set(0.06)
2559 elif cspace.get()=="CIE (1931) E":
2560 cspacewhiteX.set(0.333); cspacewhiteY.set(0.333) # E
2561 cspaceredX.set(0.7347); cspaceredY.set(0.2653)
2562 cspacegreenX.set(0.2738); cspacegreenY.set(0.7174)
2563 cspaceblueX.set(0.1666); cspaceblueY.set(0.0089)
2565 whitepointusecspace = luxProp(scn, "film.whitepointusecolorspace", "true")
2566 luxBool("whitepointusecolorspace", whitepointusecspace, "Colorspace Whitepoint", "Use default whitepoint for selected colorspace", gui, 1.0)
2567 gammausecspace = luxProp(scn, "film.gammausecolorspace", "true")
2568 luxBool("gammausecolorspace", gammausecspace, "Colorspace Gamma", "Use default output gamma for selected colorspace", gui, 1.0)
2570 if(whitepointusecspace.get() == "false"):
2571 if gui: gui.newline(" Whitepoint:")
2572 whitepointusepreset = luxProp(scn, "film.whitepointusepreset", "true")
2573 luxBool("whitepointusepreset", whitepointusepreset, "Preset", "Select from a list of predefined presets", gui, 0.4)
2575 if(whitepointusepreset.get() == "true"):
2576 whitepointpresets = ["E", "D50", "D55", "D65", "D75", "A", "B", "C", "9300", "F2", "F7", "F11"]
2577 whitepointpreset = luxProp(scn, "film.whitepointpreset", "D65")
2578 luxOption("whitepointpreset", whitepointpreset, whitepointpresets, " PRESET", "select Whitepoint preset", gui, 1.6)
2580 if whitepointpreset.get()=="E": cspacewhiteX.set(0.333); cspacewhiteY.set(0.333)
2581 elif whitepointpreset.get()=="D50": cspacewhiteX.set(0.346); cspacewhiteY.set(0.359)
2582 elif whitepointpreset.get()=="D55": cspacewhiteX.set(0.332); cspacewhiteY.set(0.347)
2583 elif whitepointpreset.get()=="D65": cspacewhiteX.set(0.313); cspacewhiteY.set(0.329)
2584 elif whitepointpreset.get()=="D75": cspacewhiteX.set(0.299); cspacewhiteY.set(0.315)
2585 elif whitepointpreset.get()=="A": cspacewhiteX.set(0.448); cspacewhiteY.set(0.407)
2586 elif whitepointpreset.get()=="B": cspacewhiteX.set(0.348); cspacewhiteY.set(0.352)
2587 elif whitepointpreset.get()=="C": cspacewhiteX.set(0.310); cspacewhiteY.set(0.316)
2588 elif whitepointpreset.get()=="9300": cspacewhiteX.set(0.285); cspacewhiteY.set(0.293)
2589 elif whitepointpreset.get()=="F2": cspacewhiteX.set(0.372); cspacewhiteY.set(0.375)
2590 elif whitepointpreset.get()=="F7": cspacewhiteX.set(0.313); cspacewhiteY.set(0.329)
2591 elif whitepointpreset.get()=="F11": cspacewhiteX.set(0.381); cspacewhiteY.set(0.377)
2593 luxFloat("white X", cspacewhiteX, 0.0, 1.0, "white X", "Whitepoint X weight", gui, 0.8)
2594 luxFloat("white Y", cspacewhiteY, 0.0, 1.0, "white Y", "Whitepoint Y weight", gui, 0.8)
2596 if(gammausecspace.get() == "false"):
2597 if gui: gui.newline(" Gamma:")
2598 luxFloat("gamma", gamma, 0.1, 6.0, "gamma", "Output and RGC Gamma", gui, 2.0)
2601 luxFloat("white X", cspacewhiteX, 0.0, 1.0, "white X", "Whitepoint X weight", gui, 0.8)
2602 luxFloat("white Y", cspacewhiteY, 0.0, 1.0, "white Y", "Whitepoint Y weight", gui, 0.8)
2603 luxFloat("red X", cspaceredX, 0.0, 1.0, "red X", "Red component X weight", gui, 1.0)
2604 luxFloat("red Y", cspaceredY, 0.0, 1.0, "red Y", "Red component Y weight", gui, 1.0)
2605 luxFloat("green X", cspacegreenX, 0.0, 1.0, "green X", "Green component X weight", gui, 1.0)
2606 luxFloat("green Y", cspacegreenY, 0.0, 1.0, "green Y", "Green component Y weight", gui, 1.0)
2607 luxFloat("blue X", cspaceblueX, 0.0, 1.0, "blue X", "Blue component X weight", gui, 1.0)
2608 luxFloat("blue Y", cspaceblueY, 0.0, 1.0, "blue Y", "Blue component Y weight", gui, 1.0)
2609 if gui: gui.newline(" Gamma:")
2610 luxFloat("gamma", gamma, 0.1, 6.0, "gamma", "Output and RGC Gamma", gui, 2.0)
2612 str += "\n \"float colorspace_white\" [%f %f]"%(cspacewhiteX.get(), cspacewhiteY.get())
2613 str += "\n \"float colorspace_red\" [%f %f]"%(cspaceredX.get(), cspaceredY.get())
2614 str += "\n \"float colorspace_green\" [%f %f]"%(cspacegreenX.get(), cspacegreenY.get())
2615 str += "\n \"float colorspace_blue\" [%f %f]"%(cspaceblueX.get(), cspaceblueY.get())
2616 str += "\n \"float gamma\" [%f]"%(gamma.get())
2621 def luxPixelFilter(scn, gui=None):
2622 global icon_c_filter
2625 filtertype = luxProp(scn, "pixelfilter.type", "mitchell")
2626 str = luxIdentifier("PixelFilter", filtertype, ["box", "gaussian", "mitchell", "sinc", "triangle"], "FILTER", "select pixel filter type", gui, icon_c_filter)
2629 parammodeadvanced = luxProp(scn, "parammodeadvanced", "false")
2630 showadvanced = luxProp(scn, "pixelfilter.showadvanced", parammodeadvanced.get())
2631 luxBool("advanced", showadvanced, "Advanced", "Show advanced options", gui, 0.6)
2633 showhelp = luxProp(scn, "pixelfilter.showhelp", "false")
2634 luxHelp("help", showhelp, "Help", "Show Help Information", gui, 0.4)
2636 if filtertype.get() == "box":
2637 if showadvanced.get()=="true":
2638 # Advanced parameters
2639 if gui: gui.newline()
2640 str += luxFloat("xwidth", luxProp(scn, "pixelfilter.box.xwidth", 0.5), 0.0, 10.0, "x-width", "Width of the filter in the x direction", gui)
2641 str += luxFloat("ywidth", luxProp(scn, "pixelfilter.box.ywidth", 0.5), 0.0, 10.0, "y-width", "Width of the filter in the y direction", gui)
2642 if filtertype.get() == "gaussian":
2643 if showadvanced.get()=="true":
2644 # Advanced parameters
2645 if gui: gui.newline()
2646 str += luxFloat("xwidth", luxProp(scn, "pixelfilter.gaussian.xwidth", 2.0), 0.0, 10.0, "x-width", "Width of the filter in the x direction", gui)
2647 str += luxFloat("ywidth", luxProp(scn, "pixelfilter.gaussian.ywidth", 2.0), 0.0, 10.0, "y-width", "Width of the filter in the y direction", gui)
2648 if gui: gui.newline()
2649 str += luxFloat("alpha", luxProp(scn, "pixelfilter.gaussian.alpha", 2.0), 0.0, 10.0, "alpha", "Gaussian rate of falloff. Lower values give blurrier images", gui)
2650 if filtertype.get() == "mitchell":
2651 if showadvanced.get()=="false":
2652 # Default parameters
2653 if gui: gui.newline("", 8, 0, None, [0.4,0.4,0.4])
2654 slidval = luxProp(scn, "pixelfilter.mitchell.sharp", 0.25)
2655 luxFloat("sharpness", slidval, 0.0, 1.0, "sharpness", "Specify amount between blurred (left) and sharp/ringed (right)", gui, 2.0, 1)
2656 # rule: B + 2*c = 1.0
2657 C = slidval.getFloat() * 0.5
2658 B = 1.0 - slidval.getFloat()
2659 str += "\n \"float B\" [%f]"%(B)
2660 str += "\n \"float C\" [%f]"%(C)
2662 if showadvanced.get()=="true":
2663 # Advanced parameters
2664 if gui: gui.newline()
2665 str += luxFloat("xwidth", luxProp(scn, "pixelfilter.mitchell.xwidth", 2.0), 0.0, 10.0, "x-width", "Width of the filter in the x direction", gui)
2666 str += luxFloat("ywidth", luxProp(scn, "pixelfilter.mitchell.ywidth", 2.0), 0.0, 10.0, "y-width", "Width of the filter in the y direction", gui)
2667 if gui: gui.newline()
2669 optmode = luxProp(scn, "pixelfilter.mitchell.optmode", "slider")
2670 luxOption("optmode", optmode, ["slider", "preset", "manual"], "Mode", "Mode of configuration", gui, 0.5)
2672 if(optmode.get() == "slider"):
2673 slidval = luxProp(scn, "pixelfilter.mitchell.sharp", 0.33)
2674 luxFloat("sharpness", slidval, 0.0, 1.0, "sharpness", "Specify amount between blurred (left) and sharp/ringed (right)", gui, 1.5, 1)
2675 # rule: B + 2*c = 1.0
2676 C = slidval.getFloat() * 0.5
2677 B = 1.0 - slidval.getFloat()
2678 str += "\n \"float B\" [%f]"%(B)
2679 str += "\n \"float C\" [%f]"%(C)
2680 elif(optmode.get() == "preset"):
2681 print "not implemented"
2683 str += luxFloat("B", luxProp(scn, "pixelfilter.mitchell.B", 0.3333), 0.0, 1.0, "B", "Specify the shape of the Mitchell filter. Often best result is when B + 2C = 1", gui, 0.75)
2684 str += luxFloat("C", luxProp(scn, "pixelfilter.mitchell.C", 0.3333), 0.0, 1.0, "C", "Specify the shape of the Mitchell filter. Often best result is when B + 2C = 1", gui, 0.75)
2686 if filtertype.get() == "sinc":
2687 if showadvanced.get()=="true":
2688 # Advanced parameters
2689 if gui: gui.newline()
2690 str += luxFloat("xwidth", luxProp(scn, "pixelfilter.sinc.xwidth", 4.0), 0.0, 10.0, "x-width", "Width of the filter in the x direction", gui)
2691 str += luxFloat("ywidth", luxProp(scn, "pixelfilter.sinc.ywidth", 4.0), 0.0, 10.0, "y-width", "Width of the filter in the y direction", gui)
2692 if gui: gui.newline()
2693 str += luxFloat("tau", luxProp(scn, "pixelfilter.sinc.tau", 3.0), 0.0, 10.0, "tau", "Permitted number of cycles of the sinc function before it is clamped to zero", gui)
2694 if filtertype.get() == "triangle":
2695 if showadvanced.get()=="true":
2696 # Advanced parameters
2697 if gui: gui.newline()
2698 str += luxFloat("xwidth", luxProp(scn, "pixelfilter.triangle.xwidth", 2.0), 0.0, 10.0, "x-width", "Width of the filter in the x direction", gui)
2699 str += luxFloat("ywidth", luxProp(scn, "pixelfilter.triangle.ywidth", 2.0), 0.0, 10.0, "y-width", "Width of the filter in the y direction", gui)
2702 def luxSampler(scn, gui=None):
2703 global icon_c_sampler, icon_help
2706 samplertype = luxProp(scn, "sampler.type", "metropolis")
2707 str = luxIdentifier("Sampler", samplertype, ["metropolis", "erpt", "lowdiscrepancy", "random"], "SAMPLER", "select sampler type", gui, icon_c_sampler)
2710 parammodeadvanced = luxProp(scn, "parammodeadvanced", "false")
2711 showadvanced = luxProp(scn, "sampler.showadvanced", parammodeadvanced.get())
2712 luxBool("advanced", showadvanced, "Advanced", "Show advanced options", gui, 0.6)
2714 showhelp = luxProp(scn, "sampler.showhelp", "false")
2715 luxHelp("help", showhelp, "Help", "Show Help Information", gui, 0.4)
2717 if samplertype.get() == "metropolis":
2718 if showadvanced.get()=="false":
2719 # Default parameters
2720 if gui: gui.newline(" Mutation:", 8, 0, None, [0.4,0.4,0.4])
2721 strength = luxProp(scn, "sampler.metro.strength", 0.6)
2722 luxFloat("strength", strength, 0.0, 1.0, "strength", "Mutation Strength (lmprob = 1.0-strength)", gui, 2.0, 1)
2723 v = 1.0 - strength.get()
2724 str += "\n \"float largemutationprob\" [%f]"%v
2725 if showadvanced.get()=="true":
2726 # Advanced parameters
2727 if gui: gui.newline(" Mutation:")
2728 str += luxFloat("largemutationprob", luxProp(scn, "sampler.metro.lmprob", 0.4), 0.0, 1.0, "LM.prob.", "Probability of generating a large sample (mutation)", gui)
2729 str += luxInt("maxconsecrejects", luxProp(scn, "sampler.metro.maxrejects", 512), 0, 32768, "max.rejects", "number of consecutive rejects before a new mutation is forced", gui)
2730 if gui: gui.newline(" Screen:")
2731 str += luxInt("initsamples", luxProp(scn, "sampler.metro.initsamples", 262144), 1, 1000000, "initsamples", "", gui)
2732 str += luxBool("usevariance",luxProp(scn, "sampler.metro.usevariance", "false"), "usevariance", "Accept based on variance", gui, 1.0)
2734 if showhelp.get()=="true":
2735 if gui: gui.newline(" Description:", 8, 0, icon_help, [0.4,0.5,0.56])
2736 r = gui.getRect(2,1); BGL.glRasterPos2i(r[0],r[1]+5)
2737 Draw.Text("A Metropolis-Hastings mutating sampler which implements MLT", 'small')
2739 if samplertype.get() == "erpt":
2740 str += luxInt("initsamples", luxProp(scn, "sampler.erpt.initsamples", 100000), 1, 1000000, "initsamples", "", gui)
2741 if gui: gui.newline(" Mutation:")
2742 str += luxInt("chainlength", luxProp(scn, "sampler.erpt.chainlength", 512), 1, 32768, "chainlength", "The number of mutations from a given seed", gui)
2743 if gui: gui.newline()
2744 str += luxInt("stratawidth", luxProp(scn, "sampler.erpt.stratawidth", 256), 1, 32768, "stratawidth", "The number of x/y strata for stratified sampling of seeds", gui)
2746 if samplertype.get() == "lowdiscrepancy":
2747 if gui: gui.newline(" PixelSampler:")
2748 str += luxOption("pixelsampler", luxProp(scn, "sampler.lowdisc.pixelsampler", "lowdiscrepancy"), ["linear", "tile", "random", "vegas","lowdiscrepancy","hilbert"], "pixel-sampler", "select pixel-sampler", gui)
2749 str += luxInt("pixelsamples", luxProp(scn, "sampler.lowdisc.pixelsamples", 4), 1, 2048, "samples", "Average number of samples taken per pixel. More samples create a higher quality image at the cost of render time", gui)
2751 if samplertype.get() == "random":
2752 if gui: gui.newline(" PixelSampler:")
2753 str += luxOption("pixelsampler", luxProp(scn, "sampler.random.pixelsampler", "vegas"), ["linear", "tile", "random", "vegas","lowdiscrepancy","hilbert"], "pixel-sampler", "select pixel-sampler", gui)
2754 if gui: gui.newline()
2755 str += luxInt("xsamples", luxProp(scn, "sampler.random.xsamples", 2), 1, 512, "xsamples", "Allows you to specify how many samples per pixel are taking in the x direction", gui)
2756 str += luxInt("ysamples", luxProp(scn, "sampler.random.ysamples", 2), 1, 512, "ysamples", "Allows you to specify how many samples per pixel are taking in the y direction", gui)
2759 def luxSurfaceIntegrator(scn, gui=None):
2760 global icon_c_integrator
2763 integratortype = luxProp(scn, "sintegrator.type", "bidirectional")
2765 str = luxIdentifier("SurfaceIntegrator", integratortype, ["directlighting", "path", "bidirectional", "exphotonmap", "distributedpath", "igi" ], "INTEGRATOR", "select surface integrator type", gui, icon_c_integrator)
2768 parammodeadvanced = luxProp(scn, "parammodeadvanced", "false")
2769 showadvanced = luxProp(scn, "sintegrator.showadvanced", parammodeadvanced.get())
2770 luxBool("advanced", showadvanced, "Advanced", "Show advanced options", gui, 0.6)
2772 showhelp = luxProp(scn, "sintegrator.showhelp", "false")
2773 luxHelp("help", showhelp, "Help", "Show Help Information", gui, 0.4)
2775 if integratortype.get() == "directlighting":
2776 if showadvanced.get()=="false":
2777 # Default parameters
2778 if gui: gui.newline(" Depth:", 8, 0, None, [0.4,0.4,0.4])
2779 str += luxInt("maxdepth", luxProp(scn, "sintegrator.dlighting.maxdepth", 8), 0, 2048, "bounces", "The maximum recursion depth for ray casting", gui, 2.0)
2781 if showadvanced.get()=="true":
2782 # Advanced parameters
2783 str += luxOption("strategy", luxProp(scn, "sintegrator.dlighting.strategy", "auto"), ["one", "all", "auto"], "strategy", "select directlighting strategy", gui)
2784 if gui: gui.newline(" Depth:")
2785 str += luxInt("maxdepth", luxProp(scn, "sintegrator.dlighting.maxdepth", 8), 0, 2048, "max-depth", "The maximum recursion depth for ray casting", gui)
2786 if gui: gui.newline()
2788 if integratortype.get() == "path":
2789 if showadvanced.get()=="false":
2790 # Default parameters
2791 if gui: gui.newline(" Depth:", 8, 0, None, [0.4,0.4,0.4])
2792 str += luxInt("maxdepth", luxProp(scn, "sintegrator.path.maxdepth", 10), 0, 2048, "bounces", "The maximum recursion depth for ray casting", gui, 1.0)
2793 ienv = luxProp(scn, "sintegrator.path.ienvironment", "true")
2794 str += luxBool("includeenvironment", ienv, "Include Environment", "Enable/Disable rendering of environment lightsources", gui)
2796 if showadvanced.get()=="true":
2797 # Advanced parameters
2798 if gui: gui.newline(" Depth:")
2799 str += luxInt("maxdepth", luxProp(scn, "sintegrator.path.maxdepth", 10), 0, 2048, "maxdepth", "The maximum recursion depth for ray casting", gui)
2800 str += luxOption("strategy", luxProp(scn, "sintegrator.path.strategy", "auto"), ["one", "all", "auto"], "strategy", "select directlighting strategy", gui)
2801 if gui: gui.newline(" RR:")
2802 rrstrat = luxProp(scn, "sintegrator.path.rrstrategy", "efficiency")
2803 str += luxOption("rrstrategy", rrstrat, ["efficiency", "probability", "none"], "RR strategy", "select Russian Roulette path termination strategy", gui)
2804 if rrstrat.get() == "probability":
2805 str += luxFloat("rrcontinueprob", luxProp(scn, "sintegrator.path.rrcontinueprob", 0.65), 0.0, 1.0, "rrprob", "Russian roulette continue probability", gui)
2806 ienv = luxProp(scn, "sintegrator.path.ienvironment", "true")
2807 str += luxBool("includeenvironment", ienv, "Include Environment", "Enable/Disable rendering of environment lightsources", gui)
2809 if integratortype.get() == "bidirectional":
2810 if showadvanced.get()=="false":
2811 # Default parameters
2812 if gui: gui.newline(" Depth:", 8, 0, None, [0.4,0.4,0.4])
2813 bounces = luxProp(scn, "sintegrator.bidir.bounces", 16)
2814 luxInt("bounces", bounces, 5, 32, "bounces", "The maximum recursion depth for ray casting (in both directions)", gui, 2.0)
2815 str += "\n \"integer eyedepth\" [%i]\n"%bounces.get()
2816 str += " \"integer lightdepth\" [%i]"%bounces.get()
2818 if showadvanced.get()=="true":
2819 # Advanced parameters
2820 if gui: gui.newline(" Depth:")
2821 str += luxInt("eyedepth", luxProp(scn, "sintegrator.bidir.eyedepth", 16), 0, 2048, "eyedepth", "The maximum recursion depth for ray casting", gui)
2822 str += luxInt("lightdepth", luxProp(scn, "sintegrator.bidir.lightdepth", 16), 0, 2048, "lightdepth", "The maximum recursion depth for light ray casting", gui)
2823 str += luxOption("strategy", luxProp(scn, "sintegrator.bidir.strategy", "auto"), ["one", "all", "auto"], "strategy", "select directlighting strategy", gui)
2825 if integratortype.get() == "exphotonmap":
2826 if gui: gui.newline(" Render:")
2827 str += luxOption("renderingmode", luxProp(scn, "sintegrator.photonmap.renderingmode", "directlighting"), ["directlighting", "path"], "renderingmode", "select rendering mode", gui)
2828 str += luxOption("strategy", luxProp(scn, "sintegrator.photonmap.strategy", "auto"), ["one", "all", "auto"], "strategy", "select directlighting strategy", gui)
2829 str += luxInt("maxphotondepth", luxProp(scn, "sintegrator.photonmap.maxphotondepth", 10), 1, 1024, "maxphotondepth", "The maximum recursion depth of photon tracing", gui)
2830 str += luxInt("maxdepth", luxProp(scn, "sintegrator.photonmap.maxdepth", 6), 1, 1024, "maxdepth", "The maximum recursion depth of specular reflection and refraction", gui)
2831 str += luxFloat("maxdist", luxProp(scn, "sintegrator.photonmap.maxdist", 0.1), 0.0, 10.0, "maxdist", "The maximum distance between a point being shaded and a photon that can contribute to that point", gui)
2832 str += luxInt("nused", luxProp(scn, "sintegrator.photonmap.nused", 50), 0, 1000000, "nused", "The number of photons to use in density estimation", gui)
2834 if gui: gui.newline(" Photons:")
2835 str += luxInt("indirectphotons", luxProp(scn, "sintegrator.photonmap.idphotons", 200000), 0, 10000000, "indirect", "The number of photons to shoot for indirect lighting during preprocessing of the photon map", gui)
2836 str += luxInt("maxdirectphotons", luxProp(scn, "sintegrator.photonmap.maxdphotons", 1000000), 0, 10000000, "maxdirect", "The maximum number of photons to shoot for direct lighting during preprocessing of the photon map", gui)
2837 str += luxInt("causticphotons", luxProp(scn, "sintegrator.photonmap.cphotons", 20000), 0, 10000000, "caustic", "The number of photons to shoot for caustics during preprocessing of the photon map", gui)
2838 if gui: gui.newline(" FinalGather:")
2839 fg = luxProp(scn, "sintegrator.photonmap.fgather", "true")
2840 str += luxBool("finalgather", fg, "finalgather", "Enable use of final gather during rendering", gui)
2841 if fg.get() == "true":
2842 rrstrat = luxProp(scn, "sintegrator.photonmap.gatherrrstrategy", "efficiency")
2843 str += luxOption("gatherrrstrategy", rrstrat, ["efficiency", "probability", "none"], "RR strategy", "select Russian Roulette gather termination strategy", gui)
2844 str += luxInt("finalgathersamples", luxProp(scn, "sintegrator.photonmap.fgathers", 32), 1, 1024, "samples", "The number of finalgather samples to take per pixel during rendering", gui)
2845 str += luxFloat("gatherangle", luxProp(scn, "sintegrator.photonmap.gangle", 10.0), 0.0, 360.0, "gatherangle", "Angle for final gather", gui)
2846 if rrstrat.get() == "probability":
2847 str += luxFloat("gatherrrcontinueprob", luxProp(scn, "sintegrator.photonmap.gatherrrcontinueprob", 0.65), 0.0, 1.0, "rrcontinueprob", "Probability for russian roulette particle tracing termination", gui)
2849 if integratortype.get() == "distributedpath":
2850 str += luxOption("strategy", luxProp(scn, "sintegrator.distributedpath.strategy", "auto"), ["one", "all", "auto"], "strategy", "select directlighting strategy", gui)
2851 if gui: gui.newline(" Direct:")
2852 str += luxBool("directsampleall",luxProp(scn, "sintegrator.distributedpath.directsampleall", "true"), "Direct ALL", "Include diffuse direct light sample at first vertex", gui, 0.75)
2853 str += luxInt("directsamples", luxProp(scn, "sintegrator.distributedpath.directsamples", 1), 0, 1024, "s", "The number of direct light samples to take at the eye vertex", gui, 0.25)
2854 str += luxBool("indirectsampleall",luxProp(scn, "sintegrator.distributedpath.indirectsampleall", "false"), "Indirect ALL", "Include diffuse direct light sample at first vertex", gui, 0.75)
2855 str += luxInt("indirectsamples", luxProp(scn, "sintegrator.distributedpath.indirectsamples", 1), 0, 1024, "s", "The number of direct light samples to take at the remaining vertices", gui, 0.25)
2856 if gui: gui.newline(" Diffuse:")
2857 str += luxInt("diffusereflectdepth", luxProp(scn, "sintegrator.distributedpath.diffusereflectdepth", 3), 0, 2048, "Reflect", "The maximum recursion depth for diffuse reflection ray casting", gui, 0.5)
2858 str += luxInt("diffusereflectsamples", luxProp(scn, "sintegrator.distributedpath.diffusereflectsamples", 1), 0, 1024, "s", "The number of diffuse reflection samples to take at the eye vertex", gui, 0.25)
2859 str += luxInt("diffuserefractdepth", luxProp(scn, "sintegrator.distributedpath.diffuserefractdepth", 5), 0, 2048, "Refract", "The maximum recursion depth for diffuse refraction ray casting", gui, 0.5)
2860 str += luxInt("diffuserefractsamples", luxProp(scn, "sintegrator.distributedpath.diffuserefractsamples", 1), 0, 1024, "s", "The number of diffuse refraction samples to take at the eye vertex", gui, 0.25)
2861 str += luxBool("directdiffuse",luxProp(scn, "sintegrator.distributedpath.directdiffuse", "true"), "DL", "Include diffuse direct light sample at first vertex", gui, 0.25)
2862 str += luxBool("indirectdiffuse",luxProp(scn, "sintegrator.distributedpath.indirectdiffuse", "true"), "IDL", "Include diffuse indirect light sample at first vertex", gui, 0.25)
2863 if gui: gui.newline(" Glossy:")
2864 str += luxInt("glossyreflectdepth", luxProp(scn, "sintegrator.distributedpath.glossyreflectdepth", 2), 0, 2048, "Reflect", "The maximum recursion depth for glossy reflection ray casting", gui, 0.5)
2865 str += luxInt("glossyreflectsamples", luxProp(scn, "sintegrator.distributedpath.glossyreflectsamples", 1), 0, 1024, "s", "The number of glossy reflection samples to take at the eye vertex", gui, 0.25)
2866 str += luxInt("glossyrefractdepth", luxProp(scn, "sintegrator.distributedpath.glossyrefractdepth", 5), 0, 2048, "Refract", "The maximum recursion depth for glossy refraction ray casting", gui, 0.5)
2867 str += luxInt("glossyrefractsamples", luxProp(scn, "sintegrator.distributedpath.glossyrefractsamples", 1), 0, 1024, "s", "The number of glossy refraction samples to take at the eye vertex", gui, 0.25)
2868 str += luxBool("directglossy",luxProp(scn, "sintegrator.distributedpath.directglossy", "true"), "DL", "Include glossy direct light sample at first vertex", gui, 0.25)
2869 str += luxBool("indirectglossy",luxProp(scn, "sintegrator.distributedpath.indirectglossy", "true"), "IDL", "Include glossy indirect light sample at first vertex", gui, 0.25)
2870 if gui: gui.newline(" Specular:")
2871 str += luxInt("specularreflectdepth", luxProp(scn, "sintegrator.distributedpath.specularreflectdepth", 3), 0, 2048, "Reflect", "The maximum recursion depth for specular reflection ray casting", gui, 1.0)
2872 str += luxInt("specularrefractdepth", luxProp(scn, "sintegrator.distributedpath.specularrefractdepth", 5), 0, 2048, "Refract", "The maximum recursion depth for specular refraction ray casting", gui, 1.0)
2873 #if gui: gui.newline(" Caustics:")
2874 #str += luxBool("causticsondiffuse",luxProp(scn, "sintegrator.distributedpath.causticsondiffuse", "false"), "Caustics on Diffuse", "Enable caustics on diffuse surfaces (warning: might generate bright pixels)", gui, 1.0)
2875 #str += luxBool("causticsonglossy",luxProp(scn, "sintegrator.distributedpath.causticsonglossy", "true"), "Caustics on Glossy", "Enable caustics on glossy surfaces (warning: might generate bright pixels)", gui, 1.0)
2877 usereject = luxProp(scn, "sintegrator.distributedpath.usereject", "false")
2878 luxCollapse("usereject", usereject, "Rejection", "Enable Rejection system to eliminate bright contributions", gui, 2.0)
2880 if usereject.get()=="true":
2881 if gui: gui.newline(" Diffuse:")
2883 diffusereflectreject = luxProp(scn, "sintegrator.distributedpath.difreflreject", "false")
2884 str += luxBool("diffusereflectreject", diffusereflectreject, "Reflect", "Enable Rejection for Diffuse Reflection", gui, 0.4)
2885 if diffusereflectreject.get()=="true":
2886 str += luxFloat("diffusereflectreject_threshold", luxProp(scn, "sintegrator.distributedpath.difreflrejectthr", 10.0), 0.01, 10.0, "Thr", "The Average Threshold to reject", gui, 0.6)
2888 diffuserefractreject = luxProp(scn, "sintegrator.distributedpath.difrefrreject", "false")
2889 str += luxBool("diffuserefractreject", diffuserefractreject, "Refract", "Enable Rejection for Diffuse Refraction", gui, 0.4)
2890 if diffuserefractreject.get()=="true":
2891 str += luxFloat("diffuserefractreject_threshold", luxProp(scn, "sintegrator.distributedpath.difrefrrejectthr", 10.0), 0.01, 10.0, "Thr", "The Average Threshold to reject", gui, 0.6)
2893 if gui: gui.newline(" Glossy:")
2895 glossyreflectreject = luxProp(scn, "sintegrator.distributedpath.glosreflreject", "false")
2896 str += luxBool("glossyreflectreject", glossyreflectreject, "Reflect", "Enable Rejection for Glossy Reflection", gui, 0.4)
2897 if glossyreflectreject.get()=="true":
2898 str += luxFloat("glossyreflectreject_threshold", luxProp(scn, "sintegrator.distributedpath.glosreflrejectthr", 10.0), 0.01, 10.0, "Thr", "The Average Threshold to reject", gui, 0.6)
2900 glossyrefractreject = luxProp(scn, "sintegrator.distributedpath.glosrefrreject", "false")
2901 str += luxBool("glossyrefractreject", glossyrefractreject, "Refract", "Enable Rejection for Glossy Refraction", gui, 0.4)
2902 if glossyrefractreject.get()=="true":
2903 str += luxFloat("glossyrefractreject_threshold", luxProp(scn, "sintegrator.distributedpath.glosrefrrejectthr", 10.0), 0.01, 10.0, "Thr", "The Average Threshold to reject", gui, 0.6)
2905 if integratortype.get() == "igi":
2906 if gui: gui.newline(" Depth:", 8, 0, None, [0.4,0.4,0.4])
2907 depth = luxProp(scn, "sintegrator.igi.maxdepth", 5)
2908 luxInt("maxdepth", depth, 1, 32, "maxdepth", "The maximum recursion depth for ray casting", gui, 2.0)
2909 if showadvanced.get()=="true":
2910 # Advanced parameters
2911 if gui: gui.newline(" VLights:")
2912 str += luxInt("nsets", luxProp(scn, "sintegrator.igi.nsets", 4), 1, 100, "nsets", "The number of virtual lights sets", gui)
2913 str += luxInt("nlights", luxProp(scn, "sintegrator.igi.nlights", 64), 1, 1000, "nlights", "The number of light paths per light set", gui)
2914 str += luxFloat("strategy", luxProp(scn, "sintegrator.igi.mindist", 0.1), 0.01, 10.0, "mindist", "The minimal distance to a virtual light to take it into account", gui)
2919 def luxVolumeIntegrator(scn, gui=None):
2920 global icon_c_volumeintegrator
2923 integratortype = luxProp(scn, "vintegrator.type", "single")
2924 str = luxIdentifier("VolumeIntegrator", integratortype, ["emission", "single"], "VOLUME INT", "select volume integrator type", gui, icon_c_volumeintegrator)
2925 if integratortype.get() == "emission":
2926 str += luxFloat("stepsize", luxProp(scn, "vintegrator.emission.stepsize", 1.0), 0.0, 100.0, "stepsize", "Stepsize for volumes", gui)
2927 if integratortype.get() == "single":
2928 str += luxFloat("stepsize", luxProp(scn, "vintegrator.emission.stepsize", 1.0), 0.0, 100.0, "stepsize", "Stepsize for volumes", gui)
2931 def luxEnvironment(scn, gui=None):
2932 global icon_c_environment
2935 envtype = luxProp(scn, "env.type", "infinite")
2936 lsstr = luxIdentifier("LightSource", envtype, ["none", "infinite", "sunsky"], "ENVIRONMENT", "select environment light type", gui, icon_c_environment)
2937 if gui: gui.newline()
2940 if envtype.get() != "none":
2942 if envtype.get() in ["infinite", "sunsky"]:
2943 env_lg = luxProp(scn, "env.lightgroup", "default")
2944 luxString("env.lightgroup", env_lg, "lightgroup", "Environment light group", gui)
2945 if luxProp(scn, "nolg", "false").get()!="true":
2946 lsstr = '\nLightGroup "' + env_lg.get() + '"' + lsstr
2947 rotZ = luxProp(scn, "env.rotation", 0.0)
2948 rotY = luxProp(scn, "env.rotationY", 0.0)
2949 rotX = luxProp(scn, "env.rotationX", 0.0)
2950 if gui: gui.newline()
2951 luxFloat("rotation", rotX, 0.0, 360.0, "rot X", "environment rotation X", gui, 0.66)
2952 luxFloat("rotation", rotY, 0.0, 360.0, "rot Y", "environment rotation Y", gui, 0.66)
2953 luxFloat("rotation", rotZ, 0.0, 360.0, "rot Z", "environment rotation Z", gui, 0.66)
2954 if rotZ.get() != 0 or rotY.get() != 0 or rotX.get() != 0:
2955 str += "\tRotate %d 1 0 0\n"%(rotX.get())
2956 str += "\tRotate %d 0 1 0\n"%(rotY.get())
2957 str += "\tRotate %d 0 0 1\n"%(rotZ.get())
2961 if envtype.get() == "infinite":
2962 mapping = luxProp(scn, "env.infinite.mapping", "latlong")
2963 mappings = ["latlong","angular","vcross"]
2964 mapstr = luxOption("mapping", mapping, mappings, "mapping", "Select mapping type", gui, 0.5)
2965 map = luxProp(scn, "env.infinite.mapname", "")
2966 mapstr += luxFile("mapname", map, "map-file", "filename of the environment map", gui, 1.5)
2967 mapstr += luxFloat("gamma", luxProp(scn, "env.infinite.gamma", 1.0), 0.0, 6.0, "gamma", "", gui, 1.0)
2973 worldcolor = Blender.World.Get('World').getHor()
2974 str += "\n \"color L\" [%g %g %g]" %(worldcolor[0], worldcolor[1], worldcolor[2])
2977 str += luxFloat("gain", luxProp(scn, "env.infinite.gain", 1.0), 0.0001, 100.0, "gain", "", gui, 1.0)
2979 infinitesun = luxProp(scn, "env.infinite.hassun", "false")
2980 luxCollapse("infinitesun", infinitesun, "Sun Component", "Add Sunlight Component", gui, 2.0)
2981 if(infinitesun.get() == "true"):
2982 sun_lg = luxProp(scn, "env.sun_lightgroup", "default")
2983 luxString("env.lightgroup", sun_lg, "lightgroup", "Sun component light group", gui)
2984 if luxProp(scn, "nolg", "false").get()!="true":
2985 str += '\nLightGroup "' + sun_lg.get() + '"'
2986 str += "\nLightSource \"sun\" "
2990 if envtype.get() == "sunsky" or infinitehassun == 1:
2994 for obj in scn.objects:
2995 if (obj.getType() == "Lamp") and ((obj.Layers & scn.Layers) > 0):
2996 if obj.getData(mesh=1).getType() == 1: # sun object # data
2999 str += luxFloat("gain", luxProp(scn, "env.sunsky.gain", 1.0), 0.0, 1000.0, "gain", "Sky gain", gui)
3001 invmatrix = Mathutils.Matrix(sun.getInverseMatrix())
3002 str += "\n \"vector sundir\" [%f %f %f]\n" %(invmatrix[0][2], invmatrix[1][2], invmatrix[2][2])
3003 str += luxFloat("relsize", luxProp(scn, "env.sunsky.relsize", 1.0), 0.0, 100.0, "rel.size", "relative sun size", gui)
3004 str += luxFloat("turbidity", luxProp(scn, "env.sunsky.turbidity", 2.2), 2.0, 50.0, "turbidity", "Sky turbidity", gui)
3006 showGeo = luxProp(sun, 'sc.show', 'false')
3008 luxCollapse("sc.show", showGeo, "Geographic Sun", "Set sun position by world location, date and time", gui, 2.0)
3009 if gui and showGeo.get() == 'true':
3010 gui.newline("Geographic:")
3011 sc = sun_calculator(sun)
3013 luxInt("sc.day", luxProp(sun, "sc.day", 1), 1, 31, "day", "Local date: day", gui, 0.66)
3014 luxInt("sc.month", luxProp(sun, "sc.month", 1), 1, 12, "month", "Local date: month", gui, 0.67)
3015 luxInt("sc.year", luxProp(sun, "sc.year", 2009), 1800, 2100, "year", "Local date: year", gui, 0.66)
3017 luxInt("sc.hour", luxProp(sun, "sc.hour", 0), 0, 23, "hour", "Local time: hour", gui, 0.72)
3018 luxInt("sc.minute", luxProp(sun, "sc.minute", 0), 0, 59, "minute", "Local time: minute", gui, 0.72)
3019 luxBool("sc.dst", luxProp(sun, "sc.dst", 'false'), "DST", "DST", gui, 0.28)
3020 r = gui.getRect(0.28,1)
3021 Draw.Button("NOW", 0, r[0], r[1], r[2], r[3], "Set to current time", lambda e,v: sc.now())
3023 r = gui.getRect(0.3,1)
3024 Draw.Button("Preset", 0, r[0], r[1], r[2], r[3], "Choose a preset location", lambda e,v: sc.set_location(
3025 Draw.PupTreeMenu(sun_calculator.location_list)
3028 luxFloat("sc.lat", luxProp(sun, "sc.lat", 0.0), -90.0, 90.0, "lat", "Location: latitude", gui, 0.56)
3029 luxFloat("sc.long", luxProp(sun, "sc.long", 0.0), -180.0, 180.0, "long", "Location: longitude", gui, 0.56)
3030 luxInt("sc.tz", luxProp(sun, "sc.tz", 0), -12, 12, "timezone", "Local time: timezone offset from GMT", gui, 0.56)
3032 r = gui.getRect(2,1)
3033 Draw.Button("Calculate", 0, r[0], r[1], r[2], r[3], "Calculate sun's position", lambda e,v: sc.compute())
3037 gui.newline(); r = gui.getRect(2,1); BGL.glRasterPos2i(r[0],r[1]+5)
3038 Draw.Text("create a blender Sun Lamp")
3042 #if gui: gui.newline("GLOBAL:", 8, 0, None, [0.75,0.5,0.25])
3043 #luxFloat("scale", luxProp(scn, "global.scale", 1.0), 0.0, 10.0, "scale", "global world scale", gui)
3047 class sun_calculator:
3048 #Based on SunLight v1.0 by Miguel Kabantsov (miguelkab@gmail.com)
3049 #Replaces the faulty sun position calculation algorythm with a precise calculation (Source for algorythm: http://de.wikipedia.org/wiki/Sonnenstand),
3050 #Co-Ordinates: http://www.bcca.org/misc/qiblih/latlong.html
3051 #Author: Nils-Peter Fischer (Nils-Peter.Fischer@web.de)
3069 ("Antwerp, Belgium", 67),
3070 ("Berlin, Germany", 1),
3071 ("Bratislava, Slovak Republic", 70),
3072 ("Brno, Czech Republic", 72),
3073 ("Brussles, Belgium", 68),
3074 ("Geneva, Switzerland", 65),
3075 ("Helsinki, Finland", 7),
3076 ("Innsbruck, Austria", 62),
3077 ("Kyiv, Ukraine", 64),
3078 ("London, England", 10),
3079 ("Lyon, France", 66),
3080 ("Nitra, Slovak Republic", 69),
3081 ("Oslo, Norway", 58),
3082 ("Paris, France", 15),
3083 ("Praha, Czech Republic", 71),
3084 ("Rome, Italy", 18),
3085 ("Telfs, Austria", 63),
3086 ("Warsaw, Poland", 74),
3087 ("Wroclaw, Poland", 73),
3088 ("Zurich, Switzerland", 21),
3092 ("Beijing, China", 0),
3093 ("Bombay, India", 2),
3094 ("Buenos Aires, Argentina", 3),
3095 ("Cairo, Egypt", 4),
3096 ("Cape Town, South Africa", 5),
3097 ("Caracas, Venezuela", 6),
3098 ("Curitiba, Brazil", 60),
3099 ("Hong Kong, China", 8),
3100 ("Jerusalem, Israel", 9),
3101 ("Joinville, Brazil", 61),
3102 ("Mexico City, Mexico", 11),
3103 ("Moscow, Russia", 12),
3104 ("New Delhi, India", 13),
3105 ("Ottawa, Canada", 14),
3106 ("Rio de Janeiro, Brazil", 16),
3107 ("Riyadh, Saudi Arabia", 17),
3108 ("Sao Paulo, Brazil", 59),
3109 ("Sydney, Australia", 19),
3110 ("Tokyo, Japan", 20),
3114 ("Albuquerque, NM", 22),
3115 ("Anchorage, AK", 23),
3116 ("Atlanta, GA", 24),
3118 ("Birmingham, AL", 26),
3119 ("Bismarck, ND", 27),
3121 ("Boulder, CO", 29),
3122 ("Chicago, IL", 30),
3125 ("Detroit, MI", 33),
3126 ("Honolulu, HI", 34),
3127 ("Houston, TX", 35),
3128 ("Indianapolis, IN", 36),
3129 ("Jackson, MS", 37),
3130 ("Kansas City, MO", 38),
3131 ("Los Angeles, CA", 39),
3132 ("Menomonee Falls, WI", 40),
3134 ("Minneapolis, MN", 42),
3135 ("New Orleans, LA", 43),
3136 ("New York City, NY", 44),
3137 ("Oklahoma City, OK", 45),
3138 ("Philadelphia, PA", 46),
3139 ("Phoenix, AZ", 47),
3140 ("Pittsburgh, PA", 48),
3141 ("Portland, ME", 49),
3142 ("Portland, OR", 50),
3143 ("Raleigh, NC", 51),
3144 ("Richmond, VA", 52),
3145 ("Saint Louis, MO", 53),
3146 ("San Diego, CA", 54),
3147 ("San Francisco, CA", 55),
3148 ("Seattle, WA", 56),
3149 ("Washington DC", 57),
3155 67: ( 51.2167, 4.4, 1),
3156 1: ( 52.33, 13.30, 1),
3157 70: ( 48.17, 17.17, 1),
3158 72: ( 49.2, 16.63, 1),
3159 68: ( 58.8467, 4.3525, 1),
3160 65: ( 46.217, 6.150, 1),
3161 7: ( 60.1667, 24.9667,2),
3162 62: ( 47.2672, 11.3928, 1),
3163 64: ( 50.75, 30.0833, 2),
3164 10: ( 51.50, 0.0, 0),
3165 66: ( 45.767, 4.833, 1),
3166 69: ( 48.32, 18.07, 1),
3167 58: ( 59.56, 10.41, 1),
3168 15: ( 48.8667, 2.667, 1),
3169 71: ( 50.08, 14.46, 1),
3170 18: ( 41.90, 12.4833, 1),
3171 63: ( 47.3, 11.0667, 1),
3172 74: ( 52.232, 21.008, 1),
3173 73: ( 51.108, 17.038, 1),
3174 21: ( 47.3833, 8.5333, 1),
3177 0: ( 39.9167, 116.4167, 8),
3178 2: ( 18.9333, 72.8333, 5.5),
3179 3: (-34.60, -58.45, -3),
3180 4: ( 30.10, 31.3667, 2),
3181 5: (-33.9167, 18.3667, 2),
3182 6: ( 10.50, -66.9333, -4),
3183 60: (-25.4278, -49.2731, -3),
3184 8: ( 22.25, 114.1667, 8),
3185 9: ( 31.7833, 35.2333, 2),
3186 61: (-29.3044, -48.8456, -3),
3187 11: ( 19.4, -99.15, -6),
3188 12: ( 55.75, 37.5833, 3),
3189 13: ( 28.6, 77.2, 5.5),
3190 14: ( 45.41667, -75.7, -5),
3191 16: (-22.90, -43.2333, -3),
3192 17: ( 24.633, 46.71667, 3),
3193 59: ( -23.5475, -46.6361, -3),
3194 19: (-33.8667,151.2167,10),
3195 20: ( 35.70, 139.7667, 9),
3198 22: ( 35.0833, -106.65, -7),
3199 23: ( 61.217, -149.90, -9),
3200 24: ( 33.733, -84.383, -5),
3201 25: ( 30.283, -97.733, -6),
3202 26: ( 33.521, -86.8025, -6),
3203 27: ( 46.817, -100.783, -6),
3204 28: ( 42.35, -71.05, -5),
3205 29: ( 40.125, -105.237, -7),
3206 30: ( 41.85, -87.65, -6),
3207 31: ( 32.46, -96.47, -6),
3208 32: ( 39.733, -104.983, -7),
3209 33: ( 42.333, -83.05, -5),
3210 34: ( 21.30, -157.85, -10),
3211 35: ( 29.75, -95.35, -6),
3212 36: ( 39.767, -86.15, -5),
3213 37: ( 32.283, -90.183, -6),
3214 38: ( 39.083, -94.567, -6),
3215 39: ( 34.05, -118.233, -8),
3216 40: ( 43.11, -88.10, -6),
3217 41: ( 25.767, -80.183, -5),
3218 42: ( 44.967, -93.25, -6),
3219 43: ( 29.95, -90.067, -6),
3220 44: ( 40.7167, -74.0167, -5),
3221 45: ( 35.483, -97.533, -6),
3222 46: ( 39.95, -75.15, -5),
3223 47: ( 33.433, -112.067,-7),
3224 48: ( 40.433, -79.9833, -5),
3225 49: ( 43.666, -70.283, -5),
3226 50: ( 45.517, -122.65, -8),
3227 51: ( 35.783, -78.65, -5),
3228 52: ( 37.5667, -77.450, -5),
3229 53: ( 38.6167, -90.1833, -6),
3230 54: ( 32.7667, -117.2167, -8),
3231 55: ( 37.7667, -122.4167, -8),
3232 56: ( 47.60, -122.3167, -8),
3233 57: ( 38.8833, -77.0333, -5),
3236 def __init__(self, sun):
3240 ct = time.localtime()
3247 luxProp(self.sun, 'sc.day', 0).set(ct[2])
3248 luxProp(self.sun, 'sc.month', 0).set(ct[1])
3249 luxProp(self.sun, 'sc.year', 0).set(ct[0])
3250 luxProp(self.sun, 'sc.hour', 0).set(ct[3])
3251 luxProp(self.sun, 'sc.minute', 0).set(ct[4])
3252 luxProp(self.sun, 'sc.dst', 0).set(dst)
3256 def set_location(self, location):
3257 if location < 0: return
3259 lat, long, tz = self.location_data[location]
3260 luxProp(self.sun, "sc.lat", 0).set(lat)
3261 luxProp(self.sun, "sc.long", 0).set(long)
3262 luxProp(self.sun, "sc.tz", 0).set(tz)
3268 self.lat = luxProp(self.sun, "sc.lat", 0).get()
3269 self.long = luxProp(self.sun, "sc.long", 0).get()
3270 self.tz = luxProp(self.sun, "sc.tz", 0).get()
3272 self.hour = luxProp(self.sun, "sc.hour", 0).get()
3273 self.min = luxProp(self.sun, "sc.minute", 0).get()
3274 self.dst = luxProp(self.sun, "sc.dst", 'false').get()
3275 if self.dst == 'true':
3280 self.day = luxProp(self.sun, "sc.day", 0).get()
3281 self.month = luxProp(self.sun, "sc.month", 0).get()
3282 self.year = luxProp(self.sun, "sc.year", 0).get()
3285 az,el = self.geoSunData(
3291 self.hour + self.min/60.0,
3295 self.sun.rot = math.radians(90-el), 0, math.radians(-az)
3300 # --- THE FOLLOWING METHODS ARE ADAPTED FROM LUXMAYA ---
3302 # mathematical helpers
3303 def sind(self, deg):
3304 return math.sin(math.radians(deg))
3306 def cosd(self, deg):
3307 return math.cos(math.radians(deg))
3309 def tand(self, deg):
3310 return math.tan(math.radians(deg))
3312 def asind(self, deg):
3313 return math.degrees(math.asin(deg))
3315 def atand(self, deg):
3316 return math.degrees(math.atan(deg))
3319 def geo_sun_astronomicJulianDate(self, Year, Month, Day, LocalTime, Timezone):
3321 See quoted source in class header for explanation
3331 UT = LocalTime - Timezone
3334 B = 2.0 - A+int(A/4.0)
3336 JD = math.floor(365.25*(Y+4716.0)) + math.floor(30.6001*(M+1.0)) + Day + hour + B - 1524.4
3340 def geoSunData(self, Latitude, Longitude, Year, Month, Day, LocalTime, Timezone):
3342 See quoted source in class header for explanation
3345 JD = self.geo_sun_astronomicJulianDate(Year, Month, Day, LocalTime, Timezone)
3351 LDeg = (280.460 + 0.9856474*n) - (math.floor((280.460 + 0.9856474*n)/360.0) * 360.0)
3352 gDeg = (357.528 + 0.9856003*n) - (math.floor((357.528 + 0.9856003*n)/360.0) * 360.0)
3353 LambdaDeg = LDeg + 1.915 * self.sind(gDeg) + 0.02 * self.sind(2.0*gDeg)
3355 epsilonDeg = 23.439 - 0.0000004*n
3357 alphaDeg = self.atand( (self.cosd(epsilonDeg) * self.sind(LambdaDeg)) / self.cosd(LambdaDeg) )
3358 if self.cosd(LambdaDeg) < 0.0:
3361 deltaDeg = self.asind( self.sind(epsilonDeg) * self.sind(LambdaDeg) )
3363 JDNull = self.geo_sun_astronomicJulianDate(Year, Month, Day, 0.0, 0.0)
3365 TNull = (JDNull - 2451545.0) / 36525.0
3366 T = LocalTime - Timezone
3368 thetaGh = 6.697376 + 2400.05134*TNull + 1.002738*T
3369 thetaGh -= math.floor(thetaGh/24.0) * 24.0
3371 thetaG = thetaGh * 15.0
3372 theta = thetaG + llambda
3374 tau = theta - alphaDeg
3376 a = self.atand( self.sind(tau) / ( self.cosd(tau)*self.sind(phi) - self.tand(deltaDeg)*self.cosd(phi)) )
3377 if self.cosd(tau)*self.sind(phi) - self.tand(deltaDeg)*self.cosd(phi) < 0.0:
3380 h = self.asind( self.cosd(deltaDeg)*self.cosd(tau)*self.cosd(phi) + self.sind(deltaDeg)*self.sind(phi) )
3382 R = 1.02 / (self.tand (h+(10.3/(h+5.11))))
3388 return azimuth, elevation
3390 def luxAccelerator(scn, gui=None):
3393 acceltype = luxProp(scn, "accelerator.type", "tabreckdtree")
3394 str = luxIdentifier("Accelerator", acceltype, ["none", "tabreckdtree", "grid", "bvh", "qbvh"], "ACCEL", "select accelerator type", gui)
3395 if acceltype.get() == "tabreckdtree":
3396 if gui: gui.newline()
3397 str += luxInt("intersectcost", luxProp(scn, "accelerator.kdtree.interscost", 80), 0, 1000, "inters.cost", "specifies how expensive ray-object intersections are", gui)
3398 str += luxInt("traversalcost", luxProp(scn, "accelerator.kdtree.travcost", 1), 0, 1000, "trav.cost", "specifies how expensive traversing a ray through the kdtree is", gui)
3399 if gui: gui.newline()
3400 str += luxFloat("emptybonus", luxProp(scn, "accelerator.kdtree.emptybonus", 0.2), 0.0, 100.0, "empty.b", "promotes kd-tree nodes that represent empty space", gui)
3401 if gui: gui.newline()
3402 str += luxInt("maxprims", luxProp(scn, "accelerator.kdtree.maxprims", 1), 0, 1000, "maxprims", "maximum number of primitives in a kdtree volume before further splitting of the volume occurs", gui)
3403 str += luxInt("maxdepth", luxProp(scn, "accelerator.kdtree.maxdepth", -1), -1, 100, "maxdepth", "If positive, the maximum depth of the tree. If negative this value is set automatically", gui)
3404 if acceltype.get() == "unsafekdtree":
3405 if gui: gui.newline()
3406 str += luxInt("intersectcost", luxProp(scn, "accelerator.kdtree.interscost", 80), 0, 1000, "inters.cost", "specifies how expensive ray-object intersections are", gui)
3407 str += luxInt("traversalcost", luxProp(scn, "accelerator.kdtree.travcost", 1), 0, 1000, "trav.cost", "specifies how expensive traversing a ray through the kdtree is", gui)
3408 if gui: gui.newline()
3409 str += luxFloat("emptybonus", luxProp(scn, "accelerator.kdtree.emptybonus", 0.2), 0.0, 100.0, "empty.b", "promotes kd-tree nodes that represent empty space", gui)
3410 if gui: gui.newline()
3411 str += luxInt("maxprims", luxProp(scn, "accelerator.kdtree.maxprims", 1), 0, 1000, "maxprims", "maximum number of primitives in a kdtree volume before further splitting of the volume occurs", gui)
3412 str += luxInt("maxdepth", luxProp(scn, "accelerator.kdtree.maxdepth", -1), -1, 100, "maxdepth", "If positive, the maximum depth of the tree. If negative this value is set automatically", gui)
3413 if acceltype.get() == "grid":
3414 str += luxBool("refineimmediately", luxProp(scn, "accelerator.grid.refine", "false"), "refine immediately", "Makes the primitive intersectable as soon as it is added to the grid", gui)
3415 if acceltype.get() == "qbvh":
3416 if gui: gui.newline()
3417 str += luxInt("maxprimsperleaf", luxProp(scn, "accelerator.qbvh.maxprimsperleaf", 4), 1, 64, "maxprimsperleaf", "Maximum number of primitives to leave in one leaf node", gui)
3420 def luxSystem(scn, gui=None):
3422 if gui: gui.newline("PATHS:", 10)
3423 lp = luxProp(scn, "lux", "")
3424 lp.set(Blender.sys.dirname(lp.get())+os.sep)
3425 luxPath("LUX dir", lp, "lux binary dir", "Lux installation path", gui, 2.0)
3427 # luxFile("GUI filename", luxProp(scn, "lux", ""), "lux-file", "filename and path of the lux GUI executable", gui, 2.0)
3428 # luxFile("Console filename", luxProp(scn, "luxconsole", ""), "lux-file-console", "filename and path of the lux console executable", gui, 2.0)
3429 if gui: gui.newline()
3430 luxFile("datadir", luxProp(scn, "datadir", ""), "default out dir", "default.lxs save path", gui, 2.0)
3432 if gui: gui.newline()
3433 pm = ["absolute","relative","flat"]
3434 luxOption("pathmode", luxProp(scn, "pathmode", "absolute"), pm, "path-mode", "select format for paths on export", gui, 2.0)
3436 if gui: gui.newline("PRIORITY:", 10)
3437 luxnice = luxProp(scn, "luxnice", 10)
3438 if osys.platform=="win32":
3439 r = gui.getRect(2, 1)
3440 Draw.Menu("priority%t|abovenormal%x-10|normal%x0|belownormal%x10|low%x19", evtLuxGui, r[0], r[1], r[2], r[3], luxnice.get(), "", lambda e,v: luxnice.set(v))
3441 else: luxInt("nice", luxnice, -20, 19, "nice", "nice value. Range goes from -20 (highest priority) to 19 (lowest)", gui)
3443 luxBool("noopengl", luxProp(scn, "noopengl", "false"), "Disable OpenGL", "(workaround for some buggy display drivers)", gui, 1.0)
3446 if gui: gui.newline("THREADS:", 10)
3447 autothreads = luxProp(scn, "autothreads", "true")
3448 luxBool("autothreads", autothreads, "Auto Detect", "Automatically use all available processors", gui, 1.0)
3449 if autothreads.get()=="false":
3450 luxInt("threads", luxProp(scn, "threads", 1), 1, 100, "threads", "number of threads used for rendering", gui, 1.0)
3452 if gui: gui.newline("ANIM:", 10)
3453 useparamkeys = luxProp(scn, "useparamkeys", "false")
3454 luxBool("useparamkeys", useparamkeys, "Enable Parameter IPO Keyframing", "Enables keyframing of luxblend parameters", gui, 2.0)
3456 if gui: gui.newline("PARAMS:", 10)
3457 parammodeadvanced = luxProp(scn, "parammodeadvanced", "false")
3458 luxBool("parammodeadvanced", parammodeadvanced, "Default Advanced Parameters", "Always use advanced parameters by default", gui, 2.0)
3460 if gui: gui.newline("PREVIEW:", 10)
3461 qs = ["low","medium","high","very high"]
3462 defprevmat = luxProp(scn, "defprevmat", "high")
3463 luxOption("defprevmat", defprevmat, qs, "Materials", "Select default preview quality in material editor for materials", gui, 1.0)
3465 if gui: gui.newline("GAMMA:", 10)
3466 luxBool("RGC", luxProp(scn, "RGC", "true"), "RGC", "use reverse gamma correction", gui)
3467 luxBool("ColClamp", luxProp(scn, "colorclamp", "false"), "ColClamp", "clamp all colors to 0.0-0.9", gui)
3468 if gui: gui.newline("MESH:", 10)
3469 luxBool("mesh_optimizing", luxProp(scn, "mesh_optimizing", "true"), "optimize meshes", "Optimize meshes during export", gui, 2.0)
3470 #luxInt("trianglemesh thr", luxProp(scn, "trianglemesh_thr", 0), 0, 10000000, "trianglemesh threshold", "Vertex threshold for exporting (wald) trianglemesh object(s)", gui, 2.0)
3471 #if gui: gui.newline()
3472 #luxInt("barytrianglemesh thr", luxProp(scn, "barytrianglemesh_thr", 300000), 0, 100000000, "barytrianglemesh threshold", "Vertex threshold for exporting barytrianglemesh object(s) (slower but uses less memory)", gui, 2.0)
3473 if gui: gui.newline("INSTANCING:", 10)
3474 luxInt("instancing_threshold", luxProp(scn, "instancing_threshold", 2), 0, 1000000, "object instancing threshold", "Threshold to created instanced objects", gui, 2.0)
3476 # dougal2 packed images, enable this when implemented in Lux itself
3477 #if gui: gui.newline('TEXTURES:',10)
3478 #impack = luxProp(scn, 'packtextures', 'false')
3479 #luxBool('impack', impack, 'Pack All Images', '', gui, 2.0)
3482 network=luxProp(scn,"network","false")
3483 gui.newline("NETWORK:", 10)
3484 luxCollapse("network",network, "network", "enable network option", gui, 2.0)
3485 if(network.get() == "true"):
3486 network_use_file=luxProp(scn,"network_use_file","false")
3487 luxBool ("use file",network_use_file,"use file", "get list of servers from file; one per line",gui,2.0)
3488 if (network_use_file.get() == "true"):
3489 luxFile("file", luxProp(scn, "network_file_path", ""), "file", "file where servers are defined", gui, 1.0)
3492 luxString("Servers",luxProp(scn,"network_servers",""),"servers","coma separated list of servers",gui,1.0)
3494 luxInt("network_interval",luxProp(scn,"newtork_interval",180),0,300,"update interval","interval between network refresh",gui)
3497 def scalelist(list, factor):
3498 for i in range(len(list)): list[i] = list[i] * factor
3502 def luxMapping(key, mat, gui, level=0):
3503 global icon_map2d, icon_map2dparam
3504 if gui: gui.newline("2Dmap:", -2, level, icon_map2d)
3505 mapping = luxProp(mat, key+".mapping", "uv")
3506 mappings = ["uv","spherical","cylindrical","planar"]
3507 str = luxOption("mapping", mapping, mappings, "mapping", "", gui, 0.5)
3508 if mapping.get() == "uv":
3509 str += luxFloat("uscale", luxProp(mat, key+".uscale", 1.0), -100.0, 100.0, "Us", "u-scale", gui, 0.375)
3510 str += luxFloat("vscale", luxProp(mat, key+".vscale", -1.0), -100.0, 100.0, "Vs", "v-scale", gui, 0.375)
3511 str += luxFloat("udelta", luxProp(mat, key+".udelta", 0.0), -100.0, 100.0, "Ud", "u-delta", gui, 0.375)
3512 str += luxFloat("vdelta", luxProp(mat, key+".vdelta", 0.0), -100.0, 100.0, "Vd", "v-delta", gui, 0.375)
3513 if mapping.get() == "planar":
3514 str += luxFloat("udelta", luxProp(mat, key+".udelta", 0.0), -100.0, 100.0, "Ud", "u-delta", gui, 0.75)
3515 str += luxFloat("vdelta", luxProp(mat, key+".vdelta", 0.0), -100.0, 100.0, "Vd", "v-delta", gui, 0.75)
3516 if gui: gui.newline("v1:", -2, level+1, icon_map2dparam)
3517 str += luxVector("v1", luxProp(mat, key+".v1", "1 0 0"), -100.0, 100.0, "v1", "v1-vector", gui, 2.0)
3518 if gui: gui.newline("v2:", -2, level+1, icon_map2dparam)
3519 str += luxVector("v2", luxProp(mat, key+".v2", "0 1 0"), -100.0, 100.0, "v2", "v2-vector", gui, 2.0)
3522 def lux3DMapping(key, mat, gui, level=0):
3523 global icon_map3dparam
3525 if gui: gui.newline("scale:", -2, level, icon_map3dparam)
3526 str += luxVectorUniform("scale", luxProp(mat, key+".3dscale", 1.0), 0.001, 1000.0, "scale", "scale-vector", gui, 2.0)
3527 if gui: gui.newline("rot:", -2, level, icon_map3dparam)
3528 str += luxVector("rotate", luxProp(mat, key+".3drotate", "0 0 0"), -360.0, 360.0, "rotate", "rotate-vector", gui, 2.0)
3529 if gui: gui.newline("move:", -2, level, icon_map3dparam)
3530 str += luxVector("translate", luxProp(mat, key+".3dtranslate", "0 0 0"), -1000.0, 1000.0, "move", "translate-vector", gui, 2.0)
3533 def getTreeNameById(tree, i): # helper function to retrive name of the selected treemenu-item
3535 if type(t)==types.TupleType:
3536 if type(t[1])==types.ListType:
3537 n=getTreeNameById(t[1], i)
3539 elif t[1]==i: return t[0]
3542 def luxTexture(name, parentkey, type, default, min, max, caption, hint, mat, gui, matlevel, texlevel=0, lightsource=0, overrideicon=""):
3543 global icon_tex, icon_texcol, icon_texmix, icon_texmixcol, icon_texparam, icon_spectex
3545 return (t1[0]+t2[0], t1[1]+t2[1])
3546 def alternativedefault(type, default):
3547 if type=="float": return 0.0
3548 else: return "0.0 0.0 0.0"
3549 level = matlevel + texlevel
3550 keyname = "%s:%s"%(parentkey, name)
3551 texname = "%s:%s"%(mat.getName(), keyname)
3552 # if gui: gui.newline(caption+":", 0, level)
3553 if(lightsource == 0):
3554 if texlevel == 0: texture = luxProp(mat, keyname+".texture", "imagemap")
3555 else: texture = luxProp(mat, keyname+".texture", "constant")
3557 texture = luxProp(mat, keyname+".texture", "blackbody")
3559 textures = ["constant","blackbody", "lampspectrum", "equalenergy", "frequency", "gaussian", "regulardata", "irregulardata", "imagemap","mix","scale","bilerp","uv", "checkerboard","brick","dots","fbm","marble","wrinkled", "windy", "blender_marble", "blender_musgrave", "blender_wood", "blender_clouds", "blender_blend", "blender_distortednoise", "blender_noise", "blender_magic", "blender_stucci", "blender_voronoi", "harlequin"]
3562 if(overrideicon != ""):
3566 if texture.get() in ["mix", "scale", "checkerboard", "dots"]:
3567 if type=="color": icon = icon_texmixcol
3568 else: icon = icon_texmix
3569 elif texture.get() in ["constant", "blackbody", "equalenergy", "frequency", "gaussian", "regulardata", "irregulardata"]:
3572 if type=="color": icon = icon_texcol
3573 else: icon = icon_tex
3574 if (texlevel > 0): gui.newline(caption+":", -2, level, icon, scalelist([0.5,0.5,0.5],2.0/(level+2)))
3575 else: gui.newline("texture:", -2, level, icon, scalelist([0.5,0.5,0.5],2.0/(level+2)))
3576 luxOption("texture", texture, textures, "texture", "", gui, 0.9)
3577 str = "Texture \"%s\" \"%s\" \"%s\""%(texname, type, texture.get())
3579 if gui: Draw.PushButton(">", evtLuxGui, gui.xmax+gui.h, gui.y-gui.h, gui.h, gui.h, "Menu", lambda e,v: showMatTexMenu(mat,keyname,True))
3580 if gui: # Draw Texture level Material preview
3581 luxPreview(mat, parentkey, 1, False, False, name, gui, texlevel, [0.5, 0.5, 0.5])
3582 # Add an offset for next controls
3583 #r = gui.getRect(1.0, 1)
3586 if texture.get() == "constant":
3587 value = luxProp(mat, keyname+".value", default)
3588 if type == "float": luxFloat("value", value, min, max, "", "", gui, 1.1)
3589 elif type == "color": luxRGB("value", value, max, "", "", gui, 1.1)
3591 if type == "color": return ("", " \"%s %s\" [%s]"%(type, name, value.getRGC()))
3592 return ("", " \"%s %s\" [%s]"%(type, name, value.get()))
3594 # if type == "color": str += " \"%s value\" [%s]"%(type, value.getRGC())
3595 # else: str += " \"%s value\" [%s]"%(type, value.get())
3597 if texture.get() == "blackbody":
3599 if gui.xmax-gui.x < gui.w: gui.newline()
3600 r = gui.getRect(1.0, 1)
3602 drawBar(bar_blackbody, gui.xmax-gui.w-7, r[1])
3603 str += luxFloat("temperature", luxProp(mat, keyname+".bbtemp", 6500.0), 1000.0, 10000.0, "temperature", "Black Body temperature in degrees Kelvin", gui, 2.0, 1)
3605 if texture.get() == "lampspectrum":
3606 lampstring = luxProp(mat, keyname+".lampstring", "Incandescent2")
3607 lamppreset = luxProp(mat, keyname+".lampspectrum", "PHILIPS [Argenta] 200W Incandescent Lamp")
3609 def setLamp(i, value, preset, tree, dict): # callback function to set ior value after selection
3612 preset.set(getTreeNameById(tree, i))
3614 measuredtree = [ ("Natural Daylight", [ ("Natural Daylight", 1) ] ), ("Incandescent", [ ("Paraffin Candle Flame", 2), ("Generic 7W Incandescent Lamp", 3), ("PHILIPS [Argenta] 200W Incandescent Lamp", 4), ("Welsbach Gas Mantle (modern, without Thorium)", 5), ("Incandescent Anti-Insect Lamp", 6) ] ), ("Fluorescent/Compact Fluorescent", [ ("PHILIPS [TL-D 30W/55] Regular Daylight Fluorescent", 7), ("Sylvania [F4T5 4W] Regular Warm White Fluorescent", 8), ("OSRAM [DULUXSTAR 21W/827] Regular Compact Triphosphor Fluorescent", 9), ("Cold Cathode Warm White CFL Triphosphor Fluorescent.", 10), ("NARVA [COLOURLUX plus daylight 20W/860] Daylight CFL Triphosphor Fluorescent", 11), ("Sylvania [GroLux] Fluorescent Aquarium/Plant Lamp", 12), ("Laptop LCD Screen", 13), ("PHILIPS [ActiViva] \"Natural\" Triphosphor Fluorescent", 14), ("PHILIPS [ActiViva] \"Active\" Triphosphor Fluorescent", 16) ] ), ("High Pressure Mercury", [ ("OSRAM [HQA 80W] Clear HPM Lamp", 17), ("PHILIPS [HPL 125W] HPM Lamp with improved color", 18), ("OSRAM [HQL 80W] HPM Lamp with improved warm deluxe color", 19), ("PHILIPS [ML 160W] Self-Ballasted HPM Vapor Lamp", 20), ("NARVA [160W] Self-ballasted HPM Vapor Lamp", 21) ] ), ("Low/High Pressure Sodium", [ ("Regular High Pressure Sodium Lamp, warmup after 5-7 sec", 22), ("Regular High Pressure Sodium Lamp, warmup after 10-12 sec", 23), ("SOX Low Pressure Sodium Discharge Lamp", 24), ("Medium Pressure Sodium Discharge Lamp, warmup after ~35 sec", 25), ("GE [Lucalox 35W] High Pressure Sodium Lamp", 26), ("PHILIPS [SDW-T 100W] Super High Pressure White Sodium Lamp", 27) ] ), ("Metal Halide", [ ("PHILIPS [HPI-T 400W] MH Lamp with Mercury, Sodium, Thallium and Indium iodides", 28), ("OSRAM [HQI-TS 75W/WDL] Metal Halide lamp with Mercury, sodium, thallium, indium and tin iodides, from ", 29), ("GE [MVR325IUWM 325 Watt I-Line Multi-Vapor® Metal Halide - Clear Watt Miser®] MH Lamp with Mercury, Sodium and Scandium iodides", 30), ("OSRAM [HQI-T 400W/D] MH Lamp with Mercury, Thallium, Dysprosium, Holmium, Thulium and Caesium iodides", 31), ("PHILIPS Diazo MH Lamp with Mercury, iron and cobalt iodides", 32), ("Sylvania Diazo MH Lamp with Mercury, gallium and lead iodides", 33), ("OSRAM [HQI-T 400W/Blau] Blue colored MH Lamp with Mercury and indium iodides", 34), ("RADIUM [HRI-T 400W/Planta] Plant growing MH Lamp with Mercury, indium and sodium iodides", 35), ("OSRAM [HQI-T 400W/Grun] Green colored MH Lamp with Mercury and thallium iodides", 36) ] ), ("Diode", [ ("Regular High Brightness Blue LED", 37), ("Monochromatic emission from a Red Laser diode", 38), ("Monochromatic emission from a Green Laser diode.", 39) ] ), ("Spectral", [ ("PHILIPS Spectral Xenon Lamp - Continuous Xenon low pressure thermionic discharge", 40), ("PHILIPS spectral Rubidium Lamp - Continuous Rubidium low pressure thermionic discharge", 41), ("PHILIPS spectral Cadmium Lamp - Continuous Cadmium low pressure thermionic discharge", 42), ("PHILIPS spectral zinc Lamp - Continuous Zinc low pressure thermionic discharge", 43) ] ), ("Glow Discharge", [ ("Neon glow discharge", 44), ("Neon and Krypton glow discharge and green phosphor (night-lights/indicators)", 45), ("Neon and Xenon glow discharge and green phosphor (night-lights/indicators)", 46), ("Neon and Xenon glow discharge and blue phosphor (night-lights/indicators)", 48), ("Argon glow discharge", 49), ("Self-ballasted High Pressure Mercury Vapor Lamp, with yttrium vanadate phosphate fluorescent phosphors, in glow discharge mode", 50) ] ), ("Molecular", [ ("Butane Gas Flame", 51), ("Alcohol Flame", 52) ] ), ("General Fluorescence", [ ("Print quality A4 Xerox paper wrapped around a blacklight Lamp", 53), ("Neon green dye, bombarded with black light", 54), ("Regular Modern Color TV CRT", 55) ] ), ("Various", [ ("Stroboscopic flash. Xenon I, likely II and perhaps III", 56), ("Carbon Arc Spectrum", 57), ("OSRAM [XBO 75W/2] Short Arc Xenon Lamp", 58) ] ), ("Blacklight/Ultraviolet", [ ("Sylvania [G8T5 8W] Germicidal lamp", 59), ("Sylvania [F6T5/BLB 8W] Black light blue fluorescent", 60), ("PHILIPS [HPW 125W] High Pressure Mercury Black Light", 61), ("Sylvania [Blacklite 350 F8W/BL350] Black Light fluorescent", 62) ] ), ("Mercury UV Spectrum", [ ("The near visible UVA emissions from a high pressure Mercury clear lamp", 63) ] ), ("Absorption/Mixed Spectra", [ ("High Pressure Mercury Warm Deluxe light ([1.4.3]) absorbed through blue Cobalt glass", 64), ("Incandescent light ([1.2.3]) absorbed through blue Cobalt glass", 65), ("High Pressure Mercury Warm Deluxe light ([1.4.3]) absorbed through ciel dye #42053", 66), ("Incandescent light ([1.2.3]) absorbed through ciel dye #42053", 67), ("High Pressure Mercury Warm Deluxe light ([1.4.3]) absorbed through red glass", 68), ("Incandescent light ([1.2.3]) absorbed through red glass.m", 69), ("Incandescent light ([1.2.3]) absorbed through olive oil. ", 70) ] ) ]
3616 measureddict = {1:"Daylight", 2:"Candle", 3:"Incandescent1", 4:"Incandescent2", 5:"Welsbach", 6:"AntiInsect", 7:"FLD2", 8:"FL37K", 9:"CFL27K", 10:"CFL4K", 11:"CFL6K", 12:"GroLux", 13:"LCDS", 14:"FLAV8K", 15:"none", 16:"FLAV17K", 17:"HPM2", 18:"HPMFL1", 19:"HPMFL2", 20:"HPMSB", 21:"HPMSBFL", 22:"SS1", 23:"SS2", 24:"LPS", 25:"MPS", 26:"HPS", 27:"SHPS", 28:"MHN", 29:"MHWWD", 30:"MHSc", 31:"MHD", 32:"FeCo", 33:"GaPb", 34:"BLAU", 35:"PLANTA", 36:"GRUN", 37:"LEDB", 38:"RedLaser", 39:"GreenLaser", 40:"XeI", 41:"Rb", 42:"Cd", 43:"Zn", 44:"Ne", 45:"NeKrFL", 46:"NeXeFL1", 47:"none", 48:"NeXeFL2", 49:"Ar", 50:"HPMFL2Glow", 51:"Butane", 52:"Alcohol", 53:"BLP", 54:"BLNG", 55:"TV", 56:"Xe", 57:"CarbonArc", 58:"HPX", 59:"LPM2", 60:"FLBLB", 61:"HPMBL", 62:"FLBL", 63:"UVA", 64:"HPMFLCobaltGlass", 65:"CobaltGlass", 66:"HPMFLCL42053", 67:"CL42053", 68:"HPMFLRedGlass", 69:"RedGlass", 70:"OliveOil" }
3618 r = gui.getRect(2.0, 1)
3619 Draw.Button(lamppreset.get(), evtLuxGui, r[0], r[1], r[2], r[3], "select lamp spectrum", lambda e,v: setLamp(Draw.PupTreeMenu(measuredtree), lampstring, lamppreset, measuredtree, measureddict))
3620 str += luxString("name", lampstring, "Lamp", "Choose measured Lamp Spectrum", None, 2.0)
3622 if texture.get() == "equalenergy":
3624 if gui.xmax-gui.x < gui.w: gui.newline()
3625 r = gui.getRect(1.0, 1)
3627 drawBar(bar_equalenergy, gui.xmax-gui.w-7, r[1])
3628 str += luxFloat("energy", luxProp(mat, keyname+".energy", 1.0), 0.0, 1.0, "energy", "Energy of each spectral band", gui, 2.0, 1)
3630 if texture.get() == "frequency":
3631 str += luxFloat("freq", luxProp(mat, keyname+".freq", 0.01), 0.01, 100.0, "frequency", "Frequency in nm", gui, 2.0, 1)
3632 str += luxFloat("phase", luxProp(mat, keyname+".phase", 0.5), 0.0, 1.0, "phase", "Phase", gui, 1.1, 1)
3633 str += luxFloat("energy", luxProp(mat, keyname+".energy", 1.0), 0.0, 1.0, "energy", "Amount of mean energy", gui, 0.9, 1)
3635 if texture.get() == "gaussian":
3637 if gui.xmax-gui.x < gui.w: gui.newline()
3638 r = gui.getRect(1.0, 1)
3640 drawBar(bar_spectrum, gui.xmax-gui.w-7, r[1])
3641 str += luxFloat("wavelength", luxProp(mat, keyname+".wavelength", 550.0), 380.0, 720.0, "wavelength", "Mean Wavelength in visible spectrum in nm", gui, 2.0, 1)
3642 str += luxFloat("width", luxProp(mat, keyname+".width", 50.0), 20.0, 300.0, "width", "Width of gaussian distribution in nm", gui, 1.1, 1)
3643 str += luxFloat("energy", luxProp(mat, keyname+".energy", 1.0), 0.0, 1.0, "energy", "Amount of mean energy", gui, 0.9, 1)
3645 if texture.get() == "imagemap":
3646 str += luxOption("wrap", luxProp(mat, keyname+".wrap", "repeat"), ["repeat","black","clamp"], "repeat", "", gui, 1.1)
3649 texturefilename = luxProp(mat, keyname+".filename", "")
3650 luxFile("filename", texturefilename, "file", "texture file path", gui, 2.0)
3651 # dougal2 image file packing
3652 impack = luxProp(Scene.GetCurrent(), 'packtextures', 'false')
3654 if impack.get() == 'false':
3655 str += luxFile("filename", texturefilename, "file", "texture file path", None, 2.0)
3658 def get_image_data(filename):
3660 f=open(filename,'rb')
3664 print 'Error reading image data from %s' % filename
3666 return base64.b64encode(zlib.compress(d))
3667 imdata = get_image_data(texturefilename.get())
3668 str += '\r\n "string imagedata" ["%s"]' % imdata
3670 useseq = luxProp(mat, keyname+".useseq", "false")
3671 luxCollapse("usesew", useseq, "Sequence", "", gui, 2.0)
3673 if useseq.get() == "true":
3674 seqframes = luxProp(mat, keyname+".seqframes", 100)
3675 luxInt("frames", seqframes, 1, 100000, "Frames", "", gui, 0.5)
3676 seqoffset = luxProp(mat, keyname+".seqoffset", 0)
3677 luxInt("offset", seqoffset, 0, 100000, "Offset", "", gui, 0.5)
3678 seqstartframe = luxProp(mat, keyname+".seqsframe", 1)
3679 luxInt("startframe", seqstartframe, 1, 100000, "StartFr", "", gui, 0.5)
3680 seqcyclic = luxProp(mat, keyname+".seqcycl", "false")
3681 luxBool("cyclic", seqcyclic, "Cyclic", "", gui, 0.5)
3684 totalframes = seqframes.get()
3685 currentframe = Blender.Get('curframe')
3687 if(currentframe < seqstartframe.get()):
3688 fnumber = 1 + seqoffset.get()
3690 fnumber = (currentframe - (seqstartframe.get()-1)) + seqoffset.get()
3692 if(fnumber > seqframes.get()):
3693 if(seqcyclic.get() == "false"):
3694 fnumber = seqframes.get()
3696 fnumber = currentframe % seqframes.get()
3699 def get_seq_filename(number, filename):
3700 m = re.findall(r'(\d+)', filename)
3702 return "ERR: Can't find pattern"
3704 rightmost_number = m[len(m)-1]
3705 seq_length = len(rightmost_number)
3708 new_seq_number = nstr.zfill(seq_length)
3710 return filename.replace(rightmost_number, new_seq_number)
3712 texturefilename.set(get_seq_filename(fnumber, texturefilename.get()))
3713 if gui: gui.newline()
3715 str += luxFloat("gamma", luxProp(mat, keyname+".gamma", texturegamma()), 0.0, 6.0, "gamma", "", gui, 0.75)
3716 str += luxFloat("gain", luxProp(mat, keyname+".gain", 1.0), 0.0, 10.0, "gain", "", gui, 0.5)
3717 filttype = luxProp(mat, keyname+".filtertype", "bilinear")
3718 filttypes = ["mipmap_ewa","mipmap_trilinear","bilinear","nearest"]
3719 str += luxOption("filtertype", filttype, filttypes, "filtertype", "Choose the filtering method to use for the image texture", gui, 0.75)
3721 if filttype.get() == "mipmap_ewa" or filttype.get() == "mipmap_trilinear":
3722 str += luxFloat("maxanisotropy", luxProp(mat, keyname+".maxanisotropy", 8.0), 1.0, 512.0, "maxaniso", "", gui, 1.0)
3723 str += luxInt("discardmipmaps", luxProp(mat, keyname+".discardmipmaps", 0), 0, 1, "discardmips", "", gui, 1.0)
3725 str += luxMapping(keyname, mat, gui, level+1)
3727 if texture.get() == "mix":
3728 (s, l) = c(("", ""), luxTexture("amount", keyname, "float", 0.5, 0.0, 1.0, "amount", "The degree of mix between the two textures", mat, gui, matlevel, texlevel+1, lightsource))
3729 (s, l) = c((s, l), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
3730 (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
3733 if texture.get() == "scale":
3734 (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
3735 (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
3738 if texture.get() == "bilerp":
3740 str += luxFloat("v00", luxProp(mat, keyname+".v00", 0.0), min, max, "v00", "", gui, 1.0)
3741 str += luxFloat("v01", luxProp(mat, keyname+".v01", 1.0), min, max, "v01", "", gui, 1.0)
3742 if gui: gui.newline("", -2)
3743 str += luxFloat("v10", luxProp(mat, keyname+".v10", 0.0), min, max, "v10", "", gui, 1.0)
3744 str += luxFloat("v11", luxProp(mat, keyname+".v11", 1.0), min, max, "v11", "", gui, 1.0)
3745 elif type == "color":
3746 if gui: gui.newline(" v00:", -2)
3747 str += luxRGB("v00", luxProp(mat, keyname+".v00", "0.0 0.0 0.0"), max, "v00", "", gui, 2.0)
3748 if gui: gui.newline(" v01:", -2)
3749 str += luxRGB("v01", luxProp(mat, keyname+".v01", "1.0 1.0 1.0"), max, "v01", "", gui, 2.0)
3750 if gui: gui.newline(" v10:", -2)
3751 str += luxRGB("v10", luxProp(mat, keyname+".v10", "0.0 0.0 0.0"), max, "v10", "", gui, 2.0)
3752 if gui: gui.newline(" v11:", -2)
3753 str += luxRGB("v11", luxProp(mat, keyname+".v11", "1.0 1.0 1.0"), max, "v11", "", gui, 2.0)
3754 str += luxMapping(keyname, mat, gui, level+1)
3756 if texture.get() == "windy":
3757 str += lux3DMapping(keyname, mat, gui, level+1)
3758 # this texture has no options
3760 if texture.get() == "checkerboard":
3761 dim = luxProp(mat, keyname+".dim", 2)
3762 str += luxInt("dimension", dim, 2, 3, "dim", "", gui, 0.5)
3763 if dim.get() == 2: str += luxOption("aamode", luxProp(mat, keyname+".aamode", "closedform"), ["closedform","supersample","none"], "aamode", "antialiasing mode", gui, 0.6)
3764 if gui: gui.newline("", -2)
3765 (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
3766 (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
3768 if dim.get() == 2: str += luxMapping(keyname, mat, gui, level+1)
3769 if dim.get() == 3: str += lux3DMapping(keyname, mat, gui, level+1)
3771 if texture.get() == "dots":
3772 (s, l) = c(("", ""), luxTexture("inside", keyname, type, default, min, max, "inside", "", mat, gui, matlevel, texlevel+1, lightsource))
3773 (s, l) = c((s, l), luxTexture("outside", keyname, type, alternativedefault(type, default), min, max, "outside", "", mat, gui, matlevel, texlevel+1, lightsource))
3775 str += luxMapping(keyname, mat, gui, level+1)
3777 if texture.get() == "fbm":
3778 str += luxInt("octaves", luxProp(mat, keyname+".octaves", 8), 1, 100, "octaves", "", gui, 1.1)
3779 if gui: gui.newline("", -2)
3780 str += luxFloat("roughness", luxProp(mat, keyname+".roughness", 0.5), 0.0, 1.0, "roughness", "", gui, 2.0, 1)
3781 if gui: gui.newline("", -2)
3782 str += lux3DMapping(keyname, mat, gui, level+1)
3784 if texture.get() == "marble":
3785 str += luxInt("octaves", luxProp(mat, keyname+".octaves", 8), 1, 100, "octaves", "", gui, 1.1)
3786 if gui: gui.newline("", -2)
3787 str += luxFloat("roughness", luxProp(mat, keyname+".roughness", 0.5), 0.0, 1.0, "roughness", "", gui, 2.0, 1)
3788 if gui: gui.newline("", -2)
3789 str += luxFloat("nscale", luxProp(mat, keyname+".nscale", 1.0), 0.0, 100.0, "nscale", "Scaling factor for the noise input", gui, 1.0)
3790 str += luxFloat("variation", luxProp(mat, keyname+".variation", 0.2), 0.0, 100.0, "variation", "A scaling factor for the noise input function", gui, 1.0)
3791 if gui: gui.newline("", -2)
3792 str += lux3DMapping(keyname, mat, gui, level+1)
3794 if texture.get() == "wrinkled":
3795 str += luxInt("octaves", luxProp(mat, keyname+".octaves", 8), 1, 100, "octaves", "", gui, 1.1)
3796 if gui: gui.newline("", -2)
3797 str += luxFloat("roughness", luxProp(mat, keyname+".roughness", 0.5), 0.0, 1.0, "roughness", "", gui, 2.0, 1)
3798 if gui: gui.newline("", -2)
3799 str += lux3DMapping(keyname, mat, gui, level+1)
3801 if texture.get() == "brick":
3802 if gui: gui.newline("brick:", -2, level+1, icon_texparam)
3804 str += luxFloat("brickwidth", luxProp(mat, keyname+".brickwidth", 0.3), 0.0, 10.0, "brickwidth (X)", "", gui, 1.0)
3805 str += luxFloat("brickheight", luxProp(mat, keyname+".brickheight", 0.1), 0.0, 10.0, "brickheight (Z)", "", gui, 1.0)
3806 str += luxFloat("brickdepth", luxProp(mat, keyname+".brickdepth", 0.15), 0.0, 10.0, "brickdepth (Y)", "", gui, 1.0)
3808 if gui: gui.newline("mortar:", -2, level+1, icon_texparam)
3810 str += luxFloat("mortarsize", luxProp(mat, keyname+".mortarsize", 0.01), 0.0, 1.0, "mortarsize", "", gui, 1.0)
3812 (s, l) = c(("", ""), luxTexture("bricktex", keyname, type, default, min, max, "bricktex", "", mat, gui, matlevel, texlevel+1, lightsource))
3813 (s, l) = c((s, l), luxTexture("mortartex", keyname, type, alternativedefault(type, default), min, max, "mortartex", "", mat, gui, matlevel, texlevel+1, lightsource))
3816 str += lux3DMapping(keyname, mat, gui, level+1)
3818 if texture.get() == "blender_marble":
3819 if gui: gui.newline("noise:", -2, level+1, icon_texparam)
3821 mtype = luxProp(mat, keyname+".mtype", "soft")
3822 mtypes = ["soft","sharp","sharper"]
3823 str += luxOption("type", mtype, mtypes, "type", "", gui, 0.5)
3825 noisetype = luxProp(mat, keyname+".noisetype", "hard_noise")
3826 noisetypes = ["soft_noise","hard_noise"]
3827 str += luxOption("noisetype", noisetype, noisetypes, "noisetypes", "", gui, 0.75)
3829 str += luxInt("noisedepth", luxProp(mat, keyname+".noisedepth", 2), 0, 6, "noisedepth", "", gui, 0.75)
3831 str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 2.0, "noisesize", "", gui, 1.0)
3832 str += luxFloat("turbulance", luxProp(mat, keyname+".turbulance", 5.0), 0.0, 200.0, "turbulance", "", gui, 1.0)
3834 if gui: gui.newline("basis:", -2, level+1, icon_texparam)
3835 noisebasis2 = luxProp(mat, keyname+".noisebasis2", "sin")
3836 noisebasises2 = ["sin","saw","tri"]
3837 str += luxOption("noisebasis2", noisebasis2, noisebasises2, "noisebasis2", "", gui, 0.7)
3839 noisebasis = luxProp(mat, keyname+".noisebasis", "blender_original")
3840 noisebasises = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
3841 str += luxOption("noisebasis", noisebasis, noisebasises, "noisebasis", "", gui, 1.3)
3843 if gui: gui.newline("level:", -2, level+1, icon_texparam)
3844 str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
3845 str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
3847 (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
3848 (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
3851 str += lux3DMapping(keyname, mat, gui, level+1)
3853 if texture.get() == "blender_musgrave":
3854 if gui: gui.newline("type:", -2, level+1, icon_texparam)
3855 mtype = luxProp(mat, keyname+".mtype", "multifractal")
3856 mtypes = ["multifractal","ridged_multifractal", "hybrid_multifractal", "hetero_terrain", "fbm"]
3857 str += luxOption("type", mtype, mtypes, "type", "", gui, 2.0)
3859 str += luxFloat("h", luxProp(mat, keyname+".h", 1.0), 0.0, 2.0, "h", "", gui, 0.5)
3860 str += luxFloat("lacu", luxProp(mat, keyname+".lacu", 2.0), 0.0, 6.0, "lacu", "", gui, 0.75)
3861 str += luxFloat("octs", luxProp(mat, keyname+".octs", 2.0), 0.0, 8.0, "octs", "", gui, 0.75)
3863 if mtype.get() == "hetero_terrain":
3864 str += luxFloat("offset", luxProp(mat, keyname+".offset", 2.0), 0.0, 6.0, "offset", "", gui, 2.0)
3865 if mtype.get() == "ridged_multifractal":
3866 str += luxFloat("offset", luxProp(mat, keyname+".offset", 2.0), 0.0, 6.0, "offset", "", gui, 1.25)
3867 str += luxFloat("gain", luxProp(mat, keyname+".gain", 2.0), 0.0, 6.0, "gain", "", gui, 0.75)
3868 if mtype.get() == "hybrid_multifractal":
3869 str += luxFloat("offset", luxProp(mat, keyname+".offset", 2.0), 0.0, 6.0, "offset", "", gui, 1.25)
3870 str += luxFloat("gain", luxProp(mat, keyname+".gain", 2.0), 0.0, 6.0, "gain", "", gui, 0.75)
3872 str += luxFloat("outscale", luxProp(mat, keyname+".outscale", 1.0), 0.0, 10.0, "iscale", "", gui, 1.0)
3873 str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 2.0, "noisesize", "", gui, 1.0)
3875 if gui: gui.newline("basis:", -2, level+1, icon_texparam)
3876 noisebasis = luxProp(mat, keyname+".noisebasis", "blender_original")
3877 noisebasises = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
3878 str += luxOption("noisebasis", noisebasis, noisebasises, "noisebasis", "", gui, 2.0)
3880 if gui: gui.newline("level:", -2, level+1, icon_texparam)
3881 str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
3882 str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
3884 (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
3885 (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
3888 str += lux3DMapping(keyname, mat, gui, level+1)
3890 if texture.get() == "blender_wood":
3891 if gui: gui.newline("noise:", -2, level+1, icon_texparam)
3893 mtype = luxProp(mat, keyname+".mtype", "bands")
3894 mtypes = ["bands","rings","bandnoise", "ringnoise"]
3895 str += luxOption("type", mtype, mtypes, "type", "", gui, 0.5)
3897 noisetype = luxProp(mat, keyname+".noisetype", "hard_noise")
3898 noisetypes = ["soft_noise","hard_noise"]
3899 str += luxOption("noisetype", noisetype, noisetypes, "noisetypes", "", gui, 0.75)
3901 str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 2.0, "noisesize", "", gui, 1.0)
3902 str += luxFloat("turbulance", luxProp(mat, keyname+".turbulance", 5.0), 0.0, 200.0, "turbulance", "", gui, 1.0)
3904 if gui: gui.newline("basis:", -2, level+1, icon_texparam)
3905 noisebasis2 = luxProp(mat, keyname+".noisebasis2", "sin")
3906 noisebasises2 = ["sin","saw","tri"]
3907 str += luxOption("noisebasis2", noisebasis2, noisebasises2, "noisebasis2", "", gui, 0.7)
3909 noisebasis = luxProp(mat, keyname+".noisebasis", "blender_original")
3910 noisebasises = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
3911 str += luxOption("noisebasis", noisebasis, noisebasises, "noisebasis", "", gui, 1.3)
3913 if gui: gui.newline("level:", -2, level+1, icon_texparam)
3914 str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
3915 str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
3917 (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
3918 (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
3921 str += lux3DMapping(keyname, mat, gui, level+1)
3923 if texture.get() == "blender_clouds":
3924 if gui: gui.newline("noise:", -2, level+1, icon_texparam)
3926 mtype = luxProp(mat, keyname+".mtype", "default")
3927 mtypes = ["default","color"]
3928 str += luxOption("type", mtype, mtypes, "type", "", gui, 0.5)
3930 noisetype = luxProp(mat, keyname+".noisetype", "hard_noise")
3931 noisetypes = ["soft_noise","hard_noise"]
3932 str += luxOption("noisetype", noisetype, noisetypes, "noisetypes", "", gui, 0.75)
3934 str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 2.0, "noisesize", "", gui, 1.0)
3935 str += luxInt("noisedepth", luxProp(mat, keyname+".noisedepth", 2), 0, 6, "noisedepth", "", gui, 1.0)
3937 if gui: gui.newline("basis:", -2, level+1, icon_texparam)
3938 noisebasis = luxProp(mat, keyname+".noisebasis", "blender_original")
3939 noisebasises = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
3940 str += luxOption("noisebasis", noisebasis, noisebasises, "noisebasis", "", gui, 1.3)
3942 if gui: gui.newline("level:", -2, level+1, icon_texparam)
3943 str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
3944 str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
3946 (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
3947 (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
3950 str += lux3DMapping(keyname, mat, gui, level+1)
3952 if texture.get() == "blender_blend":
3953 if gui: gui.newline("type:", -2, level+1, icon_texparam)
3955 mtype = luxProp(mat, keyname+".mtype", "lin")
3956 mtypes = ["lin","quad","ease","diag","sphere","halo","radial"]
3957 str += luxOption("type", mtype, mtypes, "type", "", gui, 0.5)
3959 mflag = luxProp(mat, keyname+".flag", "false")
3960 str += luxBool("flipxy", mflag, "flipXY", "", gui, 0.5)
3962 if gui: gui.newline("level:", -2, level+1, icon_texparam)
3963 str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
3964 str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
3966 (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
3967 (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
3970 str += lux3DMapping(keyname, mat, gui, level+1)
3972 if texture.get() == "blender_distortednoise":
3973 if gui: gui.newline("noise:", -2, level+1, icon_texparam)
3975 str += luxFloat("distamount", luxProp(mat, keyname+".distamount", 1.0), 0.0, 10.0, "distamount", "", gui, 1.0)
3976 str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 2.0, "noisesize", "", gui, 1.0)
3977 str += luxFloat("nabla", luxProp(mat, keyname+".nabla", 0.025), 0.000, 2.0, "nabla", "", gui, 1.0)
3979 if gui: gui.newline("distortion:", -2, level+1, icon_texparam)
3980 ntype = luxProp(mat, keyname+".type", "blender_original")
3981 ntypes = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
3982 str += luxOption("type", ntype, ntypes, "type", "", gui, 1.3)
3984 if gui: gui.newline("basis:", -2, level+1, icon_texparam)
3985 noisebasis = luxProp(mat, keyname+".noisebasis", "blender_original")
3986 noisebasises = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
3987 str += luxOption("noisebasis", noisebasis, noisebasises, "noisebasis", "", gui, 1.3)
3989 if gui: gui.newline("level:", -2, level+1, icon_texparam)
3990 str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
3991 str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
3993 (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
3994 (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
3997 str += lux3DMapping(keyname, mat, gui, level+1)
3999 if texture.get() == "blender_noise":
4000 if gui: gui.newline("level:", -2, level+1, icon_texparam)
4001 str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
4002 str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
4004 (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
4005 (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
4008 str += lux3DMapping(keyname, mat, gui, level+1)
4010 if texture.get() == "blender_magic":
4011 if gui: gui.newline("noise:", -2, level+1, icon_texparam)
4013 str += luxInt("noisedepth", luxProp(mat, keyname+".noisedepth", 2), 0.0, 10.0, "noisedepth", "", gui, 1.0)
4014 str += luxFloat("turbulance", luxProp(mat, keyname+".turbulance", 5.0), 0.0, 2.0, "turbulance", "", gui, 1.0)
4016 if gui: gui.newline("level:", -2, level+1, icon_texparam)
4017 str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
4018 str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
4020 (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
4021 (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
4024 str += lux3DMapping(keyname, mat, gui, level+1)
4026 if texture.get() == "blender_stucci":
4027 if gui: gui.newline("noise:", -2, level+1, icon_texparam)
4028 mtype = luxProp(mat, keyname+".mtype", "Plastic")
4029 mtypes = ["Plastic","Wall In","Wall Out"]
4030 str += luxOption("type", mtype, mtypes, "type", "", gui, 0.5)
4032 noisetype = luxProp(mat, keyname+".noisetype", "soft_noise")
4033 noisetypes = ["soft_noise","hard_noise"]
4034 str += luxOption("noisetype", noisetype, noisetypes, "noisetypes", "", gui, 0.75)
4036 str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 10.0, "noisesize", "", gui, 1.0)
4037 str += luxFloat("turbulance", luxProp(mat, keyname+".turbulance", 5.0), 0.0, 200.0, "turbulance", "", gui, 1.0)
4039 noisebasis = luxProp(mat, keyname+".noisebasis", "blender_original")
4040 noisebasises = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
4041 str += luxOption("noisebasis", noisebasis, noisebasises, "noisebasis", "", gui, 1.3)
4043 if gui: gui.newline("level:", -2, level+1, icon_texparam)
4044 str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
4045 str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
4047 (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
4048 (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
4051 str += lux3DMapping(keyname, mat, gui, level+1)
4053 if texture.get() == "blender_voronoi":
4054 #if gui: gui.newline("distmetric:", -2, level+1, icon_texparam)
4055 mtype = luxProp(mat, keyname+".distmetric", "actual_distance")
4056 mtypes = ["actual_distance","distance_squared","manhattan", "chebychev", "minkovsky_half", "minkovsky_four", "minkovsky"]
4057 str += luxOption("distmetric", mtype, mtypes, "distmetric", "", gui, 1.1)
4059 if gui: gui.newline("param:", -2, level+1, icon_texparam)
4060 str += luxFloat("minkovsky_exp", luxProp(mat, keyname+".minkovsky_exp", 2.5), 0.001, 10.0, "minkovsky_exp", "", gui, 1.0)
4061 str += luxFloat("outscale", luxProp(mat, keyname+".outscale", 1.0), 0.01, 10.0, "outscale", "", gui, 1.0)
4062 str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 2.0, "noisesize", "", gui, 1.0)
4063 str += luxFloat("nabla", luxProp(mat, keyname+".nabla", 0.025), 0.001, 0.1, "nabla", "", gui, 1.0)
4064 if gui: gui.newline("wparam:", -2, level+1, icon_texparam)
4065 str += luxFloat("w1", luxProp(mat, keyname+".w1", 1.0), -2.0, 2.0, "w1", "", gui, 1.0)
4066 str += luxFloat("w2", luxProp(mat, keyname+".w2", 0.0), -2.0, 2.0, "w2", "", gui, 1.0)
4067 str += luxFloat("w3", luxProp(mat, keyname+".w3", 0.0), -2.0, 2.0, "w3", "", gui, 1.0)
4068 str += luxFloat("w4", luxProp(mat, keyname+".w4", 0.0), -2.0, 2.0, "w4", "", gui, 1.0)
4070 if gui: gui.newline("level:", -2, level+1, icon_texparam)
4071 str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
4072 str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
4074 (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
4075 (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
4078 str += lux3DMapping(keyname, mat, gui, level+1)
4082 return (str+"\n", " \"texture %s\" [\"%s\"]"%(name, texname))
4085 def luxSpectrumTexture(name, key, default, max, caption, hint, mat, gui, level=0):
4087 if gui: gui.newline(caption, 4, level, icon_col, scalelist([0.5,0.6,0.5],2.0/(level+2)))
4089 keyname = "%s:%s"%(key, name)
4090 texname = "%s:%s"%(mat.getName(), keyname)
4091 value = luxProp(mat, keyname, default)
4092 link = luxRGB(name, value, max, "", hint, gui, 2.0)
4093 tex = luxProp(mat, keyname+".textured", False)
4094 if gui: Draw.Toggle("T", evtLuxGui, gui.x, gui.y-gui.h, gui.h, gui.h, tex.get()=="true", "use texture", lambda e,v:tex.set(["false","true"][bool(v)]))
4095 if tex.get()=="true":
4096 if gui: gui.newline("", -2)
4097 (str, link) = luxTexture(name, key, "color", default, 0, max, caption, hint, mat, gui, level+1)
4098 if value.getRGB() != (1.0, 1.0, 1.0):
4099 if str == "": # handle special case if texture is a just a constant
4100 str += "Texture \"%s\" \"color\" \"scale\" \"color tex1\" [%s] \"color tex2\" [%s]\n"%(texname+".scale", (link.rpartition("[")[2])[0:-1], value.get())
4101 else: str += "Texture \"%s\" \"color\" \"scale\" \"texture tex1\" [\"%s\"] \"color tex2\" [%s]\n"%(texname+".scale", texname, value.get())
4102 link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
4105 def luxLightSpectrumTexture(name, key, default, max, caption, hint, mat, gui, level=0):
4106 #if gui: gui.newline(caption, 4, level, icon_emission, scalelist([0.6,0.5,0.5],2.0/(level+2)))
4108 keyname = "%s:%s"%(key, name)
4109 texname = "%s:%s"%(mat.getName(), keyname)
4110 (str, link) = luxTexture(name, key, "color", default, 0, max, caption, hint, mat, gui, level+1, 0, 1)
4113 def luxFloatTexture(name, key, default, min, max, caption, hint, mat, gui, level=0):
4115 if gui: gui.newline(caption, 4, level, icon_float, scalelist([0.5,0.5,0.6],2.0/(level+2)))
4117 keyname = "%s:%s"%(key, name)
4118 texname = "%s:%s"%(mat.getName(), keyname)
4119 value = luxProp(mat, keyname, default)
4120 link = luxFloat(name, value, min, max, "", hint, gui, 2.0)
4121 tex = luxProp(mat, keyname+".textured", False)
4122 if gui: Draw.Toggle("T", evtLuxGui, gui.x, gui.y-gui.h, gui.h, gui.h, tex.get()=="true", "use texture", lambda e,v:tex.set(["false","true"][bool(v)]))
4123 if tex.get()=="true":
4124 if gui: gui.newline("", -2)
4125 (str, link) = luxTexture(name, key, "float", default, min, max, caption, hint, mat, gui, level+1)
4126 if value.get() != 1.0:
4127 if str == "": # handle special case if texture is a just a constant
4128 str += "Texture \"%s\" \"float\" \"scale\" \"float tex1\" [%s] \"float tex2\" [%s]\n"%(texname+".scale", (link.rpartition("[")[2])[0:-1], value.get())
4129 else: str += "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" [\"%s\"] \"float tex2\" [%s]\n"%(texname+".scale", texname, value.get())
4130 link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
4133 def luxFloatSliderTexture(name, key, default, min, max, caption, hint, mat, gui, level=0):
4135 if gui: gui.newline(caption, 4, level, icon_float, scalelist([0.5,0.5,0.6],2.0/(level+2)))
4137 keyname = "%s:%s"%(key, name)
4138 texname = "%s:%s"%(mat.getName(), keyname)
4139 value = luxProp(mat, keyname, default)
4140 link = luxFloat(name, value, min, max, caption, hint, gui, 2.0, 1)
4141 tex = luxProp(mat, keyname+".textured", False)
4142 if gui: Draw.Toggle("T", evtLuxGui, gui.x, gui.y-gui.h, gui.h, gui.h, tex.get()=="true", "use texture", lambda e,v:tex.set(["false","true"][bool(v)]))
4143 if tex.get()=="true":
4144 if gui: gui.newline("", -2)
4145 (str, link) = luxTexture(name, key, "float", default, min, max, caption, hint, mat, gui, level+1)
4146 if value.get() != 1.0:
4147 if str == "": # handle special case if texture is a just a constant
4148 str += "Texture \"%s\" \"float\" \"scale\" \"float tex1\" [%s] \"float tex2\" [%s]\n"%(texname+".scale", (link.rpartition("[")[2])[0:-1], value.get())
4149 else: str += "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" [\"%s\"] \"float tex2\" [%s]\n"%(texname+".scale", texname, value.get())
4150 link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
4154 def luxExponentTexture(name, key, default, min, max, caption, hint, mat, gui, level=0):
4156 if gui: gui.newline(caption, 4, level, icon_float, scalelist([0.5,0.5,0.6],2.0/(level+2)))
4158 keyname = "%s:%s"%(key, name)
4159 texname = "%s:%s"%(mat.getName(), keyname)
4160 value = luxProp(mat, keyname, default)
4162 if(value.get() == None): value.set(0.002)
4164 # link = luxFloat(name, value, min, max, "", hint, gui, 2.0)
4166 r = gui.getRect(2.0, 1)
4167 Draw.Number("", evtLuxGui, r[0], r[1], r[2], r[3], float(1.0/value.getFloat()), 1.0, 1000000.0, hint, lambda e,v: value.set(1.0/v))
4168 link = " \"float %s\" [%f]"%(name, value.getFloat())
4170 tex = luxProp(mat, keyname+".textured", False)
4171 if gui: Draw.Toggle("T", evtLuxGui, gui.x, gui.y-gui.h, gui.h, gui.h, tex.get()=="true", "use texture", lambda e,v:tex.set(["false","true"][bool(v)]))
4172 if tex.get()=="true":
4173 if gui: gui.newline("", -2)
4174 (str, link) = luxTexture(name, key, "float", default, min, max, caption, hint, mat, gui, level+1)
4175 if value.get() != 1.0:
4176 if str == "": # handle special case if texture is a just a constant
4177 str += "Texture \"%s\" \"float\" \"scale\" \"float tex1\" [%s] \"float tex2\" [%s]\n"%(texname+".scale", (link.rpartition("[")[2])[0:-1], value.get())
4178 else: str += "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" [\"%s\"] \"float tex2\" [%s]\n"%(texname+".scale", texname, value.get())
4179 link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
4183 def luxDispFloatTexture(name, key, default, min, max, caption, hint, mat, gui, level=0):
4185 if gui: gui.newline(caption, 4, level, icon_float, scalelist([0.5,0.5,0.6],2.0/(level+2)))
4187 keyname = "%s:%s"%(key, name)
4188 texname = "%s:%s"%(mat.getName(), keyname)
4189 value = luxProp(mat, keyname, default)
4190 link = luxFloat(name, value, min, max, "", hint, gui, 2.0)
4191 tex = luxProp(mat, keyname+".textured", False)
4192 if gui: Draw.Toggle("T", evtLuxGui, gui.x, gui.y-gui.h, gui.h, gui.h, tex.get()=="true", "use texture", lambda e,v:tex.set(["false","true"][bool(v)]))
4193 if tex.get()=="true":
4194 if gui: gui.newline("", -2)
4195 (str, link) = luxTexture(name, key, "float", default, min, max, caption, hint, mat, gui, level+1)
4196 str += "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" [\"%s\"] \"float tex2\" [%s]\n"%(texname+".scale", texname, value.get())
4197 link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
4200 def luxIORFloatTexture(name, key, default, min, max, caption, hint, mat, gui, level=0):
4202 iornames = ["0Z *** Gases @ 0 C ***", "01 - Vacuum", "02 - Air @ STP", "03 - Air", "04 - Helium", "05 - Hydrogen", "06 - Carbon dioxide",
4203 "1Z *** LIQUIDS @ 20 C ***", "11 - Benzene", "12 - Water", "13 - Ethyl alcohol", "14 - Carbon tetrachloride", "15 - Carbon disulfide",
4204 "2Z *** SOLIDS at room temperature ***", "21 - Diamond", "22 - Strontium titanate", "23 - Amber", "24 - Fused silica glass", "25 - sodium chloride",
4205 "3Z *** OTHER Materials ***", "31 - Pyrex (Borosilicate glass)", "32 - Ruby", "33 - Water ice", "34 - Cryolite", "35 - Acetone", "36 - Ethanol", "37 - Teflon", "38 - Glycerol", "39 - Acrylic glass", "40 - Rock salt", "41 - Crown glass (pure)", "42 - Salt (NaCl)", "43 - Polycarbonate", "44 - PMMA", "45 - PETg", "46 - PET", "47 - Flint glass (pure)", "48 - Crown glass (impure)", "49 - Fused Quartz", "50 - Bromine", "51 - Flint glass (impure)", "52 - Cubic zirconia", "53 - Moissanite", "54 - Cinnabar (Mercury sulfide)", "55 - Gallium(III) prosphide", "56 - Gallium(III) arsenide", "57 - Silicon"]
4206 iorvals = [1.0, 1.0, 1.0002926, 1.000293, 1.000036, 1.000132, 1.00045,
4207 1.501, 1.501, 1.333, 1.361, 1.461, 1.628,
4208 2.419, 2.419, 2.41, 1.55, 1.458, 1.50,
4209 1.470, 1.470, 1.760, 1.31, 1.388, 1.36, 1.36, 1.35, 1.4729, 1.490, 1.516, 1.50, 1.544, 1.584, 1.4893, 1.57, 1.575, 1.60, 1.485, 1.46, 1.661, 1.523, 2.15, 2.419, 2.65, 3.02, 3.5, 3.927, 4.01]
4212 if gui: gui.newline(caption, 4, level, icon_float, scalelist([0.5,0.5,0.6],2.0/(level+2)))
4214 keyname = "%s:%s"%(key, name)
4215 texname = "%s:%s"%(mat.getName(), keyname)
4216 value = luxProp(mat, keyname, default)
4218 iorusepreset = luxProp(mat, keyname+".iorusepreset", "true")
4219 luxBool("iorusepreset", iorusepreset, "Preset", "Select from a list of predefined presets", gui, 0.4)
4221 if(iorusepreset.get() == "true"):
4222 iorpreset = luxProp(mat, keyname+".iorpreset", "24 - Fused silica glass")
4224 def setIor(i, value, preset, tree, dict): # callback function to set ior value after selection
4227 preset.set(getTreeNameById(tree, i))
4228 iortree = [ ("LIQUIDS", [("Acetone", 1), ("Alcohol, Ethyl (grain)", 2), ("Alcohol, Methyl (wood)", 3), ("Beer", 4), ("Benzene", 5), ("Carbon tetrachloride", 6), ("Carbon disulfide", 7), ("Carbonated Beverages", 8), ("Chlorine (liq)", 9), ("Cranberry Juice (25%)", 10), ("Glycerin", 11), ("Honey, 13% water content", 12), ("Honey, 17% water content", 13), ("Honey, 21% water content", 14), ("Ice", 15), ("Milk", 16), ("Oil, Clove", 17), ("Oil, Lemon", 18), ("Oil, Neroli", 19), ("Oil, Orange", 20), ("Oil, Safflower", 21), ("Oil, vegetable (50 C)", 22), ("Oil of Wintergreen", 23), ("Rum, White", 24), ("Shampoo", 25), ("Sugar Solution 30%", 26), ("Sugar Solution 80%", 27), ("Turpentine", 28), ("Vodka", 29), ("Water (0 C)", 30), ("Water (100 C)", 31), ("Water (20 C)", 32), ("Whisky", 33) ] ), ("GASES(0C)", [("Vacuum", 101), ("Air @ STP", 102), ("Air", 103), ("Helium", 104), ("Hydrogen", 105), ("Carbon dioxide", 106) ]), ("TRANSPARENT", [("Eye, Aqueous humor", 201), ("Eye, Cornea", 202), ("Eye, Lens", 203), ("Eye, Vitreous humor", 204), ("Glass, Arsenic Trisulfide", 205), ("Glass, Crown (common)", 206), ("Glass, Flint, 29% lead", 207), ("Glass, Flint, 55% lead", 208), ("Glass, Flint, 71% lead", 209), ("Glass, Fused Silica", 210), ("Glass, Pyrex", 211), ("Lucite", 212), ("Nylon", 213), ("Obsidian", 214), ("Plastic", 215), ("Plexiglas", 216), ("Salt", 217) ]), ("GEMSTONES", [("Agate", 301), ("Alexandrite", 302), ("Almandine", 303), ("Amber", 304), ("Amethyst", 305), ("Ammolite", 306), ("Andalusite", 307), ("Apatite", 308), ("Aquamarine", 309), ("Axenite", 310), ("Beryl", 311), ("Beryl, Red", 312), ("Chalcedony", 313), ("Chrome Tourmaline", 314), ("Citrine", 315), ("Clinohumite", 316), ("Coral", 317), ("Crystal", 318), ("Crysoberyl, Catseye", 319), ("Danburite", 320), ("Diamond", 321), ("Emerald", 322), ("Emerald Catseye", 323), ("Flourite", 324), ("Garnet, Grossular", 325), ("Garnet, Andradite", 326), ("Garnet, Demantiod", 327), ("Garnet, Mandarin", 328), ("Garnet, Pyrope", 329), ("Garnet, Rhodolite", 330), ("Garnet, Tsavorite", 331), ("Garnet, Uvarovite", 332), ("Hauyn", 333), ("Iolite", 334), ("Jade, Jadeite", 335), ("Jade, Nephrite", 336), ("Jet", 337), ("Kunzite", 338), ("Labradorite", 339), ("Lapis Lazuli", 340), ("Moonstone", 341), ("Morganite", 342), ("Obsidian", 343), ("Opal, Black", 344), ("Opal, Fire", 345), ("Opal, White", 346), ("Oregon Sunstone", 347), ("Padparadja", 348), ("Pearl", 349), ("Peridot", 350), ("Quartz", 351), ("Ruby", 352), ("Sapphire", 353), ("Sapphire, Star", 354), ("Spessarite", 355), ("Spinel", 356), ("Spinel, Blue", 357), ("Spinel, Red", 358), ("Star Ruby", 359), ("Tanzanite", 360), ("Topaz", 361), ("Topaz, Imperial", 362), ("Tourmaline", 363), ("Tourmaline, Blue", 364), ("Tourmaline, Catseye", 365), ("Tourmaline, Green", 366), ("Tourmaline, Paraiba", 367), ("Tourmaline, Red", 368), ("Zircon", 369), ("Zirconia, Cubic", 370) ] ), ("OTHER", [("Pyrex (Borosilicate glass)", 401), ("Ruby", 402), ("Water ice", 403), ("Cryolite", 404), ("Acetone", 405), ("Ethanol", 406), ("Teflon", 407), ("Glycerol", 408), ("Acrylic glass", 409), ("Rock salt", 410), ("Crown glass (pure)", 411), ("Salt (NaCl)", 412), ("Polycarbonate", 413), ("PMMA", 414), ("PETg", 415), ("PET", 416), ("Flint glass (pure)", 417), ("Crown glass (impure)", 418), ("Fused Quartz", 419), ("Bromine", 420), ("Flint glass (impure)", 421), ("Cubic zirconia", 422), ("Moissanite", 423), ("Cinnabar (Mercury sulfide)", 424), ("Gallium(III) prosphide", 425), ("Gallium(III) arsenide", 426), ("Silicon", 427) ] ) ]
4229 iordict = {1:1.36, 2:1.36, 3:1.329, 4:1.345, 5:1.501, 6:1.000132, 7:1.00045, 8:1.34, 9:1.385, 10:1.351, 11:1.473, 12:1.504, 13:1.494, 14:1.484, 15:1.309, 16:1.35, 17:1.535, 18:1.481, 19:1.482, 20:1.473, 21:1.466, 22:1.47, 23:1.536, 24:1.361, 25:1.362, 26:1.38, 27:1.49, 28:1.472, 29:1.363, 30:1.33346, 31:1.31766, 32:1.33283, 33:1.356, 101:1.0, 102:1.0002926, 103:1.000293, 104:1.000036, 105:1.000132, 106:1.00045, 201:1.33, 202:1.38, 203:1.41, 204:1.34, 205:2.04, 206:1.52, 207:1.569, 208:1.669, 209:1.805, 210:1.459, 211:1.474, 212:1.495, 213:1.53, 214:1.50, 215:1.460, 216:1.488, 217:1.516, 301:1.544, 302:1.746, 303:1.75, 304:1.539, 305:1.532, 306:1.52, 307:1.629, 308:1.632, 309:1.567, 310:1.674, 311:1.57, 312:1.570, 313:1.544, 314:1.61, 315:1.532, 316:1.625, 317:1.486, 318:2.000, 319:1.746, 320:1.627, 321:2.417, 322:1.560, 323:1.560, 324:1.434, 325:1.72, 326:1.88, 327:1.880, 328:1.790, 329:1.73, 330:1.740, 331:1.739, 332:1.74, 333:1.490, 334:1.522, 335:1.64, 336:1.600, 337:1.660, 338:1.660, 339:1.560, 340:1.50, 341:1.518, 342:1.585, 343:1.50, 344:1.440, 345:1.430, 346:1.440, 347:1.560, 348:1.760, 349:1.53, 350:1.635, 351:1.544, 352:1.757, 353:1.757, 354:1.760, 355:1.79, 356:1.712, 357:1.712, 358:1.708, 359:1.76, 360:1.690, 361:1.607, 362:1.605, 363:1.603, 364:1.61, 365:1.61, 366:1.61, 367:1.61, 368:1.61, 369:1.777, 370:2.173, 401:1.47, 402:1.76, 403:1.31, 404:1.388, 405:1.36, 406:1.36, 407:1.35, 408:1.4729, 409:1.49, 410:1.516, 411:1.5, 412:1.544, 413:1.584, 414:1.4893, 415:1.57, 416:1.575, 417:1.6, 418:1.485, 419:1.46, 420:1.661, 421:1.523, 422:2.15, 423:2.419, 424:2.65, 425:3.02, 426:3.5, 427:3.927}
4230 r = gui.getRect(1.6, 1)
4231 Draw.Button(iorpreset.get(), evtLuxGui, r[0], r[1], r[2], r[3], "select IOR preset", lambda e,v: setIor(Draw.PupTreeMenu(iortree), value, iorpreset, iortree, iordict))
4232 link = luxFloat(name, value, min, max, "IOR", hint, None, 1.6)
4234 link = luxFloat(name, value, min, max, "IOR", hint, gui, 1.6, 1)
4236 tex = luxProp(mat, keyname+".textured", False)
4237 if gui: Draw.Toggle("T", evtLuxGui, gui.x, gui.y-gui.h, gui.h, gui.h, tex.get()=="true", "use texture", lambda e,v:tex.set(["false","true"][bool(v)]))
4238 if tex.get()=="true":
4239 if gui: gui.newline("", -2)
4240 (str, link) = luxTexture(name, key, "float", default, min, max, caption, hint, mat, gui, level+1)
4241 if value.get() != 1.0:
4242 str += "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" [\"%s\"] \"float tex2\" [%s]\n"%(texname+".scale", texname, value.get())
4243 link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
4246 def luxCauchyBFloatTexture(name, key, default, min, max, caption, hint, mat, gui, level=0):
4248 cauchybnames = ["01 - Fused silica glass", "02 - Borosilicate glass BK7", "03 - Hard crown glass K5", "04 - Barium crown glass BaK4", "05 - Barium flint glass BaF10", "06 - Dense flint glass SF10" ]
4249 cauchybvals = [ 0.00354, 0.00420, 0.00459, 0.00531, 0.00743, 0.01342 ]
4252 if gui: gui.newline(caption, 4, level, icon_float, scalelist([0.5,0.5,0.6],2.0/(level+2)))
4254 keyname = "%s:%s"%(key, name)
4255 texname = "%s:%s"%(mat.getName(), keyname)
4256 value = luxProp(mat, keyname, default)
4258 cauchybusepreset = luxProp(mat, keyname+".cauchybusepreset", "true")
4259 luxBool("cauchybusepreset", cauchybusepreset, "Preset", "Select from a list of predefined presets", gui, 0.4)
4261 if(cauchybusepreset.get() == "true"):
4262 cauchybpreset = luxProp(mat, keyname+".cauchybpreset", "01 - Fused silica glass")
4263 luxOption("cauchybpreset", cauchybpreset, cauchybnames, " PRESET", "select CauchyB preset", gui, 1.6)
4264 idx = cauchybnames.index(cauchybpreset.get())
4265 value.set(cauchybvals[idx])
4266 link = luxFloat(name, value, min, max, "cauchyb", hint, None, 1.6)
4268 link = luxFloat(name, value, min, max, "cauchyb", hint, gui, 1.6, 1)
4270 tex = luxProp(mat, keyname+".textured", False)
4271 if gui: Draw.Toggle("T", evtLuxGui, gui.x, gui.y-gui.h, gui.h, gui.h, tex.get()=="true", "use texture", lambda e,v:tex.set(["false","true"][bool(v)]))
4272 if tex.get()=="true":
4273 if gui: gui.newline("", -2)
4274 (str, link) = luxTexture(name, key, "float", default, min, max, caption, hint, mat, gui, level+1)
4275 if value.get() != 1.0:
4276 str += "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" [\"%s\"] \"float tex2\" [%s]\n"%(texname+".scale", texname, value.get())
4277 link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
4280 def luxLight(name, kn, mat, gui, level):
4282 if name != "": gui.newline(name+":", 10, level)
4283 else: gui.newline("color:", 0, level+1)
4284 (str,link) = luxLightSpectrumTexture("L", kn+"light", "1.0 1.0 1.0", 1.0, "Spectrum", "", mat, gui, level+1)
4285 if gui: gui.newline("")
4286 link += luxFloat("power", luxProp(mat, kn+"light.power", 100.0), 0.0, 10000.0, "Power(W)", "AreaLight Power in Watts", gui)
4287 link += luxFloat("efficacy", luxProp(mat, kn+"light.efficacy", 17.0), 0.0, 100.0, "Efficacy(lm/W)", "Efficacy Luminous flux/watt", gui)
4288 if gui: gui.newline("")
4289 link += luxFloat("gain", luxProp(mat, kn+"light.gain", 1.0), 0.0, 100.0, "gain", "Gain/scale multiplier", gui)
4290 lightgroup = luxProp(mat, kn+"light.lightgroup", "default")
4291 luxString("lightgroup", lightgroup, "group", "assign light to a named light-group", gui, 1.0)
4293 if gui: gui.newline("Photometric")
4294 pm = luxProp(mat, kn+"light.usepm", "false")
4295 luxCollapse("photometric", pm, "Photometric Diagram", "Enable Photometric Diagram options", gui, 2.0)
4297 if(pm.get()=="true"):
4298 pmtype = luxProp(mat, kn+"light.pmtype", "IESna")
4299 pmtypes = ["IESna", "imagemap"]
4300 luxOption("type", pmtype, pmtypes, "type", "Choose Photometric data type to use", gui, 0.6)
4301 if(pmtype.get() == "imagemap"):
4302 map = luxProp(mat, kn+"light.pmmapname", "")
4303 link += luxFile("mapname", map, "map-file", "filename of the photometric map", gui, 1.4)
4304 if(pmtype.get() == "IESna"):
4305 map = luxProp(mat, kn+"light.pmiesname", "")
4306 link += luxFile("iesname", map, "ies-file", "filename of the IES photometric data file", gui, 1.4)
4308 has_bump_options = 0
4309 has_object_options = 1
4312 def luxLamp(name, kn, mat, gui, level):
4314 if name != "": gui.newline(name+":", 10, level)
4315 else: gui.newline("color:", 0, level+1)
4316 # if gui: gui.newline("", 10, level)
4317 (str,link) = luxLightSpectrumTexture("L", kn+"light", "1.0 1.0 1.0", 1.0, "Spectrum", "", mat, gui, level+1)
4318 if gui: gui.newline("")
4319 link += luxFloat("gain", luxProp(mat, kn+"light.gain", 1.0), 0.0, 100.0, "gain", "Gain/scale multiplier", gui)
4320 lightgroup = luxProp(mat, kn+"light.lightgroup", "default")
4321 luxString("lightgroup", lightgroup, "group", "assign light to a named light-group", gui, 1.0)
4323 if gui: gui.newline("Photometric")
4324 pm = luxProp(mat, kn+"light.usepm", "false")
4325 luxBool("photometric", pm, "Photometric Diagram", "Enable Photometric Diagram options", gui, 2.0)
4327 if(pm.get()=="true"):
4328 pmtype = luxProp(mat, kn+"light.pmtype", "IESna")
4329 pmtypes = ["IESna", "imagemap"]
4330 luxOption("type", pmtype, pmtypes, "type", "Choose Photometric data type to use", gui, 0.6)
4331 if(pmtype.get() == "imagemap"):
4332 map = luxProp(mat, kn+"light.pmmapname", "")
4333 link += luxFile("mapname", map, "map-file", "filename of the photometric map", gui, 1.4)
4334 if(pmtype.get() == "IESna"):
4335 map = luxProp(mat, kn+"light.pmiesname", "")
4336 link += luxFile("iesname", map, "ies-file", "filename of the IES photometric data file", gui, 1.4)
4338 link += luxBool("flipz", luxProp(mat, kn+"light.flipZ", "true"), "Flip Z", "Flip Z direction in mapping", gui, 2.0)
4342 def luxSpot(name, kn, mat, gui, level):
4344 if name != "": gui.newline(name+":", 10, level)
4345 else: gui.newline("color:", 0, level+1)
4346 # if gui: gui.newline("", 10, level)
4347 (str,link) = luxLightSpectrumTexture("L", kn+"light", "1.0 1.0 1.0", 1.0, "Spectrum", "", mat, gui, level+1)
4348 if gui: gui.newline("")
4349 link += luxFloat("gain", luxProp(mat, kn+"light.gain", 1.0), 0.0, 100.0, "gain", "Gain/scale multiplier", gui)
4350 lightgroup = luxProp(mat, kn+"light.lightgroup", "default")
4351 luxString("lightgroup", lightgroup, "group", "assign light to a named light-group", gui, 1.0)
4353 if gui: gui.newline("Projection")
4354 proj = luxProp(mat, kn+"light.usetexproj", "false")
4355 luxBool("projection", proj, "Texture Projection", "Enable imagemap texture projection", gui, 2.0)
4357 if(proj.get() == "true"):
4358 map = luxProp(mat, kn+"light.pmmapname", "")
4359 link += luxFile("mapname", map, "map-file", "filename of the photometric map", gui, 2.0)
4364 def Preview_Sphereset(mat, kn, state):
4366 luxProp(mat, kn+"prev_sphere", "true").set("true")
4367 luxProp(mat, kn+"prev_plane", "false").set("false")
4368 luxProp(mat, kn+"prev_torus", "false").set("false")
4369 def Preview_Planeset(mat, kn, state):
4371 luxProp(mat, kn+"prev_sphere", "true").set("false")
4372 luxProp(mat, kn+"prev_plane", "false").set("true")
4373 luxProp(mat, kn+"prev_torus", "false").set("false")
4374 def Preview_Torusset(mat, kn, state):
4376 luxProp(mat, kn+"prev_sphere", "true").set("false")
4377 luxProp(mat, kn+"prev_plane", "false").set("false")
4378 luxProp(mat, kn+"prev_torus", "false").set("true")
4380 def Preview_Update(mat, kn, defLarge, defType, texName, name, level):
4381 #print "%s %s %s %s %s %s %s" % (mat, kn, defLarge, defType, texName, name, level)
4386 Blender.Window.WaitCursor(True)
4387 scn = Scene.GetCurrent()
4389 # Size of preview thumbnail
4390 thumbres = 110 # default 110x110
4392 large = luxProp(mat, kn+"prev_large", "true")
4394 large = luxProp(mat, kn+"prev_large", "false")
4395 if(large.get() == "true"):
4396 thumbres = 140 # small 140x140
4398 thumbbuf = thumbres*thumbres*3
4400 # consolebin = luxProp(scn, "luxconsole", "").get()
4401 consolebin = Blender.sys.dirname(luxProp(scn, "lux", "").get()) + os.sep + "luxconsole"
4402 if osys.platform == "win32": consolebin = consolebin + ".exe"
4404 PIPE = subprocess.PIPE
4405 p = subprocess.Popen((consolebin, '-b', '-'), bufsize=thumbbuf, stdin=PIPE, stdout=PIPE, stderr=PIPE)
4407 # Unremark to write debugging output to file
4408 # p.stdin = open('c:\preview.lxs', 'w')
4411 prev_sphere = luxProp(mat, kn+"prev_sphere", "true")
4412 prev_plane = luxProp(mat, kn+"prev_plane", "false")
4413 prev_torus = luxProp(mat, kn+"prev_torus", "false")
4415 prev_sphere = luxProp(mat, kn+"prev_sphere", "false")
4416 prev_plane = luxProp(mat, kn+"prev_plane", "true")
4417 prev_torus = luxProp(mat, kn+"prev_torus", "false")
4419 prev_sphere = luxProp(mat, kn+"prev_sphere", "false")
4420 prev_plane = luxProp(mat, kn+"prev_plane", "false")
4421 prev_torus = luxProp(mat, kn+"prev_torus", "true")
4424 if luxProp(mat, kn+"prev_zoom", "false").get() == "true":
4425 p.stdin.write('LookAt 0.250000 -1.500000 0.750000 0.250000 -0.500000 0.750000 0.000000 0.000000 1.000000\nCamera "perspective" "float fov" [22.5]\n')
4427 p.stdin.write('LookAt 0.0 -3.0 0.5 0.0 -2.0 0.5 0.0 0.0 1.0\nCamera "perspective" "float fov" [22.5]\n')
4429 p.stdin.write('Film "fleximage" "integer xresolution" [%i] "integer yresolution" [%i] "integer displayinterval" [3] "integer ldr_writeinterval" [3600] "string tonemapper" ["reinhard"] "integer haltspp" [1] "integer reject_warmup" [64] "bool write_tonemapped_tga" ["false"] "bool write_untonemapped_exr" ["false"] "bool write_tonemapped_exr" ["false"] "bool write_untonemapped_igi" ["false"] "bool write_tonemapped_igi" ["false"] "bool write_png" ["false"] "string filename" ["luxblend-preview"] \n'%(thumbres, thumbres))
4430 p.stdin.write('PixelFilter "sinc"\n')
4432 scn = Scene.GetCurrent()
4433 defprevmat = luxProp(scn, "defprevmat", "high")
4434 quality = luxProp(mat, kn+"prev_quality", defprevmat.get())
4435 if quality.get()=="low":
4436 p.stdin.write('Sampler "lowdiscrepancy" "string pixelsampler" ["hilbert"] "integer pixelsamples" [2]\n')
4437 elif quality.get()=="medium":
4438 p.stdin.write('Sampler "lowdiscrepancy" "string pixelsampler" ["hilbert"] "integer pixelsamples" [4]\n')
4439 elif quality.get()=="high":
4440 p.stdin.write('Sampler "lowdiscrepancy" "string pixelsampler" ["hilbert"] "integer pixelsamples" [8]\n')
4442 p.stdin.write('Sampler "lowdiscrepancy" "string pixelsampler" ["hilbert"] "integer pixelsamples" [32]\n')
4444 if(prev_plane.get()=="false"):
4445 p.stdin.write('SurfaceIntegrator "distributedpath" "integer directsamples" [1] "integer diffusereflectdepth" [1] "integer diffusereflectsamples" [4] "integer diffuserefractdepth" [4] "integer diffuserefractsamples" [1] "integer glossyreflectdepth" [1] "integer glossyreflectsamples" [2] "integer glossyrefractdepth" [4] "integer glossyrefractsamples" [1] "integer specularreflectdepth" [2] "integer specularrefractdepth" [4]\n')
4447 p.stdin.write('SurfaceIntegrator "distributedpath" "integer directsamples" [1] "integer diffusereflectdepth" [0] "integer diffusereflectsamples" [0] "integer diffuserefractdepth" [0] "integer diffuserefractsamples" [0] "integer glossyreflectdepth" [0] "integer glossyreflectsamples" [0] "integer glossyrefractdepth" [0] "integer glossyrefractsamples" [0] "integer specularreflectdepth" [1] "integer specularrefractdepth" [1]\n')
4449 p.stdin.write('WorldBegin\n')
4450 if(prev_sphere.get()=="true"):
4451 p.stdin.write('AttributeBegin\nTransform [0.5 0.0 0.0 0.0 0.0 0.5 0.0 0.0 0.0 0.0 0.5 0.0 0.0 0.0 0.5 1.0]\n')
4452 elif (prev_plane.get()=="true"):
4453 p.stdin.write('AttributeBegin\nTransform [0.649999976158 0.0 0.0 0.0 0.0 4.90736340453e-008 0.649999976158 0.0 0.0 -0.649999976158 4.90736340453e-008 0.0 0.0 0.0 0.5 1.0]\n')
4455 p.stdin.write('AttributeBegin\nTransform [0.35 -0.35 0.0 0.0 0.25 0.25 0.35 0.0 -0.25 -0.25 0.35 0.0 0.0 0.0 0.5 1.0]\n')
4456 obwidth = luxProp(mat, kn+"prev_obwidth", 1.0)
4458 p.stdin.write('TransformBegin\n')
4459 p.stdin.write('Scale %f %f %f\n'%(obw,obw,obw))
4461 print "texture "+texName+" "+name
4462 (str, link) = luxTexture(texName, name, "color", "1.0 1.0 1.0", None, None, "", "", mat, None, 0, level)
4463 link = link.replace(" "+texName+"\"", " Kd\"") # swap texture name to "Kd"
4464 p.stdin.write(str+"\n")
4465 p.stdin.write("Material \"matte\" "+link+"\n")
4468 p.stdin.write(luxMaterial(mat))
4469 link = luxProp(mat,"link","").get()
4470 if kn!="": link = link.rstrip("\"")+":"+kn.strip(".:")+"\""
4471 p.stdin.write(link+'\n')
4472 p.stdin.write('TransformEnd\n')
4474 if(prev_sphere.get()=="true"):
4475 p.stdin.write('Shape "sphere" "float radius" [1.0]\n')
4476 elif (prev_plane.get()=="true"):
4477 p.stdin.write(' Shape "trianglemesh" "integer indices" [ 0 1 2 0 2 3 ] "point P" [ 1.0 1.0 0.0 -1.0 1.0 0.0 -1.0 -1.0 -0.0 1.0 -1.0 -0.0 ] "float uv" [ 1.0 1.0 0.0 1.0 0.0 0.0 1.0 0.0 ]\n')
4478 elif (prev_torus.get()=="true"):
4479 p.stdin.write('Shape "torus" "float radius" [1.0]\n')
4480 p.stdin.write('AttributeEnd\n')
4481 # Checkerboard floor
4482 if(prev_plane.get()=="false"):
4483 p.stdin.write('AttributeBegin\nTransform [5.0 0.0 0.0 0.0 0.0 5.0 0.0 0.0 0.0 0.0 5.0 0.0 0.0 0.0 0.0 1.0]\n')
4484 p.stdin.write('Texture "checks" "color" "checkerboard"')
4485 p.stdin.write('"integer dimension" [2] "string aamode" ["supersample"] "color tex1" [0.9 0.9 0.9] "color tex2" [0.0 0.0 0.0]')
4486 p.stdin.write('"string mapping" ["uv"] "float uscale" [36.8] "float vscale" [36.0]\n')
4487 p.stdin.write('Material "matte" "texture Kd" ["checks"]\n')
4488 p.stdin.write('Shape "loopsubdiv" "integer nlevels" [3] "bool dmnormalsmooth" ["true"] "bool dmsharpboundary" ["false"] ')
4489 p.stdin.write('"integer indices" [ 0 1 2 0 2 3 1 0 4 1 4 5 5 4 6 5 6 7 ]')
4490 p.stdin.write('"point P" [ 1.000000 1.000000 0.000000 -1.000000 1.000000 0.000000 -1.000000 -1.000000 0.000000 1.000000 -1.000000 0.000000 1.000000 3.000000 0.000000 -1.000000 3.000000 0.000000 1.000000 3.000000 2.000000 -1.000000 3.000000 2.000000')
4491 p.stdin.write('] "normal N" [ 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 -0.707083 0.707083 0.000000 -0.707083 0.707083 0.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000')
4492 p.stdin.write('] "float uv" [ 0.333334 0.000000 0.333334 0.333334 0.000000 0.333334 0.000000 0.000000 0.666667 0.000000 0.666667 0.333333 1.000000 0.000000 1.000000 0.333333 ]\n')
4493 p.stdin.write('AttributeEnd\n')
4495 if(prev_plane.get()=="false"):
4496 p.stdin.write('AttributeBegin\nTransform [1.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 1.0 0.0 1.0 -1.0 4.0 1.0]\n')
4498 p.stdin.write('AttributeBegin\nTransform [1.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 1.0 0.0 1.0 -4.0 1.0 1.0]\n')
4499 area = luxProp(mat, kn+"prev_arealight", "false")
4500 if(area.get() == "false"):
4501 p.stdin.write('Texture "pL" "color" "blackbody" "float temperature" [6500.0]\n')
4502 p.stdin.write('LightSource "point" "texture L" ["pL"]')
4504 p.stdin.write('ReverseOrientation\n')
4505 p.stdin.write('AreaLightSource "area" "color L" [1.0 1.0 1.0]\n')
4506 p.stdin.write('Shape "disk" "float radius" [1.0]\nAttributeEnd\n')
4507 p.stdin.write('WorldEnd\n')
4510 data = p.communicate()[0]
4512 if(len(data) < thumbbuf):
4513 print "error on preview"
4517 image.decodeLuxConsole(thumbres, thumbres, data)
4518 previewCache[(mat.name+":"+kn).__hash__()] = image
4520 Blender.Window.WaitCursor(False)
4522 def luxPreview(mat, name, defType=0, defEnabled=False, defLarge=False, texName=None, gui=None, level=0, color=None):
4527 if texName: kn += ":"+texName
4528 if kn != "": kn += "."
4529 if(defEnabled == True):
4530 showpreview = luxProp(mat, kn+"prev_show", "true")
4532 showpreview = luxProp(mat, kn+"prev_show", "false")
4533 Draw.Toggle("P", evtLuxGui, gui.xmax, gui.y-gui.h, gui.h, gui.h, showpreview.get()=="true", "Preview", lambda e,v: showpreview.set(["false","true"][bool(v)]))
4534 if showpreview.get()=="true":
4536 large = luxProp(mat, kn+"prev_large", "true")
4538 large = luxProp(mat, kn+"prev_large", "false")
4541 if(large.get() == "true"):
4545 r = gui.getRect(1.1, rr)
4547 BGL.glColor3f(color[0],color[1],color[2]); BGL.glRectf(r[0]-110, r[1], 418, r[1]+128+voffset); BGL.glColor3f(0.9, 0.9, 0.9)
4548 try: previewCache[(mat.name+":"+kn).__hash__()].draw(r[0]-82, r[1]+4)
4551 prev_sphere = luxProp(mat, kn+"prev_sphere", "true")
4552 prev_plane = luxProp(mat, kn+"prev_plane", "false")
4553 prev_torus = luxProp(mat, kn+"prev_torus", "false")
4555 prev_sphere = luxProp(mat, kn+"prev_sphere", "false")
4556 prev_plane = luxProp(mat, kn+"prev_plane", "true")
4557 prev_torus = luxProp(mat, kn+"prev_torus", "false")
4559 prev_sphere = luxProp(mat, kn+"prev_sphere", "false")
4560 prev_plane = luxProp(mat, kn+"prev_plane", "false")
4561 prev_torus = luxProp(mat, kn+"prev_torus", "true")
4563 # preview mode toggle buttons
4564 Draw.Toggle("S", evtLuxGui, r[0]-108, r[1]+100+voffset, 22, 22, prev_sphere.get()=="true", "Draw Sphere", lambda e,v: Preview_Sphereset(mat, kn, ["false","true"][bool(v)]))
4565 Draw.Toggle("P", evtLuxGui, r[0]-108, r[1]+74+voffset, 22, 22, prev_plane.get()=="true", "Draw 2D Plane", lambda e,v: Preview_Planeset(mat, kn, ["false","true"][bool(v)]))
4566 Draw.Toggle("T", evtLuxGui, r[0]-108, r[1]+48+voffset, 22, 22, prev_torus.get()=="true", "Draw Torus", lambda e,v: Preview_Torusset(mat, kn, ["false","true"][bool(v)]))
4569 zoom = luxProp(mat, kn+"prev_zoom", "false")
4570 Draw.Toggle("Zoom", evtLuxGui, r[0]+66, r[1]+100+voffset, 50, 18, zoom.get()=="true", "Zoom", lambda e,v: zoom.set(["false","true"][bool(v)]))
4572 area = luxProp(mat, kn+"prev_arealight", "false")
4573 Draw.Toggle("Area", evtLuxGui, r[0]+66, r[1]+5, 50, 18, area.get()=="true", "Area", lambda e,v: area.set(["false","true"][bool(v)]))
4576 obwidth = luxProp(mat, kn+"prev_obwidth", 1.0)
4577 Draw.Number("Width:", evtLuxGui, r[0]+66, r[1]+78+voffset, 129, 18, obwidth.get(), 0.001, 10, "The width of the preview object in blender/lux 1m units", lambda e,v: obwidth.set(v))
4580 Draw.Toggle("large", evtLuxGui, r[0]+200, r[1]+78+voffset, 88, 18, large.get()=="true", "Large", lambda e,v: large.set(["false","true"][bool(v)]))
4583 qs = ["low","medium","high","very high"]
4584 scn = Scene.GetCurrent()
4585 defprevmat = luxProp(scn, "defprevmat", "high")
4586 quality = luxProp(mat, kn+"prev_quality", defprevmat.get())
4587 luxOptionRect("quality", quality, qs, " Quality", "select preview quality", gui, r[0]+200, r[1]+100+voffset, 88, 18)
4590 Draw.Button("Update Preview", evtLuxGui, r[0]+120, r[1]+5, 167, 18, "Update Material Preview", lambda e,v: Preview_Update(mat, kn, defLarge, defType, texName, name, level))
4592 # Reset depths after getRect()
4597 def luxMaterialBlock(name, luxname, key, mat, gui=None, level=0, str_opt=""):
4598 global icon_mat, icon_matmix, icon_map3dparam
4600 return (t1[0]+t2[0], t1[1]+t2[1])
4602 if key == "": keyname = kn = name
4603 else: keyname = kn = "%s:%s"%(key, name)
4604 if kn != "": kn += "."
4605 if keyname == "": matname = mat.getName()
4606 else: matname = "%s:%s"%(mat.getName(), keyname)
4609 mattype = luxProp(mat, kn+"type", "matte")
4610 # Set backwards compatibility of glossy material from plastic and substrate
4611 if(mattype.get() == "substrate" or mattype.get() == "plastic"):
4612 mattype.set("glossy")
4614 # this is reverse order than in shown in the dropdown list
4615 materials = ["null","mix","mirror","shinymetal","metal","mattetranslucent","matte","glossy","roughglass","glass","carpaint"]
4617 if level == 0: materials = ["portal","light","boundvolume"]+materials
4620 if mattype.get() == "mix": icon = icon_matmix
4621 if level == 0: gui.newline("Material type:", 12, level, icon, [0.75,0.5,0.25])
4622 else: gui.newline(name+":", 12, level, icon, scalelist([0.75,0.6,0.25],2.0/(level+2)))
4625 link = luxOption("type", mattype, materials, " TYPE", "select material type", gui)
4626 showadvanced = luxProp(mat, kn+"showadvanced", "false")
4627 luxBool("advanced", showadvanced, "Advanced", "Show advanced options", gui, 0.6)
4628 showhelp = luxProp(mat, kn+"showhelp", "false")
4629 luxHelp("help", showhelp, "Help", "Show Help Information", gui, 0.4)
4631 # show copy/paste menu button
4632 if gui: Draw.PushButton(">", evtLuxGui, gui.xmax+gui.h, gui.y-gui.h, gui.h, gui.h, "Menu", lambda e,v: showMatTexMenu(mat,keyname,False))
4634 # Draw Material preview option
4638 if gui: luxPreview(mat, keyname, 0, showmatprev, True, None, gui, level, [0.746, 0.625, 0.5])
4641 if gui: gui.newline()
4642 has_object_options = 0 # disable object options by default
4643 has_bump_options = 0 # disable bump mapping options by default
4644 has_emission_options = 0 # disable emission options by default
4645 has_compositing_options = 0 # disable compositing options by default
4647 if mattype.get() == "mix":
4648 (str,link) = c((str,link), luxFloatTexture("amount", keyname, 0.5, 0.0, 1.0, "amount", "The degree of mix between the two materials", mat, gui, level+1))
4649 (str,link) = c((str,link), luxMaterialBlock("mat1", "namedmaterial1", keyname, mat, gui, level+1))
4650 (str,link) = c((str,link), luxMaterialBlock("mat2", "namedmaterial2", keyname, mat, gui, level+1))
4651 has_bump_options = 0
4652 has_object_options = 1
4653 has_emission_options = 1
4654 has_compositing_options = 0
4656 if mattype.get() == "light":
4657 lightgroup = luxProp(mat, kn+"light.lightgroup", "default")
4658 if luxProp(Scene.GetCurrent(), "nolg", "false").get()!="true":
4659 link = "LightGroup \"%s\"\n"%lightgroup.get()
4660 link += "AreaLightSource \"area\""
4661 (str,link) = c((str,link), luxLight("", kn, mat, gui, level))
4662 has_bump_options = 0
4663 has_object_options = 1
4664 has_emission_options = 0
4665 has_compositing_options = 1
4667 if mattype.get() == "boundvolume":
4669 voltype = luxProp(mat, kn+"vol.type", "homogeneous")
4670 vols = ["homogeneous", "exponential", "cloud"]
4671 vollink = luxOption("type", voltype, vols, "type", "", gui)
4672 if voltype.get() == "homogeneous":
4673 link = "Volume \"homogeneous\""
4674 if voltype.get() == "exponential":
4675 link = "Volume \"exponential\""
4676 if voltype.get() == "cloud":
4677 link = "Volume \"cloud\""
4679 if gui: gui.newline("absorption:", 0, level+1)
4680 link += luxRGB("sigma_a", luxProp(mat, kn+"vol.sig_a", "1.0 1.0 1.0"), 1.0, "sigma_a", "The absorption cross section", gui)
4681 if gui: gui.newline("scattering:", 0, level+1)
4682 link += luxRGB("sigma_s", luxProp(mat, kn+"vol.sig_b", "0.0 0.0 0.0"), 1.0, "sigma_b", "The scattering cross section", gui)
4683 if gui: gui.newline("emission:", 0, level+1)
4684 link += luxRGB("Le", luxProp(mat, kn+"vol.le", "0.0 0.0 0.0"), 1.0, "Le", "The volume's emission spectrum", gui)
4685 if gui: gui.newline("assymetry:", 0, level+1)
4686 link += luxFloat("g", luxProp(mat, kn+"vol.g", 0.0), 0.0, 100.0, "g", "The phase function asymmetry parameter", gui)
4688 if voltype.get() == "exponential":
4689 if gui: gui.newline("form:", 0, level+1)
4690 link += luxFloat("a", luxProp(mat, kn+"vol.a", 1.0), 0.0, 100.0, "a/scale", "exponential::a parameter in the ae^{-bh} formula", gui)
4691 link += luxFloat("b", luxProp(mat, kn+"vol.b", 2.0), 0.0, 100.0, "b/falloff", "exponential::b parameter in the ae^{-bh} formula", gui)
4692 if gui: gui.newline("updir:", 0, level+1)
4693 link += luxVector("updir", luxProp(mat, kn+"vol.updir", "0 0 1"), -1.0, 1.0, "updir", "Up direction vector", gui, 2.0)
4695 if voltype.get() == "cloud":
4696 if gui: gui.newline("cloud:", 0, level+1)
4697 link += luxFloat("radius", luxProp(mat, kn+"vol.radius", 0.5), 0.01, 2.0, "radius", "Radius of hemisphere used as basis for cloud shape", gui)
4698 link += luxFloat("noisescale", luxProp(mat, kn+"vol.noisescale", 0.3), 0.1, 2.0, "noisesize", "Size of cloud noise", gui)
4699 link += luxFloat("turbulence", luxProp(mat, kn+"vol.turbulence", 0.5), 0.0, 3.0, "turbulence", "Extent to which the noise effects the cloud shape", gui)
4700 link += luxFloat("noiseoffset", luxProp(mat, kn+"vol.noiseoffset", 0.0), 0.0, 1000.0, "noiseoffset", "Useful for creating unique clouds", gui )
4701 link += luxInt("octaves", luxProp(mat, kn+"vol.octaves", 3), 1, 8, "octaves", "Sets the amount of detail for the noise", gui )
4702 link += luxFloat("omega", luxProp(mat, kn+"vol.omega", 0.75), 0.1, 1.0, "omega", "Sets the scale difference of each successive octave", gui )
4703 link += luxFloat("sharpness", luxProp(mat, kn+"vol.sharpness", 6.0), 0.2, 10.0, "sharpness", "Sets the sharpness of the noise", gui)
4704 link += luxFloat("variability", luxProp(mat, kn+"vol.variability", 0.9), 0.0, 1.0, "mask amount", "Noise mask amount. 0 means noise everywhere, 1 means only some spots have noise.", gui)
4705 link += luxFloat("baseflatness", luxProp(mat, kn+"vol.baseflatness", 0.8), 0.0, 1.0, "baseflatness", "Flatness of the cloud's base. (0.0 makes a round cloud.)", gui)
4706 link += luxInt("spheres", luxProp(mat, kn+"vol.spheres", 2000), 0, 10000, "spheres", "Number of small spheres for cumulus shape. 0 is non-cumulus.", gui )
4707 link += luxFloat("spheresize", luxProp(mat, kn+"vol.spheresize", 0.15), 0.05, 0.55, "spheresize", "Size of cumulus spheres", gui)
4711 has_bump_options = 0
4712 has_object_options = 0
4713 has_emission_options = 0
4717 if mattype.get() == "carpaint":
4718 if gui: gui.newline("Preset:", 0, level+1)
4719 carname = luxProp(mat, kn+"carpaint.name", "Custom")
4720 cars = ["Custom","ford f8","polaris silber","opel titan","bmw339","2k acrylack","white","blue","blue matte"]
4721 carlink = luxOption("name", carname, cars, "name", "", gui)
4722 if carname.get() == "Custom":
4723 (str,link) = c((str,link), luxSpectrumTexture("Kd", keyname, "1.0 1.0 1.0", 1.0, "diffuse", "", mat, gui, level+1))
4724 (str,link) = c((str,link), luxSpectrumTexture("Ks1", keyname, "1.0 1.0 1.0", 1.0, "specular1", "", mat, gui, level+1))
4725 (str,link) = c((str,link), luxSpectrumTexture("Ks2", keyname, "1.0 1.0 1.0", 1.0, "specular2", "", mat, gui, level+1))
4726 (str,link) = c((str,link), luxSpectrumTexture("Ks3", keyname, "1.0 1.0 1.0", 1.0, "specular3", "", mat, gui, level+1))
4727 (str,link) = c((str,link), luxFloatTexture("R1", keyname, 1.0, 0.0, 1.0, "R1", "", mat, gui, level+1))
4728 (str,link) = c((str,link), luxFloatTexture("R2", keyname, 1.0, 0.0, 1.0, "R2", "", mat, gui, level+1))
4729 (str,link) = c((str,link), luxFloatTexture("R3", keyname, 1.0, 0.0, 1.0, "R3", "", mat, gui, level+1))
4730 (str,link) = c((str,link), luxFloatTexture("M1", keyname, 1.0, 0.0, 1.0, "M1", "", mat, gui, level+1))
4731 (str,link) = c((str,link), luxFloatTexture("M2", keyname, 1.0, 0.0, 1.0, "M2", "", mat, gui, level+1))
4732 (str,link) = c((str,link), luxFloatTexture("M3", keyname, 1.0, 0.0, 1.0, "M3", "", mat, gui, level+1))
4733 else: link += carlink
4734 absorption = luxProp(mat, keyname+".useabsorption", "false")
4735 luxCollapse("absorption", absorption, "Absorption", "Enable Coating Absorption", gui, 2.0)
4736 if absorption.get() == "true":
4737 (str,link) = c((str,link), luxSpectrumTexture("Ka", keyname, "0.2 0.2 0.2", 1.0, "absorption", "", mat, gui, level+1))
4738 (str,link) = c((str,link), luxFloatTexture("d", keyname, 5.0, 0.0, 15.0, "depth", "", mat, gui, level+1))
4739 has_bump_options = 1
4740 has_object_options = 1
4741 has_emission_options = 1
4742 has_compositing_options = 1
4744 if mattype.get() == "glass":
4745 (str,link) = c((str,link), luxSpectrumTexture("Kr", keyname, "1.0 1.0 1.0", 1.0, "reflection", "", mat, gui, level+1))
4746 (str,link) = c((str,link), luxSpectrumTexture("Kt", keyname, "1.0 1.0 1.0", 1.0, "transmission", "", mat, gui, level+1))
4747 (str,link) = c((str,link), luxIORFloatTexture("index", keyname, 1.5, 1.0, 6.0, "IOR", "", mat, gui, level+1))
4748 architectural = luxProp(mat, keyname+".architectural", "false")
4749 link += luxBool("architectural", architectural, "architectural", "Enable architectural glass", gui, 2.0)
4750 if architectural.get() == "false":
4751 chromadisp = luxProp(mat, keyname+".chromadisp", "false")
4752 luxCollapse("chromadisp", chromadisp, "Dispersive Refraction", "Enable Chromatic Dispersion", gui, 2.0)
4753 if chromadisp.get() == "true":
4754 (str,link) = c((str,link), luxCauchyBFloatTexture("cauchyb", keyname, 0.0, 0.0, 1.0, "cauchyb", "", mat, gui, level+1))
4755 thinfilm = luxProp(mat, keyname+".thinfilm", "false")
4756 luxCollapse("thinfilm", thinfilm, "Thin Film Coating", "Enable Thin Film Coating", gui, 2.0)
4757 if thinfilm.get() == "true":
4758 (str,link) = c((str,link), luxFloatSliderTexture("film", keyname, 200.0, 1.0, 1500.0, "film", "thickness of film coating in nanometers", mat, gui, level+1))
4759 (str,link) = c((str,link), luxIORFloatTexture("filmindex", keyname, 1.5, 1.0, 6.0, "film IOR", "film coating index of refraction", mat, gui, level+1))
4760 has_bump_options = 1
4761 has_object_options = 1
4762 has_emission_options = 1
4763 has_compositing_options = 1
4765 if mattype.get() == "matte":
4766 orennayar = luxProp(mat, keyname+".orennayar", "false")
4767 (str,link) = c((str,link), luxSpectrumTexture("Kd", keyname, "1.0 1.0 1.0", 1.0, "diffuse", "", mat, gui, level+1))
4768 luxCollapse("orennayar", orennayar, "Oren-Nayar", "Enable Oren-Nayar BRDF", gui, 2.0)
4769 if orennayar.get() == "true":
4770 (str,link) = c((str,link), luxFloatTexture("sigma", keyname, 0.0, 0.0, 100.0, "sigma", "sigma value for Oren-Nayar BRDF", mat, gui, level+1))
4771 has_bump_options = 1
4772 has_object_options = 1
4773 has_emission_options = 1
4774 has_compositing_options = 1
4776 if mattype.get() == "mattetranslucent":
4777 orennayar = luxProp(mat, keyname+".orennayar", "false")
4778 (str,link) = c((str,link), luxSpectrumTexture("Kr", keyname, "1.0 1.0 1.0", 1.0, "reflection", "", mat, gui, level+1))
4779 (str,link) = c((str,link), luxSpectrumTexture("Kt", keyname, "1.0 1.0 1.0", 1.0, "transmission", "", mat, gui, level+1))
4780 luxCollapse("orennayar", orennayar, "Oren-Nayar", "Enable Oren-Nayar BRDF", gui, 2.0)
4781 if orennayar.get() == "true":
4782 (str,link) = c((str,link), luxFloatTexture("sigma", keyname, 0.0, 0.0, 100.0, "sigma", "", mat, gui, level+1))
4783 has_bump_options = 1
4784 has_object_options = 1
4785 has_emission_options = 1
4786 has_compositing_options = 1
4788 if mattype.get() == "metal":
4789 if gui: gui.newline("name:", 0, level+1)
4790 metalname = luxProp(mat, kn+"metal.name", "")
4791 metals = ["aluminium","amorphous carbon","silver","gold","copper"]
4793 if not(metalname.get() in metals):
4794 metals.append(metalname.get())
4795 metallink = luxOption("name", metalname, metals, "name", "", gui, 1.88)
4796 if gui: Draw.Button("...", evtLuxGui, gui.x, gui.y-gui.h, gui.h, gui.h, "click to select a nk file",lambda e,v:Window.FileSelector(lambda s:metalname.set(s), "Select nk file"))
4797 link += luxstr(metallink)
4798 anisotropic = luxProp(mat, kn+"metal.anisotropic", "false")
4801 Draw.Toggle("A", evtLuxGui, gui.x-gui.h, gui.y-gui.h, gui.h, gui.h, anisotropic.get()=="true", "anisotropic roughness", lambda e,v:anisotropic.set(["false","true"][bool(v)]))
4802 if anisotropic.get()=="true":
4803 (str,link) = c((str,link), luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "u-exponent", "", mat, gui, level+1))
4804 (str,link) = c((str,link), luxExponentTexture("vroughness", keyname, 0.002, 0.0, 1.0, "v-exponent", "", mat, gui, level+1))
4806 (s, l) = luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "exponent", "", mat, gui, level+1)
4807 (str,link) = c((str,link), (s, l))
4808 link += l.replace("uroughness", "vroughness", 1)
4810 has_bump_options = 1
4811 has_object_options = 1
4812 has_emission_options = 1
4813 has_compositing_options = 1
4815 if mattype.get() == "mirror":
4816 (str,link) = c((str,link), luxSpectrumTexture("Kr", keyname, "1.0 1.0 1.0", 1.0, "reflection", "", mat, gui, level+1))
4817 thinfilm = luxProp(mat, keyname+".thinfilm", "false")
4818 luxCollapse("thinfilm", thinfilm, "Thin Film Coating", "Enable Thin Film Coating", gui, 2.0)
4819 if thinfilm.get() == "true":
4820 (str,link) = c((str,link), luxFloatSliderTexture("film", keyname, 200.0, 1.0, 1500.0, "film", "thickness of film coating in nanometers", mat, gui, level+1))
4821 (str,link) = c((str,link), luxIORFloatTexture("filmindex", keyname, 1.5, 1.0, 6.0, "film IOR", "film coating index of refraction", mat, gui, level+1))
4823 has_bump_options = 1
4824 has_object_options = 1
4825 has_emission_options = 1
4826 has_compositing_options = 1
4828 if mattype.get() == "roughglass":
4829 (str,link) = c((str,link), luxSpectrumTexture("Kr", keyname, "1.0 1.0 1.0", 1.0, "reflection", "", mat, gui, level+1))
4830 (str,link) = c((str,link), luxSpectrumTexture("Kt", keyname, "1.0 1.0 1.0", 1.0, "transmission", "", mat, gui, level+1))
4831 anisotropic = luxProp(mat, kn+"roughglass.anisotropic", "false")
4834 Draw.Toggle("A", evtLuxGui, gui.x-gui.h, gui.y-gui.h, gui.h, gui.h, anisotropic.get()=="true", "anisotropic roughness", lambda e,v:anisotropic.set(["false","true"][bool(v)]))
4835 if anisotropic.get()=="true":
4836 (str,link) = c((str,link), luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "u-exponent", "", mat, gui, level+1))
4837 (str,link) = c((str,link), luxExponentTexture("vroughness", keyname, 0.002, 0.0, 1.0, "v-exponent", "", mat, gui, level+1))
4839 (s, l) = luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "exponent", "", mat, gui, level+1)
4840 (str,link) = c((str,link), (s, l))
4841 link += l.replace("uroughness", "vroughness", 1)
4842 (str,link) = c((str,link), luxIORFloatTexture("index", keyname, 1.5, 1.0, 6.0, "IOR", "", mat, gui, level+1))
4843 chromadisp = luxProp(mat, keyname+".chromadisp", "false")
4844 luxCollapse("chromadisp", chromadisp, "Dispersive Refraction", "Enable Chromatic Dispersion", gui, 2.0)
4845 if chromadisp.get() == "true":
4846 (str,link) = c((str,link), luxCauchyBFloatTexture("cauchyb", keyname, 0.0, 0.0, 1.0, "cauchyb", "", mat, gui, level+1))
4847 has_bump_options = 1
4848 has_object_options = 1
4849 has_emission_options = 1
4850 has_compositing_options = 1
4852 if mattype.get() == "shinymetal":
4853 (str,link) = c((str,link), luxSpectrumTexture("Kr", keyname, "1.0 1.0 1.0", 1.0, "reflection", "", mat, gui, level+1))
4854 (str,link) = c((str,link), luxSpectrumTexture("Ks", keyname, "1.0 1.0 1.0", 1.0, "specular", "", mat, gui, level+1))
4855 anisotropic = luxProp(mat, kn+"shinymetal.anisotropic", "false")
4858 Draw.Toggle("A", evtLuxGui, gui.x-gui.h, gui.y-gui.h, gui.h, gui.h, anisotropic.get()=="true", "anisotropic roughness", lambda e,v:anisotropic.set(["false","true"][bool(v)]))
4859 if anisotropic.get()=="true":
4860 (str,link) = c((str,link), luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "u-exponent", "", mat, gui, level+1))
4861 (str,link) = c((str,link), luxExponentTexture("vroughness", keyname, 0.002, 0.0, 1.0, "v-exponent", "", mat, gui, level+1))
4863 (s, l) = luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "exponent", "", mat, gui, level+1)
4864 (str,link) = c((str,link), (s, l))
4865 link += l.replace("uroughness", "vroughness", 1)
4867 thinfilm = luxProp(mat, keyname+".thinfilm", "false")
4868 luxCollapse("thinfilm", thinfilm, "Thin Film Coating", "Enable Thin Film Coating", gui, 2.0)
4869 if thinfilm.get() == "true":
4870 (str,link) = c((str,link), luxFloatSliderTexture("film", keyname, 200.0, 1.0, 1500.0, "film", "thickness of film coating in nanometers", mat, gui, level+1))
4871 (str,link) = c((str,link), luxIORFloatTexture("filmindex", keyname, 1.5, 1.0, 6.0, "film IOR", "film coating index of refraction", mat, gui, level+1))
4873 has_bump_options = 1
4874 has_object_options = 1
4875 has_emission_options = 1
4876 has_compositing_options = 1
4878 if mattype.get() == "glossy":
4879 (str,link) = c((str,link), luxSpectrumTexture("Kd", keyname, "1.0 1.0 1.0", 1.0, "diffuse", "", mat, gui, level+1))
4880 useior = luxProp(mat, keyname+".useior", "false")
4883 Draw.Toggle("I", evtLuxGui, gui.x-gui.h, gui.y-gui.h, gui.h, gui.h, useior.get()=="true", "Use IOR/Reflective index input", lambda e,v:useior.set(["false","true"][bool(v)]))
4884 if useior.get() == "true":
4885 (str,link) = c((str,link), luxIORFloatTexture("index", keyname, 1.5, 1.0, 50.0, "IOR", "", mat, gui, level+1))
4886 link += " \"color Ks\" [1.0 1.0 1.0]"
4888 (str,link) = c((str,link), luxSpectrumTexture("Ks", keyname, "1.0 1.0 1.0", 1.0, "specular", "", mat, gui, level+1))
4889 link += " \"float index\" [0.0]"
4890 anisotropic = luxProp(mat, kn+"glossy.anisotropic", "false")
4893 Draw.Toggle("A", evtLuxGui, gui.x-gui.h, gui.y-gui.h, gui.h, gui.h, anisotropic.get()=="true", "anisotropic roughness", lambda e,v:anisotropic.set(["false","true"][bool(v)]))
4894 if anisotropic.get()=="true":
4895 (str,link) = c((str,link), luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "u-exponent", "", mat, gui, level+1))
4896 (str,link) = c((str,link), luxExponentTexture("vroughness", keyname, 0.002, 0.0, 1.0, "v-exponent", "", mat, gui, level+1))
4898 (s, l) = luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "exponent", "", mat, gui, level+1)
4899 (str,link) = c((str,link), (s, l))
4900 link += l.replace("uroughness", "vroughness", 1)
4902 absorption = luxProp(mat, keyname+".useabsorption", "false")
4903 luxCollapse("absorption", absorption, "Absorption", "Enable Coating Absorption", gui, 2.0)
4904 if absorption.get() == "true":
4905 (str,link) = c((str,link), luxSpectrumTexture("Ka", keyname, "0.2 0.2 0.2", 1.0, "absorption", "", mat, gui, level+1))
4906 (str,link) = c((str,link), luxFloatTexture("d", keyname, 0.15, 0.0, 15.0, "depth", "", mat, gui, level+1))
4907 has_bump_options = 1
4908 has_object_options = 1
4909 has_emission_options = 1
4910 has_compositing_options = 1
4912 if mattype.get() == 'null':
4913 has_emission_options = 1
4915 # Bump mapping options (common)
4916 if (has_bump_options == 1):
4917 usebump = luxProp(mat, keyname+".usebump", "false")
4918 luxCollapse("usebump", usebump, "Bump Map", "Enable Bump Mapping options", gui, 2.0)
4919 if usebump.get() == "true":
4920 (str,link) = c((str,link), luxFloatTexture("bumpmap", keyname, 0.0, -1.0, 1.0, "bumpmap", "", mat, gui, level+1))
4922 # emission options (common)
4924 if (has_emission_options == 1):
4925 if gui: gui.newline("", 2, level, None, [0.6,0.6,0.4])
4926 useemission = luxProp(mat, "emission", "false")
4927 luxCollapse("useemission", useemission, "Emission", "Enable emission options", gui, 2.0)
4928 if useemission.get() == "true":
4929 # emission GUI is here but lux export will be done later
4930 luxLight("", "", mat, gui, level)
4931 else: luxProp(mat, "emission", "false").set("false") # prevent from exporting later
4934 # Compositing options (common)
4935 # Note - currently only display options when using distributedpath integrator
4936 integratortype = luxProp(Scene.GetCurrent(), "sintegrator.type", "bidirectional")
4937 if (integratortype.get() == "distributedpath" and level == 0):
4938 if (has_compositing_options == 1):
4939 if gui: gui.newline("", 2, level, None, [0.4,0.4,0.6])
4940 usecompo = luxProp(mat, "compo", "false")
4941 luxCollapse("compo", usecompo, "Compositing", "Enable Compositing options", gui, 2.0)
4942 if usecompo.get() == "true":
4943 if gui: gui.newline("", 2, level, None, [0.35,0.35,0.55])
4944 usecompoviz = luxProp(mat, "compo_viz", "false")
4945 luxCollapse("compo_viz", usecompoviz, "Visibility", "Enable Visibility Compositing options", gui, 2.0)
4946 if usecompoviz.get() == "true":
4947 if gui: gui.newline("View", 2, level, None, [0.35,0.35,0.55])
4948 compovizmat = luxProp(mat, "compo_viz_mat", "true")
4949 link += luxBool("compo_visible_material", compovizmat, "Material", "Enable View Visibility of Material", gui, 1.0)
4950 compovizemi = luxProp(mat, "compo_viz_emi", "true")
4951 link += luxBool("compo_visible_emission", compovizemi, "Emission", "Enable View Visibility of Emission", gui, 1.0)
4953 if gui: gui.newline("Indirect", 2, level, None, [0.35,0.35,0.55])
4954 compovizmati = luxProp(mat, "compo_viz_mati", "true")
4955 link += luxBool("compo_visible_indirect_material", compovizmati, "Material", "Enable InDirect Visibility of Material", gui, 1.0)
4956 compovizemii = luxProp(mat, "compo_viz_emii", "true")
4957 link += luxBool("compo_visible_indirect_emission", compovizemii, "Emission", "Enable InDirect Visibility of Emission", gui, 1.0)
4959 if gui: gui.newline("", 2, level, None, [0.4,0.4,0.6])
4960 overridealpha = luxProp(mat, "compo_o_alpha", "false")
4961 link += luxCollapse("compo_override_alpha", overridealpha, "Override Alpha", "Enable Manual control of alpha value", gui, 2.0)
4962 if overridealpha.get() == "true":
4963 if gui: gui.newline("Alpha", 2, level, None, [0.4,0.4,0.6])
4964 link += luxFloat("compo_override_alpha_value", luxProp(mat, "compo_o_alpha_v", 0.0), 0.0, 1.0, "Alpha", "Alpha Value", gui, 2.0, 1)
4965 usecolorkey = luxProp(mat, "compo_usekey", "false")
4966 if gui: gui.newline("", 2, level, None, [0.35,0.35,0.55])
4967 link += luxCollapse("compo_use_key", usecolorkey, "Chroma Key", "Enable Chroma Object key", gui, 2.0)
4968 if usecolorkey.get() == "true":
4969 if gui: gui.newline("Key", 2, level, None, [0.35,0.35,0.55])
4970 link += luxRGB("compo_key_color", luxProp(mat, "compo_key_color", "0.0 0.0 1.0"), 1.0, "key", "", gui, 2.0)
4972 # transformation options (common)
4973 if (level == 0) and mattype.get() not in ['portal', 'null']:
4974 if gui: gui.newline("", 2, level, None, [0.6,0.6,0.4])
4975 usetransformation = luxProp(mat, "transformation", "false")
4976 luxCollapse("usetransformation", usetransformation, "Texture Transformation", "Enable transformation option", gui, 2.0)
4977 if usetransformation.get() == "true":
4978 scale = luxProp(mat, "3dscale", 1.0)
4979 rotate = luxProp(mat, "3drotate", "0 0 0")
4980 translate = luxProp(mat, "3dtranslate", "0 0 0")
4982 gui.newline("scale:", -2, level, icon_map3dparam)
4983 luxVectorUniform("scale", scale, 0.001, 1000.0, "scale", "scale-vector", gui, 2.0)
4984 gui.newline("rot:", -2, level, icon_map3dparam)
4985 luxVector("rotate", rotate, -360.0, 360.0, "rotate", "rotate-vector", gui, 2.0)
4986 gui.newline("move:", -2, level, icon_map3dparam)
4987 luxVector("translate", translate, -1000.0, 1000.0, "move", "translate-vector", gui, 2.0)
4988 str = ("TransformBegin\n\tScale %f %f %f\n"%( 1.0/scale.getVector()[0],1.0/scale.getVector()[1],1.0/scale.getVector()[2] ))+("\tRotate %f 1 0 0\n\tRotate %f 0 1 0\n\tRotate %f 0 0 1\n"%rotate.getVector())+("\tTranslate %f %f %f\n"%translate.getVector()) + str + "TransformEnd\n"
4990 # Object options (common)
4991 if (level == 0) and (has_object_options == 1):
4992 if gui: gui.newline("Mesh:", 2, level, icon, [0.6,0.6,0.4])
4993 usesubdiv = luxProp(mat, "subdiv", "false")
4994 luxBool("usesubdiv", usesubdiv, "Subdivision", "Enable Loop Subdivision options", gui, 1.0)
4995 usedisp = luxProp(mat, "dispmap", "false")
4996 luxBool("usedisp", usedisp, "Displacement Map", "Enable Displacement mapping options", gui, 1.0)
4997 if usesubdiv.get() == "true" or usedisp.get() == "true":
4998 luxInt("sublevels", luxProp(mat, "sublevels", 2), 0, 12, "sublevels", "The number of levels of object subdivision", gui, 2.0)
4999 sharpbound = luxProp(mat, "sharpbound", "false")
5000 luxBool("sharpbound", sharpbound, "Sharpen Bounds", "Sharpen boundaries during subdivision", gui, 1.0)
5001 nsmooth = luxProp(mat, "nsmooth", "true")
5002 luxBool("nsmooth", nsmooth, "Smooth", "Smooth faces during subdivision", gui, 1.0)
5003 if usedisp.get() == "true":
5004 (str,ll) = c((str,link), luxDispFloatTexture("dispmap", keyname, 0.1, -10, 10.0, "dispmap", "Displacement Mapping amount", mat, gui, level+1))
5005 luxFloat("sdoffset", luxProp(mat, "sdoffset", 0.0), 0.0, 1.0, "Offset", "Offset for displacement map", gui, 2.0)
5006 usesubdiv.set("true");
5008 if mattype.get() == "light":
5011 str += "MakeNamedMaterial \"%s\"%s\n"%(matname, link)
5012 return (str, " \"string %s\" [\"%s\"]"%(luxname, matname))
5015 def luxMaterial(mat, gui=None):
5018 if luxProp(mat, "type", "").get()=="": # lux material not defined yet
5019 print "Blender material \"%s\" has no lux material definition, converting..."%(mat.getName())
5021 convertMaterial(mat) # try converting the blender material to a lux material
5023 (str, link) = luxMaterialBlock("", "", "", mat, gui, 0)
5024 if luxProp(mat, "type", "matte").get() != "light":
5025 link = "NamedMaterial \"%s\""%(mat.getName())
5026 # export emission options (no gui)
5027 useemission = luxProp(mat, "emission", "false")
5028 if useemission.get() == "true":
5029 lightgroup = luxProp(mat, "light.lightgroup", "default")
5030 if luxProp(Scene.GetCurrent(), "nolg", "false").get()!="true":
5031 link += "\n\tLightGroup \"%s\"\n"%lightgroup.get()
5033 (estr, elink) = luxLight("", "", mat, None, 0)
5035 link += "\n\tAreaLightSource \"area\" "+elink
5037 luxProp(mat, "link", "").set("".join(link))
5042 def luxVolume(mat, gui=None):
5045 (str, link) = luxMaterialBlock("", "", "", mat, gui, 0)
5046 luxProp(mat, "link", "").set("".join(link))
5049 runRenderAfterExport = None
5050 def CBluxExport(default, run):
5051 global runRenderAfterExport
5052 runRenderAfterExport = run
5054 datadir = luxProp(Scene.GetCurrent(), "datadir", "").get()
5055 if datadir=="": datadir = Blender.Get("datadir")
5056 filename = datadir + os.sep + "default.lxs"
5057 save_still(filename)
5059 Window.FileSelector(save_still, "Export", sys.makename(Blender.Get("filename"), ".lxs"))
5062 def CBluxAnimExport(default, run, fileselect=True):
5064 datadir = luxProp(Scene.GetCurrent(), "datadir", "").get()
5065 if datadir=="": datadir = Blender.Get("datadir")
5066 filename = datadir + os.sep + "default.lxs"
5070 Window.FileSelector(save_anim, "Export", sys.makename(Blender.Get("filename"), ".lxs"))
5072 datadir = luxProp(Scene.GetCurrent(), "datadir", "").get()
5073 if datadir=="": datadir = Blender.Get("datadir")
5074 filename = sys.makename(Blender.Get("filename") , ".lxs")
5078 # convert a Blender material to lux material
5079 def convertMaterial(mat):
5081 if str != "": return str+"."
5084 if str != "": return str+":"
5086 def mapConstDict(value, constant_dict, lux_dict, default=None):
5087 for k,v in constant_dict.items():
5088 if (v == value) and (lux_dict.has_key(k)):
5092 def convertMapping(name, tex):
5093 if tex.texco == Texture.TexCo["UV"]:
5094 luxProp(mat, dot(name)+"mapping","").set("uv")
5095 luxProp(mat, dot(name)+"uscale", 1.0).set(tex.size[0])
5096 luxProp(mat, dot(name)+"vscale", 1.0).set(-tex.size[1])
5097 luxProp(mat, dot(name)+"udelta", 0.0).set(tex.ofs[0]+0.5*(1.0-tex.size[0]))
5098 luxProp(mat, dot(name)+"vdelta", 0.0).set(-tex.ofs[1]-0.5*(1.0-tex.size[1]))
5099 if tex.mapping != Texture.Mappings["FLAT"]:
5100 print "Material Conversion Warning: for UV-texture-input only FLAT mapping is supported\n"
5102 if tex.mapping == Texture.Mappings["FLAT"]:
5103 luxProp(mat, dot(name)+"mapping","").set("planar")
5104 elif tex.mapping == Texture.Mappings["TUBE"]:
5105 luxProp(mat, dot(name)+"mapping","").set("cylindrical")
5106 elif tex.mapping == Texture.Mappings["SPHERE"]:
5107 luxProp(mat, dot(name)+"mapping","").set("spherical")
5108 else: luxProp(mat, dot(name)+"mapping","").set("planar")
5109 luxProp(mat, dot(name)+"3dscale", "1.0 1.0 1.0").setVector((1.0/tex.size[0], 1.0/tex.size[1], 1.0/tex.size[2]))
5110 luxProp(mat, dot(name)+"3dtranslate", "0.0 0.0 0.0").setVector((-tex.ofs[0], -tex.ofs[1], -tex.ofs[2]))
5112 def convertColorband(colorband):
5113 # colorbands are not supported in lux - so lets extract a average low-side and high-side color
5114 cb = [colorband[0]] + colorband[:] + [colorband[-1]]
5115 cb[0][4], cb[-1][4] = 0.0, 1.0
5116 low, high = [0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0]
5117 for i in range(1, len(cb)):
5119 low[c] += (cb[i-1][c]*(1.0-cb[i-1][4]) + cb[i][c]*(1.0-cb[i][4])) * (cb[i][4]-cb[i-1][4])
5120 high[c] += (cb[i-1][c]*cb[i-1][4] + cb[i][c]*cb[i][4]) * (cb[i][4]-cb[i-1][4])
5123 def createLuxTexture(name, tex):
5125 convertMapping(name, tex)
5126 if (texture.type == Texture.Types["IMAGE"]) and (texture.image) and (texture.image.filename!=""):
5127 luxProp(mat, dot(name)+"texture", "").set("imagemap")
5128 luxProp(mat, dot(name)+"filename", "").set(texture.image.filename)
5129 luxProp(mat, dot(name)+"wrap", "").set(mapConstDict(texture.extend, Texture.ExtendModes, {"REPEAT":"repeat", "EXTEND":"clamp", "CLIP":"black"}, ""))
5131 if tex.texco != Texture.TexCo["GLOB"]:
5132 print "Material Conversion Warning: procedural textures supports global mapping only\n"
5133 noiseDict = {"BLENDER":"blender_original", "CELLNOISE":"cell_noise", "IMPROVEDPERLIN":"improved_perlin", "PERLIN":"original_perlin", "VORONOICRACKLE":"voronoi_crackle", "VORONOIF1":"voronoi_f1", "VORONOIF2":"voronoi_f2", "VORONOIF2F1":"voronoi_f2f1", "VORONOIF3":"voronoi_f3", "VORONOIF4":"voronoi_f4"}
5134 luxProp(mat, dot(name)+"bright", 1.0).set(texture.brightness)
5135 luxProp(mat, dot(name)+"contrast", 1.0).set(texture.contrast)
5136 if texture.type == Texture.Types["CLOUDS"]:
5137 luxProp(mat, dot(name)+"texture", "").set("blender_clouds")
5138 luxProp(mat, dot(name)+"mtype", "").set(mapConstDict(texture.stype, Texture.STypes, {"CLD_DEFAULT":"default", "CLD_COLOR":"color"}, ""))
5139 luxProp(mat, dot(name)+"noisetype", "").set({"soft":"soft_noise", "hard":"hard_noise"}[texture.noiseType])
5140 luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
5141 luxProp(mat, dot(name)+"noisedepth", 2).set(texture.noiseDepth)
5142 luxProp(mat, dot(name)+"noisebasis", "").set(mapConstDict(texture.noiseBasis, Texture.Noise, noiseDict, ""))
5143 elif texture.type == Texture.Types["WOOD"]:
5144 luxProp(mat, dot(name)+"texture", "").set("blender_wood")
5145 luxProp(mat, dot(name)+"mtype", "").set(mapConstDict(texture.stype, Texture.STypes, {"WOD_BANDS":"bands", "WOD_RINGS":"rings", "WOD_BANDNOISE":"bandnoise", "WOD_RINGNOISE":"ringnoise"}, ""))
5146 luxProp(mat, dot(name)+"noisebasis2", "").set(mapConstDict(texture.noiseBasis2, Texture.Noise, {"SINE":"sin", "SAW":"saw", "TRI":"tri"}, ""))
5147 luxProp(mat, dot(name)+"noisebasis", "").set(mapConstDict(texture.noiseBasis, Texture.Noise, noiseDict, ""))
5148 luxProp(mat, dot(name)+"noisetype", "").set({"soft":"soft_noise", "hard":"hard_noise"}[texture.noiseType])
5149 luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
5150 luxProp(mat, dot(name)+"turbulance", 0.25).set(texture.turbulence)
5151 elif texture.type == Texture.Types["MUSGRAVE"]:
5152 luxProp(mat, dot(name)+"texture", "").set("blender_musgrave")
5153 luxProp(mat, dot(name)+"mtype", "").set(mapConstDict(texture.stype, Texture.STypes, {"MUS_MFRACTAL":"multifractal", "MUS_RIDGEDMF":"ridged_multifractal", "MUS_HYBRIDMF":"hybrid_multifractal", "MUS_HTERRAIN":"hetero_terrain", "MUS_FBM":"fbm"}, ""))
5154 luxProp(mat, dot(name)+"noisebasis", "").set(mapConstDict(texture.noiseBasis, Texture.Noise, noiseDict, ""))
5155 luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
5156 # bug in blender python API: value of "hFracDim" is casted to Integer instead of Float (reported to Ideasman42 - will be fixed after Blender 2.47)
5157 if texture.hFracDim != 0.0: luxProp(mat, dot(name)+"h", 1.0).set(texture.hFracDim) # bug in blender API, "texture.hFracDim" returns a Int instead of a Float
5158 else: luxProp(mat, dot(name)+"h", 1.0).set(0.5) # use a default value
5159 # bug in blender python API: values "offset" and "gain" are missing in Python-API (reported to Ideasman42 - will be fixed after Blender 2.47)
5161 luxProp(mat, dot(name)+"offset", 1.0).set(texture.offset)
5162 luxProp(mat, dot(name)+"gain", 1.0).set(texture.gain)
5163 except AttributeError: pass
5164 luxProp(mat, dot(name)+"lacu", 2.0).set(texture.lacunarity)
5165 luxProp(mat, dot(name)+"octs", 2.0).set(texture.octs)
5166 luxProp(mat, dot(name)+"outscale", 1.0).set(texture.iScale)
5167 elif texture.type == Texture.Types["MARBLE"]:
5168 luxProp(mat, dot(name)+"texture", "").set("blender_marble")
5169 luxProp(mat, dot(name)+"mtype", "").set(mapConstDict(texture.stype, Texture.STypes, {"MBL_SOFT":"soft", "MBL_SHARP":"sharp", "MBL_SHARPER":"sharper"}, ""))
5170 luxProp(mat, dot(name)+"noisetype", "").set({"soft":"soft_noise", "hard":"hard_noise"}[texture.noiseType])
5171 luxProp(mat, dot(name)+"turbulance", 0.25).set(texture.turbulence)
5172 luxProp(mat, dot(name)+"noisedepth", 2).set(texture.noiseDepth)
5173 luxProp(mat, dot(name)+"noisebasis", "").set(mapConstDict(texture.noiseBasis, Texture.Noise, noiseDict, ""))
5174 luxProp(mat, dot(name)+"noisebasis2", "").set(mapConstDict(texture.noiseBasis2, Texture.Noise, {"SINE":"sin", "SAW":"saw", "TRI":"tri"}, ""))
5175 luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
5176 elif texture.type == Texture.Types["VORONOI"]:
5177 luxProp(mat, dot(name)+"texture", "").set("blender_voronoi")
5178 luxProp(mat, dot(name)+"distmetric", "").set({0:"actual_distance", 1:"distance_squared", 2:"manhattan", 3:"chebychev", 4:"minkovsky_half", 5:"minkovsky_four", 6:"minkovsky"}[texture.distMetric])
5179 luxProp(mat, dot(name)+"outscale", 1.0).set(texture.iScale)
5180 luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
5181 luxProp(mat, dot(name)+"minkosky_exp", 2.5).set(texture.exp)
5182 luxProp(mat, dot(name)+"w1", 1.0).set(texture.weight1)
5183 luxProp(mat, dot(name)+"w2", 0.0).set(texture.weight2)
5184 luxProp(mat, dot(name)+"w3", 0.0).set(texture.weight3)
5185 luxProp(mat, dot(name)+"w4", 0.0).set(texture.weight4)
5186 elif texture.type == Texture.Types["NOISE"]:
5187 luxProp(mat, dot(name)+"texture", "").set("blender_noise")
5188 elif texture.type == Texture.Types["DISTNOISE"]:
5189 luxProp(mat, dot(name)+"texture", "").set("blender_distortednoise")
5190 luxProp(mat, dot(name)+"distamount", 1.0).set(texture.distAmnt)
5191 luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
5192 luxProp(mat, dot(name)+"noisebasis", "").set(mapConstDict(texture.noiseBasis, Texture.Noise, noiseDict, ""))
5193 luxProp(mat, dot(name)+"noisebasis2", "").set(mapConstDict(texture.noiseBasis2, Texture.Noise, noiseDict, ""))
5194 elif texture.type == Texture.Types["MAGIC"]:
5195 luxProp(mat, dot(name)+"texture", "").set("blender_magic")
5196 luxProp(mat, dot(name)+"turbulance", 0.25).set(texture.turbulence)
5197 luxProp(mat, dot(name)+"noisedepth", 2).set(texture.noiseDepth)
5198 elif texture.type == Texture.Types["STUCCI"]:
5199 luxProp(mat, dot(name)+"texture", "").set("blender_stucci")
5200 luxProp(mat, dot(name)+"mtype", "").set(mapConstDict(texture.stype, Texture.STypes, {"STC_PLASTIC":"Plastic", "MSTC_WALLIN":"Wall In", "STC_WALLOUT":"Wall Out"}, ""))
5201 luxProp(mat, dot(name)+"noisetype", "").set({"soft":"soft_noise", "hard":"hard_noise"}[texture.noiseType])
5202 luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
5203 luxProp(mat, dot(name)+"turbulance", 0.25).set(texture.turbulence)
5204 luxProp(mat, dot(name)+"noisebasis", "").set(mapConstDict(texture.noiseBasis, Texture.Noise, noiseDict, ""))
5205 elif texture.type == Texture.Types["BLEND"]:
5206 luxProp(mat, dot(name)+"texture", "").set("blender_blend")
5207 luxProp(mat, dot(name)+"type", "").set(mapConstDict(texture.stype, Texture.STypes, {"BLN_LIN":"lin", "BLN_QUAD":"quad", "BLN_EASE":"ease", "BLN_DIAG":"diag", "BLN_SPHERE":"sphere", "BLN_HALO":"halo", "BLN_RADIAL":"radial"}, ""))
5208 luxProp(mat, dot(name)+"flipXY", "false").set({0:"false", 1:"true"}[texture.rot90])
5210 print "Material Conversion Warning: SORRY, this procedural texture isn\'t implemented in conversion\n"
5212 def convertTextures(basename, texs, type="float", channel="col", val=1.0):
5215 isImagemap = (texture.type == Texture.Types["IMAGE"]) and (texture.image) and (texture.image.filename!="")
5216 if channel == "col":
5217 if texture.flags & Texture.Flags["COLORBAND"] > 0:
5218 cbLow, cbHigh = convertColorband(texture.colorband)
5219 val1, alpha1, val2, alpha2 = (cbLow[0],cbLow[1],cbLow[2]), cbLow[3]*tex.colfac, (cbHigh[0], cbHigh[1], cbHigh[2]), cbHigh[3]*tex.colfac
5221 lum1, lum2 = (val1[0]+val1[1]+val1[2])/3.0, (val2[0]+val2[1]+val2[2])/3.0
5222 val1, val2 = (tex.col[0]*lum1,tex.col[1]*lum1,tex.col[2]*lum1), (tex.col[0]*lum2,tex.col[1]*lum2,tex.col[2]*lum2)
5223 elif isImagemap and not(tex.noRGB): val1, alpha1, val2, alpha2 = (0.0,0.0,0.0), tex.colfac, (1.0,1.0,1.0), tex.colfac
5224 else: val1, alpha1, val2, alpha2 = tex.col, 0.0, tex.col, tex.colfac
5225 elif channel == "nor": val1, alpha1, val2, alpha2 = tex.norfac * 0.01, 0.0, tex.norfac * 0.01, 1.0
5226 else: val1, alpha1, val2, alpha2 = 1.0, 0.0, 1.0, tex.varfac
5227 if (tex.neg)^((channel=="nor") and (tex.mtNor<0)): val1, alpha1, val2, alpha2 = val2, alpha2, val1, alpha1
5228 luxProp(mat, dot(basename)+"textured", "").set("true")
5231 if (alpha1 < 1.0) or (alpha2 < 1.0): # texture with transparency
5232 luxProp(mat, dot(basename)+"texture", "").set("mix")
5233 if alpha1 == alpha2: # constant alpha
5234 luxProp(mat, ddot(basename)+"amount.value", 1.0).set(alpha1)
5236 createLuxTexture(ddot(basename)+"amount", tex)
5237 luxProp(mat, ddot(basename)+"amount:tex1.value", 1.0).set(alpha1)
5238 luxProp(mat, ddot(basename)+"amount:tex2.value", 1.0).set(alpha2)
5239 # transparent to next texture
5240 name = ddot(basename)+"tex1"
5242 convertTextures(ddot(basename)+"tex1", texs, type, channel, val)
5244 if type=="float": luxProp(mat, ddot(basename)+"tex1.value", 1.0).set(val);
5245 else: luxProp(mat, ddot(basename)+"tex1.value", "1.0 1.0 1.0").setRGB((val[0], val[1], val[2]))
5246 name = ddot(basename)+"tex2"
5247 if val1 == val2: # texture with different colors / value
5248 if type == "col": luxProp(mat, dot(name)+"value", "1.0 1.0 1.0").setRGB(val1)
5249 else: luxProp(mat, dot(name)+"value", 1.0).set(val1)
5251 createLuxTexture(name, tex)
5252 if type == "col": luxProp(mat, ddot(name)+"tex1.value", "1.0 1.0 1.0").setRGB(val1)
5253 else: luxProp(mat, ddot(name)+"tex1.value", 1.0).set(val1)
5254 if type == "col": luxProp(mat, ddot(name)+"tex2.value", "1.0 1.0 1.0").setRGB(val2)
5255 else: luxProp(mat, ddot(name)+"tex2.value", 1.0).set(val2)
5258 def convertDiffuseTexture(name):
5260 for tex in mat.getTextures():
5261 if tex and (tex.mapto & Texture.MapTo["COL"] > 0) and (tex.tex) and (tex.tex.type != Texture.Types["NONE"]): texs.append(tex)
5263 luxProp(mat, name, "").setRGB((mat.ref, mat.ref, mat.ref))
5264 convertTextures(name, texs, "col", "col", (mat.R, mat.G, mat.B))
5265 def convertSpecularTexture(name):
5267 for tex in mat.getTextures():
5268 if tex and (tex.mapto & Texture.MapTo["CSP"] > 0) and (tex.tex) and (tex.tex.type != Texture.Types["NONE"]): texs.append(tex)
5270 luxProp(mat, name, "").setRGB((mat.ref*mat.spec, mat.ref*mat.spec, mat.ref*mat.spec))
5271 convertTextures(name, texs, "col", "col", (mat.specR, mat.specG, mat.specB))
5272 def convertMirrorTexture(name):
5274 for tex in mat.getTextures():
5275 if tex and (tex.mapto & Texture.MapTo["CMIR"] > 0) and (tex.tex) and (tex.tex.type != Texture.Types["NONE"]): texs.append(tex)
5277 luxProp(mat, name, "").setRGB((mat.ref, mat.ref, mat.ref))
5278 convertTextures(name, texs, "col", "col", (mat.mirR, mat.mirG, mat.mirB))
5279 def convertBumpTexture(basename):
5281 for tex in mat.getTextures():
5282 if tex and (tex.mapto & Texture.MapTo["NOR"] > 0) and (tex.tex) and (tex.tex.type != Texture.Types["NONE"]): texs.append(tex)
5284 name = basename+":bumpmap"
5285 luxProp(mat, basename+".usebump", "").set("true")
5286 luxProp(mat, dot(name)+"textured", "").set("true")
5287 luxProp(mat, name, "").set(1.0)
5288 convertTextures(name, texs, "float", "nor", 0.0)
5290 def makeMatte(name):
5291 luxProp(mat, dot(name)+"type", "").set("matte")
5292 luxProp(mat, name+":Kd", "").setRGB((mat.R*mat.ref, mat.G*mat.ref, mat.B*mat.ref))
5293 convertDiffuseTexture(name+":Kd")
5294 convertBumpTexture(name)
5295 def makeGlossy(name, roughness):
5296 luxProp(mat, dot(name)+"type", "").set("glossy")
5297 luxProp(mat, name+":Kd", "").setRGB((mat.R*mat.ref, mat.G*mat.ref, mat.B*mat.ref))
5298 luxProp(mat, name+":Ks", "").setRGB((mat.specR*mat.spec*0.5, mat.specG*mat.spec*0.5, mat.specB*mat.spec*0.5))
5299 luxProp(mat, name+":uroughness", 0.0).set(roughness)
5300 luxProp(mat, name+":vroughness", 0.0).set(roughness)
5301 convertDiffuseTexture(name+":Kd")
5302 convertSpecularTexture(name+":Ks")
5303 convertBumpTexture(name)
5304 def makeMirror(name):
5305 luxProp(mat, dot(name)+"type", "").set("mirror")
5306 luxProp(mat, name+":Kr", "").setRGB((mat.mirR, mat.mirG, mat.mirB))
5307 convertMirrorTexture(name+":Kr")
5308 convertBumpTexture(name)
5309 def makeGlass(name):
5310 luxProp(mat, dot(name)+"type", "").set("glass")
5311 luxProp(mat, name+":Kr", "").setRGB((0.0, 0.0, 0.0))
5312 luxProp(mat, name+":Kt", "").setRGB((mat.R, mat.G, mat.B))
5313 luxProp(mat, name+":index.iorusepreset", "").set("false")
5314 luxProp(mat, name+":index", 0.0).set(mat.getIOR())
5315 convertMirrorTexture(name+":Kr")
5316 convertDiffuseTexture(name+":Kt")
5317 convertBumpTexture(name)
5318 def makeRoughglass(name, roughness):
5319 luxProp(mat, dot(name)+"type", "").set("roughglass")
5320 luxProp(mat, name+":Kr", "").setRGB((0.0, 0.0, 0.0))
5321 luxProp(mat, name+":Kt", "").setRGB((mat.R, mat.G, mat.B))
5322 luxProp(mat, name+":index.iorusepreset", "").set("false")
5323 luxProp(mat, name+":index", 0.0).set(mat.getIOR())
5324 luxProp(mat, name+":uroughness", 0.0).set(roughness)
5325 luxProp(mat, name+":vroughness", 0.0).set(roughness)
5326 convertMirrorTexture(name+":Kr")
5327 convertDiffuseTexture(name+":Kt")
5328 convertBumpTexture(name)
5329 print "convert Blender material \"%s\" to lux material"%(mat.name)
5330 mat.properties['luxblend'] = {}
5331 if mat.emit > 0.0001:
5332 luxProp(mat, "type", "").set("light")
5333 luxProp(mat, "light.l", "").setRGB((mat.R, mat.G, mat.B))
5334 luxProp(mat, "light.gain", 1.0).set(mat.emit)
5337 if not(mat.mode & Material.Modes.RAYTRANSP): alpha = 1.0
5338 alpha0name, alpha1name = "", ""
5339 if (alpha > 0.0) and (alpha < 1.0):
5340 luxProp(mat, "type", "").set("mix")
5341 luxProp(mat, ":amount", 0.0).set(alpha)
5342 alpha0name, alpha1name = "mat2", "mat1"
5344 mirror = mat.rayMirr
5345 if not(mat.mode & Material.Modes.RAYMIRROR): mirror = 0.0
5346 mirror0name, mirror1name = alpha1name, alpha1name
5347 if (mirror > 0.0) and (mirror < 1.0):
5348 luxProp(mat, dot(alpha1name)+"type", "").set("mix")
5349 luxProp(mat, alpha1name+":amount", 0.0).set(1.0 - mirror)
5350 mirror0name, mirror1name = ddot(alpha1name)+"mat1", ddot(alpha1name)+"mat2"
5352 if mat.glossMir < 1.0: makeGlossy(mirror1name, 1.0-mat.glossMir**2)
5353 else: makeMirror(mirror1name)
5355 if mat.spec > 0.0: makeGlossy(mirror0name, 1.0/mat.hard)
5356 else: makeMatte(mirror0name)
5358 if mat.glossTra < 1.0: makeRoughnessGlass(alpha0name, 1.0-mat.glossTra**2)
5359 else: makeGlass(alpha0name)
5361 def convertAllMaterials():
5362 for mat in Material.Get(): convertMaterial(mat)
5367 ### Connect LRMDB ###
5368 ConnectLrmdb = False
5370 import socket # try import of socket library
5372 def downloadLRMDB(mat, id):
5374 DrawProgressBar(0.0,'Getting Material #'+id)
5376 HOST = 'www.luxrender.net'
5377 GET = '/lrmdb/en/material/download/'+id
5379 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
5380 sock.connect((HOST, PORT))
5381 sock.send("GET %s HTTP/1.0\r\nHost: %s\r\n\r\n" % (GET, HOST))
5382 data = sock.recv(1024)
5386 data = sock.recv(1024)
5388 if str.split("\n", 1)[0].find("200") < 0:
5389 print "ERROR: server error: %s"%(str.split("\n",1)[0])
5391 str = (str.split("\r\n\r\n")[1]).strip()
5392 if (str[0]=="{") and (str[-1]=="}"):
5393 return str2MatTex(str)
5394 print "ERROR: downloaded data is not a material or texture"
5396 print "ERROR: download failed"
5398 DrawProgressBar(1.0,'')
5400 print "ERROR: material id is not valid"
5404 #===========================================================================
5406 #===========================================================================
5408 #---------------------------------------------------------------------------
5410 import cookielib, urllib2, xmlrpclib
5412 #---------------------------------------------------------------------------
5414 # https://fedorahosted.org/python-bugzilla/browser/bugzilla.py?rev=e6f699f06e92b1e49b1b8d2c8fbe89d9425a4a9a
5415 class CookieTransport(xmlrpclib.Transport):
5417 A subclass of xmlrpclib.Transport that supports cookies.
5424 # Cribbed from xmlrpclib.Transport.send_user_agent
5425 def send_cookies(self, connection, cookie_request):
5427 Send all the cookie data that we have received
5430 if self.cookiejar is None:
5431 self.cookiejar = cookielib.CookieJar()
5432 elif self.cookiejar:
5433 # Let the cookiejar figure out what cookies are appropriate
5434 self.cookiejar.add_cookie_header(cookie_request)
5435 # Pull the cookie headers out of the request object...
5437 for header, value in cookie_request.header_items():
5438 if header.startswith('Cookie'):
5439 cookielist.append([header, value])
5440 # ...and put them over the connection
5441 for header, value in cookielist:
5442 connection.putheader(header, value)
5444 # This is the same request() method from xmlrpclib.Transport,
5445 # with a couple additions noted below
5446 def request(self, host, handler, request_body, verbose=0):
5451 host_connection = self.make_connection(host)
5453 host_connection.set_debuglevel(1)
5455 # ADDED: construct the URL and Request object for proper cookie handling
5456 request_url = "%s://%s/" % (self.scheme, host)
5457 cookie_request = urllib2.Request(request_url)
5459 self.send_request(host_connection, handler, request_body)
5460 self.send_host(host_connection, host)
5462 # ADDED. creates cookiejar if None.
5463 self.send_cookies(host_connection, cookie_request)
5464 self.send_user_agent(host_connection)
5465 self.send_content(host_connection, request_body)
5467 errcode, errmsg, headers = host_connection.getreply()
5469 # ADDED: parse headers and get cookies here
5470 class CookieResponse:
5472 fake a response object that we can fill with the headers above
5475 def __init__(self, headers):
5476 self.headers = headers
5481 cookie_response = CookieResponse(headers)
5483 # Okay, extract the cookies from the headers
5484 self.cookiejar.extract_cookies(cookie_response, cookie_request)
5486 # And write back any changes
5487 # DH THIS DOESN'T WORK
5488 # self.cookiejar.save(self.cookiejar.filename)
5491 raise xmlrpclib.ProtocolError(
5497 self.verbose = verbose
5500 sock = host_connection._conn.sock
5501 except AttributeError:
5504 return self._parse_response(host_connection.getfile(), sock)
5507 #===========================================================================
5509 #===========================================================================
5511 host = 'http://www.luxrender.net/lrmdb/ixr'
5519 last_error_str = None
5521 def last_error(self):
5522 return self.last_error_str #'LRMDB Connector: %s' %
5526 result = self.SERVER.user.login(
5533 self.logged_in = True
5536 self.last_error_str = 'Login Failed'
5537 self.logged_in = False
5540 def submit_object(self, mat, basekey, tex):
5541 if not self.check_creds(): return False
5544 result = 'Unknown Error'
5547 name = Draw.PupStrInput('Name: ', '', 32)
5551 result = self.SERVER.object.submit(
5553 MatTex2dict( getMatTex(mat, basekey, tex), tex )
5555 if result is not True:
5560 self.last_error_str = 'Submit failed: %s' % result
5563 def check_creds(self):
5564 if self.SERVER is None:
5566 self.SERVER = xmlrpclib.ServerProxy(self.host, transport=CookieTransport())
5568 self.last_error_str = 'ServerProxy init failed'
5572 if not self.logged_in:
5573 #if self.username is "":
5574 self.request_username()
5576 #if self.password is "":
5577 self.request_password()
5583 def request_username(self):
5584 self.username = Draw.PupStrInput("Username:", self.username, 32)
5586 def request_password(self):
5587 self.password = Draw.PupStrInput("Password:", self.password, 32)
5589 lrmdb_connector = lrmdb()
5592 except: print "WARNING: LRMDB support not available"
5596 ### MatTex functions ###
5597 ### MatTex : is a dictionary of material or texture properties
5599 def getMatTex(mat, basekey='', tex=False):
5600 global usedproperties, usedpropertiesfilterobj
5602 usedpropertiesfilterobj = mat
5605 for k,v in usedproperties.items():
5606 if k[:len(basekey)]==basekey:
5607 if k[-9:] != '.textured':
5608 name = k[len(basekey):]
5609 if name == ".type": name = "type"
5611 dict["__type__"] = ["material","texture"][bool(tex)]
5614 def putMatTex(mat, dict, basekey='', tex=None):
5615 if dict and (tex!=None) and (tex ^ (dict.has_key("__type__") and (dict["__type__"]=="texture"))):
5616 print "ERROR: Can't apply %s as %s"%(["texture","material"][bool(tex)],["material","texture"][bool(tex)])
5619 # remove all current properties in mat that starts with basekey
5621 d = mat.properties['luxblend']
5622 for k,v in d.convert_to_pyobject().items():
5624 if k[:7]=="__hash:": # decode if entry is hashed (cause of 32chars limit)
5627 if kn[:len(basekey)]==basekey:
5628 del mat.properties['luxblend'][k]
5629 except: print "error" # pass
5630 # assign loaded properties
5631 for k,v in dict.items():
5633 if (basekey!="") and (k=="type"): k = ".type"
5634 # zuegs: following two lines should fix issue http://www.luxrender.net/forum/viewtopic.php?f=16&t=1618&p=14512#p14512
5635 if (basekey!="") and ((k[0]!=".") and (k[0]!=":")): k = ":"+k
5636 if (basekey=="") and (k[0:4]==":mat"): k = k[1:]
5637 luxProp(mat, basekey+k, None).set(v)
5638 if k[-8:] == '.texture':
5639 luxProp(mat, basekey+k[:-8]+'.textured', 'false').set('true')
5645 def MatTex2dict(d, tex = None):
5648 if LBX_VERSION == '0.6':
5650 if tex is not None and tex == True:
5651 d['LUX_DATA'] = 'TEXTURE'
5653 d['LUX_DATA'] = 'MATERIAL'
5655 d['LUX_VERSION'] = '0.6'
5659 elif LBX_VERSION == '0.7':
5662 if type(d[k]) == types.IntType:
5664 if type(d[k]) == types.FloatType:
5666 if type(d[k]) == types.BooleanType:
5668 if type(d[k]) == types.StringType:
5673 if l==None or len(l)!=3:
5678 definition.append([ t, k, d[k] ])
5682 'type': d['__type__'],
5684 'definition': definition,
5686 ['string', 'generator', 'luxblend'],
5692 def format_dictStr(dictStr):
5698 for char in dictStr:
5699 if char in ['}', ']']:
5702 for j in range(0,pos):
5707 if char in [',', '{', '[']:
5709 if char in ['{', '[']:
5711 for j in range(0,pos):
5717 def MatTex2str(d, tex = None):
5720 if LBX_VERSION == '0.6':
5721 return format_dictStr(str( MatTex2dict(d, tex) )) #.replace(", \'", ",\n\'")
5723 elif LBX_VERSION == '0.7':
5724 return format_dictStr(str( MatTex2dict(d, tex) )) #.replace("], \'", "],\r\n\'").replace("[","\r\n\t[")
5727 def str2MatTex(s, tex = None): # todo: this is not absolutely save from attacks!!!
5731 if (s[0]=='{') and (s[-1]=='}'):
5732 d = eval(s, dict(__builtins__=None,True=True,False=False))
5733 if type(d)==types.DictType:
5736 if LBX_VERSION == '0.6':
5738 if tex is not None and tex == True:
5739 test_str = 'TEXTURE'
5741 test_str = 'MATERIAL'
5743 if ('LUX_DATA' in d.keys() and d['LUX_DATA'] == test_str) \
5744 and ('LUX_VERSION' in d.keys() and (d['LUX_VERSION'] == '0.6' or d['LUX_VERSION'] == 0.6)):
5747 reason = 'Missing/incorrect metadata'
5749 elif LBX_VERSION == '0.7':
5751 def lb_list_to_dict(list):
5753 for t, k, v in list:
5760 if ('version' in d.keys() and d['version'] in ['0.6', '0.7']) \
5761 and ('type' in d.keys() and d['type'] in ['material', 'texture']) \
5762 and ('definition' in d.keys()):
5766 definition = lb_list_to_dict(d['definition'])
5768 if 'metadata' in d.keys():
5769 definition.update( lb_list_to_dict(d['metadata']) )
5773 reason = 'Incorrect LBX definition data'
5775 reason = 'Missing/incorrect metadata'
5777 reason = 'Unknown LBX version'
5779 reason = 'Not a parsed dict'
5781 reason = 'Not a stored dict'
5784 print "ERROR: string to material/texture conversion failed: %s" % reason
5788 luxclipboard = None # global variable for copy/paste content
5789 def showMatTexMenu(mat, basekey='', tex=False):
5790 global luxclipboard, ConnectLrmdb
5791 if tex: menu="Texture menu:%t"
5792 else: menu="Material menu:%t"
5795 if luxclipboard and (not(tex) ^ (luxclipboard["__type__"]=="texture")): menu +="|Paste%x2"
5798 menu += "|Load LBT%x3|Save LBT%x4"
5800 menu += "|Load LBM%x3|Save LBM%x4"
5802 menu += "|Download from DB%x5" #not(tex) and
5803 menu += "|Upload to DB%x6"
5805 # menu += "|%l|dump material%x99|dump clipboard%x98"
5806 r = Draw.PupMenu(menu)
5808 luxclipboard = getMatTex(mat, basekey, tex)
5809 elif r==2: putMatTex(mat, luxclipboard, basekey, tex)
5811 scn = Scene.GetCurrent()
5813 Window.FileSelector(lambda fn:loadMatTex(mat, fn, basekey, tex), "load texture", luxProp(scn, "lux", "").get()+os.sep+".lbt")
5815 Window.FileSelector(lambda fn:loadMatTex(mat, fn, basekey, tex), "load material", luxProp(scn, "lux", "").get()+os.sep+".lbm")
5817 scn = Scene.GetCurrent()
5819 Window.FileSelector(lambda fn:saveMatTex(mat, fn, basekey, tex), "save texture", luxProp(scn, "lux", "").get()+os.sep+".lbt")
5821 Window.FileSelector(lambda fn:saveMatTex(mat, fn, basekey, tex), "save material", luxProp(scn, "lux", "").get()+os.sep+".lbm")
5824 id = Draw.PupStrInput("Material ID:", "", 32)
5826 id = Draw.PupStrInput("Texture ID:", "", 32)
5827 if id: putMatTex(mat, downloadLRMDB(mat, id), basekey, tex)
5829 global lrmdb_connector
5830 if not lrmdb_connector.submit_object(mat, basekey, tex):
5831 msg = lrmdb_connector.last_error()
5835 Draw.PupMenu("Upload: "+msg+".%t|OK")
5837 # for k,v in mat.properties['luxblend'].convert_to_pyobject().items(): print k+"="+repr(v)
5839 # for k,v in luxclipboard.items(): print k+"="+repr(v)
5844 def saveMatTex(mat, fn, basekey='', tex=False):
5846 d = getMatTex(mat, basekey, tex)
5847 file = open(fn, 'w')
5848 file.write(MatTex2str(d, tex))
5850 if LuxIsGUI: Draw.Redraw()
5853 def loadMatTex(mat, fn, basekey='', tex=None):
5855 file = open(fn, 'r')
5858 data = str2MatTex(data, tex)
5859 putMatTex(mat, data, basekey, tex)
5860 if LuxIsGUI: Draw.Redraw()
5864 def setactivemat(mat):
5872 self.position = 0 # current position at top (inside 0..height-viewHeight)
5873 self.height = 0 # total height of the content
5874 self.viewHeight = 0 # height of window
5875 self.x = 0 # horizontal position of the scrollbar
5876 self.scrolling = self.over = False # start without scrolling ;)
5877 def calcRects(self):
5878 # Blender doesn't give us direct access to the window size yet, but it does set the
5879 # GL scissor box for it, so we can get the size from that. (thx to Daniel Dunbar)
5880 size = BGL.Buffer(BGL.GL_FLOAT, 4)
5881 BGL.glGetFloatv(BGL.GL_SCISSOR_BOX, size)
5882 size = size.list # [winx, winy, width, height]
5883 self.winrect = size[:]
5884 self.viewHeight = size[3]
5885 size[0], size[1] = size[2]-20, 0 # [scrollx1, scrolly1, scrollx2, scrolly2]
5887 if self.position < 0: self.position = 0
5888 if self.height < self.viewHeight: self.height = self.viewHeight
5889 if self.position > self.height-self.viewHeight: self.position = self.height-self.viewHeight
5890 self.factor = (size[3]-size[1]-4)/self.height
5891 self.sliderRect = [size[0]+2, size[3]-2-(self.position+self.viewHeight)*self.factor, size[2]-2, size[3]-2-self.position*self.factor]
5894 BGL.glColor3f(0.5,0.5,0.5); BGL.glRectf(self.rect[0],self.rect[1],self.rect[2],self.rect[3])
5895 if self.over or self.scrolling: BGL.glColor3f(1.0,1.0,0.7)
5896 else: BGL.glColor3f(0.7,0.7,0.7)
5897 BGL.glRectf(self.sliderRect[0],self.sliderRect[1],self.sliderRect[2],self.sliderRect[3])
5899 return self.viewHeight+self.position
5900 def scroll(self, delta):
5901 self.position = self.position + delta
5906 coord, buttons = Window.GetMouseCoords(), Window.GetMouseButtons()
5907 over = (coord[0]>=self.winrect[0]+self.rect[0]) and (coord[0]<=self.winrect[0]+self.rect[2]) and \
5908 (coord[1]>=self.winrect[1]+self.rect[1]) and (coord[1]<=self.winrect[1]+self.rect[3])
5909 if Window.MButs.L and buttons > 0:
5911 if self.factor > 0: self.scroll((self.lastcoord[1]-coord[1])/self.factor)
5914 self.scrolling = True
5915 self.lastcoord = coord
5916 elif self.scrolling:
5917 self.scrolling = False
5919 if self.over != over: Draw.Redraw()
5922 scrollbar = scrollbar()
5927 global icon_luxblend
5929 BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
5931 y = int(scrollbar.getTop()) # 420
5932 BGL.glColor3f(0.1,0.1,0.1); BGL.glRectf(0,0,440,y)
5933 BGL.glColor3f(1.0,0.5,0.0); BGL.glRasterPos2i(130,y-21); Draw.Text("v0.6RC5")
5934 BGL.glColor3f(0.9,0.9,0.9);
5936 drawLogo(icon_luxblend, 6, y-25);
5938 scn = Scene.GetCurrent()
5940 luxpage = luxProp(scn, "page", 0)
5944 BGL.glRasterPos2i(10,y-45); Draw.Text("Render presets:")
5945 luxpreset = luxProp(scn, "preset", "1C - Final - medium MLT/Path Tracing (indoor) (recommended)")
5946 presets = getScenePresets()
5947 presetskeys = presets.keys()
5949 presetskeys.insert(0, "")
5950 presetsstr = "presets: %t"
5951 for i, v in enumerate(presetskeys): presetsstr = "%s %%x%d|%s"%(v, i, presetsstr)
5952 try: i = presetskeys.index(luxpreset.get())
5953 except ValueError: i = 0
5954 Draw.Menu(presetsstr, evtLuxGui, 110, y-50, 220, 18, i, "", lambda e,v: luxpreset.set(presetskeys[v]))
5955 Draw.Button("save", evtSavePreset, 330, y-50, 40, 18, "create a render-settings preset")
5956 Draw.Button("del", evtDeletePreset, 370, y-50, 40, 18, "delete a render-settings preset")
5958 # if preset is selected load values
5959 if luxpreset.get() != "":
5961 d = presets[luxpreset.get()]
5962 for k,v in d.items(): scn.properties['luxblend'][k] = v
5965 Draw.Button("Material", evtLuxGui, 10, y-70, 80, 16, "", lambda e,v:luxpage.set(0))
5966 Draw.Button("Cam/Env", evtLuxGui, 90, y-70, 80, 16, "", lambda e,v:luxpage.set(1))
5967 Draw.Button("Render", evtLuxGui, 170, y-70, 80, 16, "", lambda e,v:luxpage.set(2))
5968 Draw.Button("Output", evtLuxGui, 250, y-70, 80, 16, "", lambda e,v:luxpage.set(3))
5969 Draw.Button("System", evtLuxGui, 330, y-70, 80, 16, "", lambda e,v:luxpage.set(4))
5970 if luxpage.get() == 0:
5971 BGL.glColor3f(1.0,0.5,0.0);BGL.glRectf(10,y-74,90,y-70);BGL.glColor3f(0.9,0.9,0.9)
5972 obj = scn.objects.active
5974 if (obj.getType() == "Lamp"):
5975 ltype = obj.getData(mesh=1).getType() # data
5976 if (ltype == Lamp.Types["Area"]): luxLight("Area LIGHT", "", obj, gui, 0)
5977 elif (ltype == Lamp.Types["Spot"]): luxSpot("Spot LIGHT", "", obj, gui, 0)
5978 elif (ltype == Lamp.Types["Lamp"]): luxLamp("Point LIGHT", "", obj, gui, 0)
5980 matfilter = luxProp(scn, "matlistfilter", "false")
5981 mats = getMaterials(obj, True)
5982 if (activemat == None) and (len(mats) > 0):
5983 setactivemat(mats[0])
5984 if matfilter.get() == "false":
5985 mats = Material.Get()
5987 for i, v in enumerate(mats):
5988 if v==activemat: matindex = i
5989 matnames = [m.getName() for m in mats]
5990 menustr = "Material: %t"
5991 for i, v in enumerate(matnames): menustr = "%s %%x%d|%s"%(v, i, menustr)
5992 gui.newline("MATERIAL:", 8)
5993 r = gui.getRect(1.1, 1)
5994 Draw.Button("C", evtConvertMaterial, r[0]-gui.h, gui.y-gui.h, gui.h, gui.h, "convert blender material to lux material")
5995 Draw.Menu(menustr, evtLuxGui, r[0], r[1], r[2], r[3], matindex, "", lambda e,v: setactivemat(mats[v]))
5996 luxBool("", matfilter, "filter", "only show active object materials", gui, 0.5)
5998 Draw.Button("L", evtLoadMaterial, gui.x, gui.y-gui.h, gui.h, gui.h, "load a material preset")
5999 Draw.Button("S", evtSaveMaterial, gui.x+gui.h, gui.y-gui.h, gui.h, gui.h, "save a material preset")
6000 Draw.Button("D", evtDeleteMaterial, gui.x+gui.h*2, gui.y-gui.h, gui.h, gui.h, "delete a material preset")
6002 setactivemat(mats[matindex])
6003 luxMaterial(activemat, gui)
6004 if luxpage.get() == 1:
6005 BGL.glColor3f(1.0,0.5,0.0);BGL.glRectf(90,y-74,170,y-70);BGL.glColor3f(0.9,0.9,0.9)
6006 cam = scn.getCurrentCamera()
6008 r = gui.getRect(1.1, 1)
6009 luxCamera(cam.data, scn.getRenderingContext(), gui)
6011 luxEnvironment(scn, gui)
6012 if luxpage.get() == 2:
6013 BGL.glColor3f(1.0,0.5,0.0);BGL.glRectf(170,y-74,250,y-70);BGL.glColor3f(0.9,0.9,0.9)
6014 r = gui.getRect(1.1, 1)
6015 luxSampler(scn, gui)
6017 luxSurfaceIntegrator(scn, gui)
6019 luxVolumeIntegrator(scn, gui)
6021 luxPixelFilter(scn, gui)
6022 if luxpage.get() == 3:
6023 BGL.glColor3f(1.0,0.5,0.0);BGL.glRectf(250,y-74,330,y-70);BGL.glColor3f(0.9,0.9,0.9)
6024 r = gui.getRect(1.1, 1)
6026 if luxpage.get() == 4:
6027 BGL.glColor3f(1.0,0.5,0.0);BGL.glRectf(330,y-74,410,y-70);BGL.glColor3f(0.9,0.9,0.9)
6030 luxAccelerator(scn, gui)
6031 gui.newline("MATERIALS:", 10)
6032 r = gui.getRect(2,1)
6033 Draw.Button("convert all blender materials", 0, r[0], r[1], r[2], r[3], "convert all blender-materials to lux-materials", lambda e,v:convertAllMaterials())
6034 gui.newline("SETTINGS:", 10)
6035 r = gui.getRect(2,1)
6036 Draw.Button("save defaults", 0, r[0], r[1], r[2], r[3], "save current settings as defaults", lambda e,v:saveluxdefaults())
6038 if y > 0: y = 0 # bottom align of render button
6039 run = luxProp(scn, "run", "true")
6040 dlt = luxProp(scn, "default", "true")
6041 clay = luxProp(scn, "clay", "false")
6042 nolg = luxProp(scn, "nolg", "false")
6043 lxs = luxProp(scn, "lxs", "true")
6044 lxo = luxProp(scn, "lxo", "true")
6045 lxm = luxProp(scn, "lxm", "true")
6046 lxv = luxProp(scn, "lxv", "true")
6047 net = luxProp(scn, "netrenderctl", "false")
6048 donet = luxProp(scn, "donetrender", "true")
6049 if (run.get()=="true"):
6050 Draw.Button("Render", 0, 10, y+20, 100, 36, "Render with Lux", lambda e,v:CBluxExport(dlt.get()=="true", True))
6051 Draw.Button("Render Anim", 0, 110, y+20, 100, 36, "Render animation with Lux", lambda e,v:CBluxAnimExport(dlt.get()=="true", True))
6053 Draw.Button("Export", 0, 10, y+20, 100, 36, "Export", lambda e,v:CBluxExport(dlt.get()=="true", False))
6054 Draw.Button("Export Anim", 0, 110, y+20, 100, 36, "Export animation", lambda e,v:CBluxAnimExport(dlt.get()=="true", False))
6056 Draw.Toggle("run", evtLuxGui, 290, y+40, 30, 16, run.get()=="true", "start Lux after export", lambda e,v: run.set(["false","true"][bool(v)]))
6057 Draw.Toggle("def", evtLuxGui, 320, y+40, 30, 16, dlt.get()=="true", "save to default.lxs", lambda e,v: dlt.set(["false","true"][bool(v)]))
6058 Draw.Toggle("clay", evtLuxGui, 350, y+40, 30, 16, clay.get()=="true", "all materials are rendered as white-matte", lambda e,v: clay.set(["false","true"][bool(v)]))
6059 Draw.Toggle("nolg", evtLuxGui, 380, y+40, 30, 16, nolg.get()=="true", "disables all light groups", lambda e,v: nolg.set(["false","true"][bool(v)]))
6060 Draw.Toggle(".lxs", 0, 290, y+20, 30, 16, lxs.get()=="true", "export .lxs scene file", lambda e,v: lxs.set(["false","true"][bool(v)]))
6061 Draw.Toggle(".lxo", 0, 320, y+20, 30, 16, lxo.get()=="true", "export .lxo geometry file", lambda e,v: lxo.set(["false","true"][bool(v)]))
6062 Draw.Toggle(".lxm", 0, 350, y+20, 30, 16, lxm.get()=="true", "export .lxm material file", lambda e,v: lxm.set(["false","true"][bool(v)]))
6063 Draw.Toggle(".lxv", 0, 380, y+20, 30, 16, lxm.get()=="true", "export .lxv volume file", lambda e,v: lxm.set(["false","true"][bool(v)]))
6064 BGL.glColor3f(0.9, 0.9, 0.9) ; BGL.glRasterPos2i(340,y+5) ; Draw.Text("Press Q or ESC to quit.", "tiny")
6065 scrollbar.height = scrollbar.getTop() - y
6081 def luxEvent(evt, val): # function that handles keyboard and mouse events
6082 global activeObject, activemat, activeEvent, lastEventTime, key_tabs
6083 if evt == Draw.ESCKEY or evt == Draw.QKEY:
6084 stop = Draw.PupMenu("OK?%t|Cancel export %x1")
6088 scn = Scene.GetCurrent()
6090 if scn.objects.active != activeObject:
6091 activeObject = scn.objects.active
6094 if (evt == Draw.MOUSEX) or (evt == Draw.MOUSEY): scrollbar.Mouse()
6095 if evt == Draw.WHEELUPMOUSE: scrollbar.scroll(-16)
6096 if evt == Draw.WHEELDOWNMOUSE: scrollbar.scroll(16)
6097 if evt == Draw.PAGEUPKEY: scrollbar.scroll(-50)
6098 if evt == Draw.PAGEDOWNKEY: scrollbar.scroll(50)
6100 # scroll to [T]op and [B]ottom
6101 if evt == Draw.TKEY:
6102 scrollbar.scroll(-scrollbar.position)
6103 if evt == Draw.BKEY:
6104 scrollbar.scroll(100000) # Some large number should be enough ?!
6106 # R key shortcut to launch render
6107 # E key shortcut to export current scene (not render)
6108 # P key shortcut to preview current material
6109 # These keys need time and process-complete locks
6110 if evt in [Draw.RKEY, Draw.EKEY, Draw.PKEY]:
6111 if activeEvent == None and (sys.time() - lastEventTime) > 5:
6112 lastEventTime = sys.time()
6113 if evt == Draw.RKEY:
6114 activeEvent = 'RKEY'
6115 CBluxExport(luxProp(scn, "default", "true").get() == "true", True)
6117 if evt == Draw.EKEY:
6118 activeEvent = 'EKEY'
6119 CBluxExport(luxProp(scn, "default", "true").get() == "true", False)
6121 if evt == Draw.PKEY:
6122 activeEvent = 'PKEY'
6123 if activemat != None:
6124 Preview_Update(activemat, '', True, 0, None, None, None)
6127 # Switch GUI tabs with number keys
6128 if evt in key_tabs.keys():
6129 luxProp(scn, "page", 0).set(key_tabs[evt])
6134 # Handle icon button events - note - radiance - this is a work in progress! :)
6135 # if evt == Draw.LEFTMOUSE and not val:
6136 # size=BGL.Buffer(BGL.GL_FLOAT, 4)
6137 # BGL.glGetFloatv(BGL.GL_SCISSOR_BOX, size)
6138 # size= [int(s) for s in size]
6139 # mx, my = Window.GetMouseCoords()
6140 # mousex = mx - size[0]
6141 # print "mousex = %i"%mousex
6142 # #if((mousex > 2) and (mousex < 25)):
6143 # # Mouse clicked in left button bar
6144 # if((mousex > 399) and (mousex < 418)):
6145 # # Mouse clicked in right button bar
6146 # mousey = my - size[1] - scrollbar.position
6147 # print "mousey = %i"%mousey
6150 def luxButtonEvt(evt): # function that handles button events
6151 global usedproperties, usedpropertiesfilterobj
6152 if evt == evtLuxGui:
6154 if evt == evtSavePreset:
6155 scn = Scene.GetCurrent()
6157 name = Draw.PupStrInput("preset name: ", "")
6160 usedpropertiesfilterobj = None
6161 luxSurfaceIntegrator(scn)
6166 # luxEnvironment(scn)
6167 saveScenePreset(name, usedproperties.copy())
6168 luxProp(scn, "preset", "").set(name)
6170 if evt == evtDeletePreset:
6171 presets = getScenePresets().keys()
6173 presetsstr = "delete preset: %t"
6174 for i, v in enumerate(presets): presetsstr += "|%s %%x%d"%(v, i)
6175 r = Draw.PupMenu(presetsstr, 20)
6177 saveScenePreset(presets[r], None)
6180 if evt == evtLoadMaterial:
6182 mats = getMaterialPresets()
6183 matskeys = mats.keys()
6185 matsstr = "load preset: %t"
6186 for i, v in enumerate(matskeys): matsstr += "|%s %%x%d"%(v, i)
6187 r = Draw.PupMenu(matsstr, 20)
6191 # for k,v in mats[name].items(): activemat.properties['luxblend'][k] = v
6192 for k,v in mats[name].items(): luxProp(activemat, k, None).set(v)
6195 if evt == evtSaveMaterial:
6197 name = Draw.PupStrInput("preset name: ", "")
6200 usedpropertiesfilterobj = activemat
6201 luxMaterial(activemat)
6202 saveMaterialPreset(name, usedproperties.copy())
6204 if evt == evtDeleteMaterial:
6205 matskeys = getMaterialPresets().keys()
6207 matsstr = "delete preset: %t"
6208 for i, v in enumerate(matskeys): matsstr += "|%s %%x%d"%(v, i)
6209 r = Draw.PupMenu(matsstr, 20)
6211 saveMaterialPreset(matskeys[r], None)
6213 if evt == evtConvertMaterial:
6214 if activemat: convertMaterial(activemat)
6216 if evt == evtLoadMaterial2:
6218 scn = Scene.GetCurrent()
6219 Window.FileSelector(lambda fn:loadMatTex(activemat, fn), "load material", luxProp(scn, "lux", "").get()+os.sep+".lbm")
6220 if evt == evtSaveMaterial2:
6222 scn = Scene.GetCurrent()
6223 Window.FileSelector(lambda fn:saveMaterial(activemat, fn), "save material", luxProp(scn, "lux", "").get()+os.sep+".lbm")
6226 def setFocus(target):
6227 currentscene = Scene.GetCurrent()
6228 camObj = currentscene.objects.camera # currentscene.getCurrentCamera()
6231 refLoc = (Object.GetSelected()[0]).getLocation()
6233 print "select an object to focus\n"
6235 refLoc = Window.GetCursorPos()
6237 refLoc = (Object.Get(target)).getLocation()
6238 dist = Mathutils.Vector(refLoc) - Mathutils.Vector(camObj.getLocation())
6239 camDir = camObj.getMatrix()[2]*(-1.0)
6240 camObj.getData(mesh=1).dofDist = (camDir[0]*dist[0]+camDir[1]*dist[1]+camDir[2]*dist[2])/camDir.length # data
6243 # Parse command line arguments for batch mode rendering if supplied
6246 batchindex = osys.argv.index('--batch')
6247 pyargs = osys.argv[osys.argv.index('--batch')+1:]
6250 if (pyargs != []) and (batchindex != 0):
6251 print "\n\nLuxBlend v0.6RC5 - BATCH mode\n"
6254 scene = Scene.GetCurrent()
6255 context = scene.getRenderingContext()
6259 o, a = getopt.getopt(pyargs, 's:e:o:t:l:',["scale=","haltspp=","run=", "lbm=", "lbt="])
6265 if (opts.has_key('--run')) and (opts['--run'] == 'false'):
6267 luxProp(scene, "run", "true").set("false")
6269 luxProp(scene, "run", "true").set("true")
6271 if opts.has_key('--scale'):
6272 print "Zoom: %s" %opts['--scale']
6273 luxProp(scene, "film.scale", "100 %").set(opts['--scale'])
6275 if opts.has_key('--haltspp'):
6276 print "haltspp: %s" %opts['--haltspp']
6277 luxProp(scene, "haltspp", 0).set(int(opts['--haltspp']))
6279 if opts.has_key('-s'):
6280 print "Start frame: %s" %opts['-s']
6281 context.startFrame(int(opts['-s']))
6283 print "Error: Start frame not supplied (-s)"; osys.exit(1)
6284 if opts.has_key('-e'):
6285 print "End frame: %s" %opts['-e']
6286 context.endFrame(int(opts['-e']))
6288 print "Error: End frame not supplied (-e)"; osys.exit(1)
6289 if opts.has_key('-l'):
6290 print "Path to lux binary: %s" %opts['-l']
6291 luxbatchconsolemode = luxProp(scene, "luxbatchc", "false")
6292 luxbatchconsolemode.set("true")
6293 luxpathprop = luxProp(scene, "lux", "")
6294 luxpathprop.set(opts['-l'])
6296 print "Error: path to lux binary not supplied (-l)"; osys.exit(1)
6297 if opts.has_key('-o'):
6298 print "Image output path: %s" %opts['-o']
6299 luxProp(scene, "overrideoutputpath", "").set(opts['-o'])
6301 print "Error: image output path not supplied (-o)"; osys.exit(1)
6302 if opts.has_key('-t'):
6303 print "Temporary export path: %s" %opts['-t']
6304 luxProp(scene, "datadir", "").set(opts['-t'])
6306 print "Error: Temporary export path not supplied (-t)"; osys.exit(1)
6308 if opts.has_key('--lbm'):
6309 print "Load material: %s" %opts['--lbm']
6310 mat = Material.Get("Material")
6311 if mat: loadMatTex(mat, opts['--lbm'])
6313 print "Error: No material with name \"Material\" found (--lbm)"; osys.exit(1)
6315 if opts.has_key('--lbt'):
6316 print "Load material: %s" %opts['--lbt']
6317 mat = Material.Get("Material")
6318 if mat: loadMatTex(mat, opts['--lbt'], ':Kd')
6320 print "Error: No material with name \"Material\" found (--lbt)"; osys.exit(1)
6322 # CBluxAnimExport(True, True)
6323 CBluxAnimExport(True, True, False) # as by zukazuka (http://www.luxrender.net/forum/viewtopic.php?f=11&t=1288)
6327 print "\n\nLuxBlend v0.6RC5 - UI mode\n"
6328 from Blender.Window import DrawProgressBar
6331 Draw.Register(luxDraw, luxEvent, luxButtonEvt) # init GUI
6333 luxpathprop = luxProp(Scene.GetCurrent(), "lux", "")
6334 luxpath = luxpathprop.get()
6335 luxrun = luxProp(Scene.GetCurrent(), "run", True).get()
6336 checkluxpath = luxProp(Scene.GetCurrent(), "checkluxpath", True).get()
6338 if checkluxpath and luxrun:
6339 if (luxpath is None) or (sys.exists(luxpath)<=0):
6340 # luxpath not valid, so delete entry from .blend scene file ...
6341 luxpathprop.delete()
6342 # and re-get luxpath, so we get the path from default-settings
6343 luxpath = luxpathprop.get()
6344 if (luxpath is None) or (sys.exists(luxpath)<=0):
6345 print "WARNING: LuxPath \"%s\" is not valid\n"%(luxpath)
6346 scn = Scene.GetCurrent()
6348 r = Draw.PupMenu("Installation: Set path to the lux render software?%t|Yes%x1|No%x0|Never%x2")
6350 Window.FileSelector(lambda s:luxProp(scn, "lux", "").set(Blender.sys.dirname(s)+os.sep), "Select file in Lux path")
6353 newluxdefaults["checkluxpath"] = False
6356 print "Lux path check disabled\n"