LuxBlend_0.1.py
author jensverwiebe
Sat Aug 08 00:48:19 2009 +0200 (2009-08-08)
changeset 338 a9ae8f25904a
parent 337 7754d0c5fc29
child 340 54697ccabb6f
permissions -rw-r--r--
changed all other RC-flags to RC5 too
jromang@0
     1
#!BPY
radiance29@241
     2
# coding=utf-8
jromang@0
     3
"""Registration info for Blender menus:
jensverwiebe@337
     4
Name: 'LuxBlend v0.6RC5 Exporter'
radiance29@160
     5
Blender: 248
radiance29@160
     6
Group: 'Render'
jensverwiebe@338
     7
Tooltip: 'Export/Render to LuxRender v0.6RC5 scene format (.lxs)'
jromang@0
     8
"""
jromang@0
     9
#
jromang@0
    10
# ***** BEGIN GPL LICENSE BLOCK *****
jromang@0
    11
#
jromang@0
    12
# --------------------------------------------------------------------------
jensverwiebe@338
    13
# LuxBlend v0.6RC5 exporter
jromang@0
    14
# --------------------------------------------------------------------------
jromang@0
    15
#
jromang@0
    16
# Authors:
dougal2@217
    17
# radiance, zuegs, ideasman42, luxblender, dougal2
dougal2@191
    18
#
jromang@0
    19
# This program is free software; you can redistribute it and/or
jromang@0
    20
# modify it under the terms of the GNU General Public License
jromang@0
    21
# as published by the Free Software Foundation; either version 2
jromang@0
    22
# of the License, or (at your option) any later version.
jromang@0
    23
#
jromang@0
    24
# This program is distributed in the hope that it will be useful,
jromang@0
    25
# but WITHOUT ANY WARRANTY; without even the implied warranty of
jromang@0
    26
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
jromang@0
    27
# GNU General Public License for more details.
jromang@0
    28
#
jromang@0
    29
# You should have received a copy of the GNU General Public License
jromang@0
    30
# along with this program; if not, write to the Free Software Foundation,
jromang@0
    31
# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
jromang@0
    32
#
jromang@0
    33
# ***** END GPL LICENCE BLOCK *****
jromang@0
    34
# --------------------------------------------------------------------------
jromang@0
    35
zuegs@21
    36
zuegs@22
    37
zuegs@22
    38
jromang@0
    39
######################################################
jromang@0
    40
# Importing modules
jromang@0
    41
######################################################
jromang@0
    42
jromang@0
    43
import math
dougal2@221
    44
import time
jromang@0
    45
import os
radiance29@1
    46
import sys as osys
radiance29@132
    47
import types
dade916@104
    48
import subprocess
jromang@0
    49
import Blender
zuegs@45
    50
from Blender import Mesh, Scene, Object, Material, Texture, Window, sys, Draw, BGL, Mathutils, Lamp, Image
zuegs@45
    51
jromang@0
    52
jromang@0
    53
zuegs@21
    54
jromang@0
    55
######################################################
jromang@0
    56
# Functions
jromang@0
    57
######################################################
jromang@0
    58
jromang@0
    59
# New name based on old with a different extension
jromang@0
    60
def newFName(ext):
dougal2@223
    61
    return Blender.Get('filename')[: -len(Blender.Get('filename').split('.', -1)[-1]) ] + ext
jromang@0
    62
jromang@0
    63
zuegs@255
    64
# some helpers
zuegs@255
    65
def luxstr(str):
zuegs@255
    66
    return str.replace("\\", "\\\\")
zuegs@255
    67
zuegs@255
    68
zuegs@255
    69
### relpath ##########################
zuegs@255
    70
def relpath(base, target):
dougal2@258
    71
    if target[0:2] == "\\\\" or target[0:2] == "//":
dougal2@258
    72
        return target[2:len(target)]
dougal2@258
    73
    if not os.path.isabs(base):
dougal2@258
    74
        base = os.path.abspath(base)
dougal2@258
    75
    if not os.path.isabs(target):
dougal2@258
    76
        target = os.path.abspath(target)
dougal2@258
    77
    if os.sep == "\\":
dougal2@258
    78
        base = os.path.normcase(base)
dougal2@258
    79
        target = os.path.normcase(target)
dougal2@258
    80
    if base == os.sep:
dougal2@258
    81
        return '.' + target
dougal2@258
    82
    baselist = base.split(os.sep)
dougal2@258
    83
    if baselist[-1] == "":
dougal2@258
    84
        baselist = baselist[:-1]
dougal2@258
    85
    targetlist = target.split(os.sep)
dougal2@258
    86
    i = 0
dougal2@258
    87
    top = min([len(baselist), len(targetlist)])
dougal2@258
    88
    while i < top and baselist[i] == targetlist[i]:
dougal2@258
    89
        i+=1
dougal2@258
    90
    if i == 0:
dougal2@258
    91
        return os.sep.join(targetlist)
dougal2@258
    92
    if i == len(baselist):
dougal2@258
    93
        return os.sep.join(targetlist[i:])
dougal2@258
    94
    else:
dougal2@258
    95
        return ('..' + os.sep) * (len(baselist) - i) + os.sep.join(targetlist[i:])
zuegs@255
    96
zuegs@255
    97
### luxFilePath #####################
zuegs@255
    98
lxs_filename = ""
zuegs@255
    99
previewing = False
zuegs@255
   100
def luxFilePath(filename):
zuegs@255
   101
    global lxs_filename, previewing
zuegs@255
   102
    scn = Scene.GetCurrent()
zuegs@255
   103
    pm = luxProp(scn, "pathmode", "absolute").get()
zuegs@255
   104
    if (pm=="absolute") or previewing: # absolute paths (the old / default mode)
zuegs@255
   105
        return filename
zuegs@255
   106
    elif pm=="relative": # relative paths
zuegs@255
   107
        base = os.path.dirname(lxs_filename)
zuegs@255
   108
        return relpath(base, filename)
zuegs@255
   109
    elif pm=="flat": # flat mode - only filename
zuegs@255
   110
        return os.path.basename(filename)
zuegs@255
   111
zuegs@255
   112
zuegs@255
   113
radiance29@1
   114
###### RGC ##########################
radiance29@1
   115
def rg(col):
dougal2@223
   116
    scn = Scene.GetCurrent()
dougal2@223
   117
    if luxProp(scn, "RGC", "true").get()=="true":
dougal2@223
   118
        gamma = luxProp(scn, "film.gamma", 2.2).get()
dougal2@223
   119
    else:
dougal2@223
   120
        gamma = 1.0
dougal2@223
   121
    ncol = col**gamma
dougal2@223
   122
    if luxProp(scn, "colorclamp", "false").get()=="true":
dougal2@223
   123
        ncol = ncol * 0.9
dougal2@223
   124
        if ncol > 0.9:
dougal2@223
   125
            ncol = 0.9
dougal2@223
   126
        if ncol < 0.0:
dougal2@223
   127
            ncol = 0.0
dougal2@223
   128
    return ncol
radiance29@1
   129
radiance29@111
   130
def texturegamma():
dougal2@223
   131
    scn = Scene.GetCurrent()
dougal2@223
   132
    if luxProp(scn, "RGC", "true").get()=="true":
dougal2@223
   133
        return luxProp(scn, "film.gamma", 2.2).get()
dougal2@223
   134
    else:
dougal2@223
   135
        return 1.0
radiance29@111
   136
jromang@0
   137
def exportMaterial(mat):
dougal2@223
   138
    str = "# Material '%s'\n" %mat.name
dougal2@223
   139
    return str+luxMaterial(mat)+"\n"
jromang@0
   140
jromang@0
   141
jromang@0
   142
def exportMaterialGeomTag(mat):
dougal2@223
   143
    return "%s\n"%(luxProp(mat, "link", "").get())
jromang@0
   144
jromang@0
   145
jromang@0
   146
jromang@0
   147
jromang@0
   148
################################################################
jromang@0
   149
jromang@0
   150
zuegs@37
   151
dummyMat = 2394723948 # random identifier for dummy material
zuegs@37
   152
clayMat = None
jromang@0
   153
zuegs@21
   154
#-------------------------------------------------
zuegs@21
   155
# getMaterials(obj)
zuegs@21
   156
# helper function to get the material list of an object in respect of obj.colbits
zuegs@21
   157
#-------------------------------------------------
zuegs@21
   158
def getMaterials(obj, compress=False):
dougal2@223
   159
    global clayMat
dougal2@223
   160
    mats = [None]*16
dougal2@223
   161
    colbits = obj.colbits
dougal2@223
   162
    objMats = obj.getMaterials(1)
dougal2@223
   163
    data = obj.getData(mesh=1)
dougal2@223
   164
    try:
dougal2@223
   165
        dataMats = data.materials
dougal2@223
   166
    except:
dougal2@223
   167
        try:
dougal2@223
   168
            dataMats = data.getMaterials(1)
dougal2@223
   169
        except:
dougal2@223
   170
            dataMats = []
dougal2@223
   171
            colbits = 0xffff
dougal2@223
   172
    m = max(len(objMats), len(dataMats))
dougal2@223
   173
    if m>0:
dougal2@223
   174
        objMats.extend([None]*16)
dougal2@223
   175
        dataMats.extend([None]*16)
dougal2@223
   176
        for i in range(m):
dougal2@223
   177
            if (colbits & (1<<i) > 0):
dougal2@223
   178
                mats[i] = objMats[i]
dougal2@223
   179
            else:
dougal2@223
   180
                mats[i] = dataMats[i]
dougal2@223
   181
        if compress:
dougal2@223
   182
            mats = [m for m in mats if m]
dougal2@223
   183
    else:
dougal2@223
   184
        print "Warning: object %s has no material assigned"%(obj.getName())
dougal2@223
   185
        mats = []
dougal2@223
   186
    # clay option
dougal2@223
   187
    if luxProp(Scene.GetCurrent(), "clay", "false").get()=="true":
dougal2@223
   188
        if clayMat==None: clayMat = Material.New("lux_clayMat")
dougal2@223
   189
        for i in range(len(mats)):
dougal2@223
   190
            if mats[i]:
dougal2@223
   191
                mattype = luxProp(mats[i], "type", "").get()
dougal2@223
   192
                if (mattype not in ["portal","light","boundvolume"]): mats[i] = clayMat
dougal2@223
   193
    return mats
zuegs@21
   194
zuegs@21
   195
zuegs@21
   196
jromang@0
   197
######################################################
jromang@0
   198
# luxExport class
jromang@0
   199
######################################################
zuegs@10
   200
jromang@0
   201
class luxExport:
dougal2@223
   202
    #-------------------------------------------------
dougal2@223
   203
    # __init__
dougal2@223
   204
    # initializes the exporter object
dougal2@223
   205
    #-------------------------------------------------
dougal2@223
   206
    def __init__(self, scene):
dougal2@223
   207
        self.scene = scene
dougal2@223
   208
        self.camera = scene.objects.camera
dougal2@223
   209
        self.objects = []
dougal2@223
   210
        self.portals = []
dougal2@223
   211
        self.volumes = []
dougal2@223
   212
        self.meshes = {}
dougal2@223
   213
        self.materials = []
dougal2@223
   214
        self.lights = []
jensverwiebe@305
   215
        self.duplis = set()
dougal2@223
   216
dougal2@223
   217
    #-------------------------------------------------
dougal2@223
   218
    # analyseObject(self, obj, matrix, name)
dougal2@223
   219
    # called by analyseScene to build the lists before export
dougal2@223
   220
    #-------------------------------------------------
jensverwiebe@305
   221
    def analyseObject(self, obj, matrix, name, isOriginal=True, isDupli=False):
dougal2@223
   222
        light = False
dougal2@223
   223
        if (obj.users > 0):
dougal2@223
   224
            obj_type = obj.getType()
dougal2@223
   225
            if (obj.enableDupFrames and isOriginal):
dougal2@223
   226
                for o, m in obj.DupObjects:
dougal2@223
   227
                    self.analyseObject(o, m, "%s.%s"%(name, o.getName()), False)    
jensverwiebe@305
   228
            if (obj.enableDupGroup or obj.enableDupVerts or obj.enableDupFaces):
jensverwiebe@305
   229
                self.duplis.add(obj)
dougal2@223
   230
                for o, m in obj.DupObjects:
jensverwiebe@305
   231
                    self.analyseObject(o, m, "%s.%s"%(name, o.getName()), True, True)    
jensverwiebe@305
   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"))):
dougal2@223
   233
                mats = getMaterials(obj)
dougal2@223
   234
                if (len(mats)>0) and (mats[0]!=None) and ((mats[0].name=="PORTAL") or (luxProp(mats[0], "type", "").get()=="portal")):
dougal2@223
   235
                    self.portals.append([obj, matrix])
dougal2@223
   236
                elif (len(mats)>0) and (luxProp(mats[0], "type", "").get()=="boundvolume"):
dougal2@223
   237
                    self.volumes.append([obj, matrix])
dougal2@223
   238
                else:
dougal2@223
   239
                    for mat in mats:
dougal2@223
   240
                        if (mat!=None) and (mat not in self.materials):
dougal2@223
   241
                            self.materials.append(mat)
dougal2@223
   242
                        if (mat!=None) and ((luxProp(mat, "type", "").get()=="light") or (luxProp(mat, "emission", "false").get()=="true")):
dougal2@223
   243
                            light = True
dougal2@223
   244
                    mesh_name = obj.getData(name_only=True)
dougal2@223
   245
                    try:
dougal2@223
   246
                        self.meshes[mesh_name] += [obj]
dougal2@223
   247
                    except KeyError:
dougal2@223
   248
                        self.meshes[mesh_name] = [obj]                
dougal2@223
   249
                    self.objects.append([obj, matrix])
dougal2@223
   250
            elif (obj_type == "Lamp"):
dougal2@223
   251
                ltype = obj.getData(mesh=1).getType() # data
dougal2@223
   252
                if (ltype == Lamp.Types["Lamp"]) or (ltype == Lamp.Types["Spot"]) or (ltype == Lamp.Types["Area"]):
dougal2@223
   253
                    self.lights.append([obj, matrix])
dougal2@223
   254
                    light = True
dougal2@223
   255
        return light
dougal2@223
   256
dougal2@223
   257
    #-------------------------------------------------
dougal2@223
   258
    # analyseScene(self)
dougal2@223
   259
    # this function builds the lists of object, lights, meshes and materials before export
dougal2@223
   260
    #-------------------------------------------------
dougal2@223
   261
    def analyseScene(self):
dougal2@223
   262
        light = False
dougal2@223
   263
        for obj in self.scene.objects:
dougal2@223
   264
            if ((obj.Layers & self.scene.Layers) > 0):
dougal2@223
   265
                if self.analyseObject(obj, obj.getMatrix(), obj.getName()): light = True
dougal2@223
   266
        return light
dougal2@223
   267
dougal2@223
   268
    #-------------------------------------------------
dougal2@223
   269
    # exportMaterialLink(self, file, mat)
dougal2@223
   270
    # exports material link. LuxRender "Material" 
dougal2@223
   271
    #-------------------------------------------------
dougal2@223
   272
    def exportMaterialLink(self, file, mat):
dougal2@223
   273
        if mat == dummyMat:
dougal2@223
   274
            file.write("\tMaterial \"matte\" # dummy material\n")
dougal2@223
   275
        else:
dougal2@223
   276
            file.write("\t%s"%exportMaterialGeomTag(mat)) # use original methode
dougal2@223
   277
dougal2@223
   278
    #-------------------------------------------------
dougal2@223
   279
    # exportMaterial(self, file, mat)
dougal2@223
   280
    # exports material. LuxRender "Texture" 
dougal2@223
   281
    #-------------------------------------------------
dougal2@223
   282
    def exportMaterial(self, file, mat):
dougal2@260
   283
        print "material %s"%(mat.getName())
dougal2@223
   284
        file.write("\t%s"%exportMaterial(mat)) # use original methode        
dougal2@223
   285
    
dougal2@223
   286
    #-------------------------------------------------
dougal2@223
   287
    # exportMaterials(self, file)
dougal2@223
   288
    # exports materials to the file
dougal2@223
   289
    #-------------------------------------------------
dougal2@223
   290
    def exportMaterials(self, file):
dougal2@223
   291
        for mat in self.materials:
dougal2@260
   292
            
dougal2@223
   293
            self.exportMaterial(file, mat)
dougal2@223
   294
dougal2@223
   295
    #-------------------------------------------------
dougal2@223
   296
    # getMeshType(self, vertcount, mat)
dougal2@223
   297
    # returns type of mesh as string to use depending on thresholds
dougal2@223
   298
    #-------------------------------------------------
dougal2@223
   299
    def getMeshType(self, vertcount, mat):
dougal2@223
   300
        scn = Scene.GetCurrent()
dougal2@223
   301
        if mat != dummyMat:
dougal2@223
   302
            usesubdiv = luxProp(mat, "subdiv", "false")
dougal2@223
   303
            usedisp = luxProp(mat, "dispmap", "false")
dougal2@223
   304
            sharpbound = luxProp(mat, "sharpbound", "false")
dougal2@223
   305
            nsmooth = luxProp(mat, "nsmooth", "true")
dougal2@223
   306
            sdoffset = luxProp(mat, "sdoffset", 0.0)
dougal2@223
   307
            dstr = ""
dougal2@223
   308
            if usesubdiv.get() == "true":
dougal2@223
   309
                nlevels = luxProp(mat, "sublevels", 1)
dougal2@223
   310
                dstr += "\"loopsubdiv\" \"integer nlevels\" [%i] \"bool dmnormalsmooth\" [\"%s\"] \"bool dmsharpboundary\" [\"%s\"]"% (nlevels.get(), nsmooth.get(), sharpbound.get())
dougal2@223
   311
            
dougal2@223
   312
            if usedisp.get() == "true":
dougal2@223
   313
                dstr += " \"string displacementmap\" [\"%s::dispmap.scale\"] \"float dmscale\" [-1.0] \"float dmoffset\" [%f]"%(mat.getName(), sdoffset.get()) # scale is scaled in texture
dougal2@223
   314
dougal2@223
   315
            if dstr != "": return dstr
dougal2@223
   316
dougal2@223
   317
        return "\"trianglemesh\""
dougal2@223
   318
dougal2@223
   319
    #-------------------------------------------------
dougal2@223
   320
    # exportMesh(self, file, mesh, mats, name, portal)
dougal2@223
   321
    # exports mesh to the file without any optimization
dougal2@223
   322
    #-------------------------------------------------
dougal2@223
   323
    def exportMesh(self, file, mesh, mats, name, portal=False):
dougal2@223
   324
        if mats == []:
dougal2@223
   325
            mats = [dummyMat]
dougal2@223
   326
        for matIndex in range(len(mats)):
dougal2@223
   327
            if (mats[matIndex] != None):
dougal2@223
   328
                mesh_str = getMeshType(len(mesh.verts), mats[matIndex])
dougal2@223
   329
                if (portal):
dougal2@223
   330
                    file.write("\tShape %s \"integer indices\" [\n"% mesh_str)
dougal2@223
   331
                else:
dougal2@223
   332
                    self.exportMaterialLink(file, mats[matIndex])
dougal2@223
   333
                    file.write("\tPortalShape %s \"integer indices\" [\n"% mesh_str)
dougal2@223
   334
                index = 0
dougal2@223
   335
                ffaces = [f for f in mesh.faces if f.mat == matIndex]
dougal2@223
   336
                for face in ffaces:
dougal2@223
   337
                    file.write("%d %d %d\n"%(index, index+1, index+2))
dougal2@223
   338
                    if (len(face)==4):
dougal2@223
   339
                        file.write("%d %d %d\n"%(index, index+2, index+3))
dougal2@223
   340
                    index += len(face.verts)
dougal2@223
   341
                file.write("\t] \"point P\" [\n");
dougal2@223
   342
                for face in ffaces:
dougal2@223
   343
                    for vertex in face:
dougal2@223
   344
                        file.write("%f %f %f\n"% tuple(vertex.co))
dougal2@223
   345
                file.write("\t] \"normal N\" [\n")
dougal2@223
   346
                for face in ffaces:
dougal2@223
   347
                    normal = face.no
dougal2@223
   348
                    for vertex in face:
dougal2@223
   349
                        if (face.smooth):
dougal2@223
   350
                            normal = vertex.no
dougal2@223
   351
                        file.write("%f %f %f\n"% tuple(normal))
dougal2@223
   352
                if (mesh.faceUV):
dougal2@223
   353
                    file.write("\t] \"float uv\" [\n")
dougal2@223
   354
                    for face in ffaces:
dougal2@223
   355
                        for uv in face.uv:
dougal2@223
   356
                            file.write("%f %f\n"% tuple(uv))
dougal2@223
   357
                file.write("\t]\n")
dougal2@223
   358
dougal2@223
   359
    #-------------------------------------------------
dougal2@223
   360
    # exportMeshOpt(self, file, mesh, mats, name, portal, optNormals)
dougal2@223
   361
    # exports mesh to the file with optimization.
dougal2@223
   362
    # portal: export without normals and UVs
dougal2@223
   363
    # optNormals: speed and filesize optimization, flat faces get exported without normals
dougal2@223
   364
    #-------------------------------------------------
dougal2@223
   365
    def exportMeshOpt(self, file, mesh, mats, name, portal=False, optNormals=True):
dougal2@223
   366
        shapeList, smoothFltr, shapeText = [0], [[0,1]], [""]
dougal2@223
   367
        if portal:
dougal2@223
   368
            normalFltr, uvFltr, shapeText = [0], [0], ["portal"] # portal, no normals, no UVs
dougal2@223
   369
        else:
dougal2@223
   370
            uvFltr, normalFltr, shapeText = [1], [1], ["mixed with normals"] # normals and UVs
dougal2@223
   371
            if optNormals: # one pass for flat faces without normals and another pass for smoothed faces with normals, all with UVs
dougal2@223
   372
                shapeList, smoothFltr, normalFltr, uvFltr, shapeText = [0,1], [[0],[1]], [0,1], [1,1], ["flat w/o normals", "smoothed with normals"]
dougal2@223
   373
        if mats == []:
dougal2@223
   374
            mats = [dummyMat]
dougal2@223
   375
        for matIndex in range(len(mats)):
dougal2@223
   376
            if (mats[matIndex] != None):
dougal2@223
   377
                if not(portal):
dougal2@223
   378
                    self.exportMaterialLink(file, mats[matIndex])
dougal2@223
   379
                for shape in shapeList:
dougal2@223
   380
                    blenderExportVertexMap = []
dougal2@223
   381
                    exportVerts = []
dougal2@223
   382
                    exportFaces = []
dougal2@223
   383
                    ffaces = [f for f in mesh.faces if (f.mat == matIndex) and (f.smooth in smoothFltr[shape])]
dougal2@223
   384
                    for face in ffaces:
dougal2@223
   385
                        exportVIndices = []
dougal2@223
   386
                        index = 0
dougal2@223
   387
                        for vertex in face:
dougal2@223
   388
#                            v = [vertex.co[0], vertex.co[1], vertex.co[2]]
dougal2@223
   389
                            v = [vertex.co]
dougal2@223
   390
                            if normalFltr[shape]:
dougal2@223
   391
                                if (face.smooth):
dougal2@223
   392
#                                    v.extend(vertex.no)
dougal2@223
   393
                                    v.append(vertex.no)
dougal2@223
   394
                                else:
dougal2@223
   395
#                                    v.extend(face.no)
dougal2@223
   396
                                    v.append(face.no)
dougal2@223
   397
                            if (uvFltr[shape]) and (mesh.faceUV):
dougal2@223
   398
#                                v.extend(face.uv[index])
dougal2@223
   399
                                v.append(face.uv[index])
dougal2@223
   400
                            blenderVIndex = vertex.index
dougal2@223
   401
                            newExportVIndex = -1
dougal2@223
   402
                            length = len(v)
dougal2@223
   403
                            if (blenderVIndex < len(blenderExportVertexMap)):
dougal2@223
   404
                                for exportVIndex in blenderExportVertexMap[blenderVIndex]:
dougal2@223
   405
                                    v2 = exportVerts[exportVIndex]
dougal2@223
   406
                                    if (length==len(v2)) and (v == v2):
dougal2@223
   407
                                        newExportVIndex = exportVIndex
dougal2@223
   408
                                        break
dougal2@223
   409
                            if (newExportVIndex < 0):
dougal2@223
   410
                                newExportVIndex = len(exportVerts)
dougal2@223
   411
                                exportVerts.append(v)
dougal2@223
   412
                                while blenderVIndex >= len(blenderExportVertexMap):
dougal2@223
   413
                                    blenderExportVertexMap.append([])
dougal2@223
   414
                                blenderExportVertexMap[blenderVIndex].append(newExportVIndex)
dougal2@223
   415
                            exportVIndices.append(newExportVIndex)
dougal2@223
   416
                            index += 1
dougal2@223
   417
                        exportFaces.append(exportVIndices)
dougal2@223
   418
                    if (len(exportVerts)>0):
dougal2@223
   419
                        mesh_str = self.getMeshType(len(exportVerts), mats[matIndex])
dougal2@223
   420
                        if (portal):
dougal2@223
   421
                            file.write("\tPortalShape %s \"integer indices\" [\n"% mesh_str)
dougal2@223
   422
                        else:
dougal2@223
   423
                            file.write("\tShape %s \"integer indices\" [\n"% mesh_str)
dougal2@223
   424
                        for face in exportFaces:
dougal2@223
   425
                            file.write("%d %d %d\n"%(face[0], face[1], face[2]))
dougal2@223
   426
                            if (len(face)==4):
dougal2@223
   427
                                file.write("%d %d %d\n"%(face[0], face[2], face[3]))
dougal2@223
   428
                        file.write("\t] \"point P\" [\n");
dougal2@223
   429
#                        for vertex in exportVerts:
dougal2@223
   430
#                            file.write("%f %f %f\n"%(vertex[0], vertex[1], vertex[2]))
dougal2@223
   431
                        file.write("".join(["%f %f %f\n"%tuple(vertex[0]) for vertex in exportVerts]))
dougal2@223
   432
                        if normalFltr[shape]:
dougal2@223
   433
                            file.write("\t] \"normal N\" [\n")
dougal2@223
   434
#                            for vertex in exportVerts:
dougal2@223
   435
#                                file.write("%f %f %f\n"%(vertex[3], vertex[4], vertex[5]))
dougal2@223
   436
                            file.write("".join(["%f %f %f\n"%tuple(vertex[1]) for vertex in exportVerts])) 
dougal2@223
   437
                            if (uvFltr[shape]) and (mesh.faceUV):
dougal2@223
   438
                                file.write("\t] \"float uv\" [\n")
dougal2@223
   439
#                                for vertex in exportVerts:
dougal2@223
   440
#                                    file.write("%f %f\n"%(vertex[6], vertex[7]))
dougal2@223
   441
                                file.write("".join(["%f %f\n"%tuple(vertex[2]) for vertex in exportVerts])) 
dougal2@223
   442
                        else:            
dougal2@223
   443
                            if (uvFltr[shape]) and (mesh.faceUV):
dougal2@223
   444
                                file.write("\t] \"float uv\" [\n")
dougal2@223
   445
#                                for vertex in exportVerts:
dougal2@223
   446
#                                    file.write("%f %f\n"%(vertex[3], vertex[4]))
dougal2@223
   447
                                file.write("".join(["%f %f\n"%tuple(vertex[1]) for vertex in exportVerts])) 
dougal2@223
   448
                        file.write("\t]\n")
dougal2@223
   449
                        print "  shape(%s): %d vertices, %d faces"%(shapeText[shape], len(exportVerts), len(exportFaces))
dougal2@223
   450
    
dougal2@223
   451
    #-------------------------------------------------
dougal2@223
   452
    # exportMeshes(self, file)
dougal2@223
   453
    # exports meshes that uses instancing (meshes that are used by at least "instancing_threshold" objects)
dougal2@223
   454
    #-------------------------------------------------
dougal2@223
   455
    def exportMeshes(self, file):
dougal2@223
   456
        scn = Scene.GetCurrent()
dougal2@223
   457
        instancing_threshold = luxProp(scn, "instancing_threshold", 2).get()
dougal2@223
   458
        mesh_optimizing = luxProp(scn, "mesh_optimizing", True).get()
dougal2@223
   459
        mesh = Mesh.New('')
dougal2@223
   460
        for (mesh_name, objs) in self.meshes.items():
dougal2@223
   461
            allow_instancing = True
dougal2@223
   462
            mats = getMaterials(objs[0]) # mats = obj.getData().getMaterials()
dougal2@223
   463
            for mat in mats: # don't instance if one of the materials is emissive
dougal2@223
   464
                if (mat!=None) and (luxProp(mat, "type", "").get()=="light"):
dougal2@223
   465
                    allow_instancing = False
dougal2@223
   466
            for obj in objs: # don't instance if the objects with same mesh uses different materials
dougal2@223
   467
                ms = getMaterials(obj)
dougal2@223
   468
                if ms <> mats:
dougal2@223
   469
                    allow_instancing = False
dougal2@235
   470
            if obj.modifiers.__len__() > 0:
dougal2@235
   471
                allow_instancing = False
zuegs@226
   472
            if allow_instancing and (len(objs) > instancing_threshold):
dougal2@223
   473
                del self.meshes[mesh_name]
dougal2@223
   474
                mesh.getFromObject(objs[0], 0, 1)
dougal2@223
   475
                print "blender-mesh: %s (%d vertices, %d faces)"%(mesh_name, len(mesh.verts), len(mesh.faces))
dougal2@223
   476
                file.write("ObjectBegin \"%s\"\n"%mesh_name)
dougal2@223
   477
                if (mesh_optimizing):
dougal2@223
   478
                    self.exportMeshOpt(file, mesh, mats, mesh_name)
dougal2@223
   479
                else:
dougal2@223
   480
                    self.exportMesh(file, mesh, mats, mesh_name)
dougal2@223
   481
                file.write("ObjectEnd # %s\n\n"%mesh_name)
dougal2@223
   482
        mesh.verts = None
dougal2@223
   483
dougal2@223
   484
    #-------------------------------------------------
dougal2@223
   485
    # exportObjects(self, file)
dougal2@223
   486
    # exports objects to the file
dougal2@223
   487
    #-------------------------------------------------
dougal2@223
   488
    def exportObjects(self, file):
dougal2@223
   489
        scn = Scene.GetCurrent()
dougal2@223
   490
        cam = scn.getCurrentCamera().data
dougal2@223
   491
        objectmblur = luxProp(cam, "objectmblur", "true")
dougal2@223
   492
        usemblur = luxProp(cam, "usemblur", "false")
dougal2@223
   493
        mesh_optimizing = luxProp(scn, "mesh_optimizing", True).get()
dougal2@223
   494
        mesh = Mesh.New('')
dougal2@223
   495
        for [obj, matrix] in self.objects:
dougal2@223
   496
            print "object: %s"%(obj.getName())
dougal2@223
   497
            mesh_name = obj.getData(name_only=True)
dougal2@223
   498
dougal2@223
   499
            motion = None
dougal2@223
   500
            if(objectmblur.get() == "true" and usemblur.get() == "true"):
dougal2@223
   501
                # motion blur
dougal2@223
   502
                frame = Blender.Get('curframe')
dougal2@223
   503
                Blender.Set('curframe', frame+1)
dougal2@223
   504
                m1 = 1.0*matrix # multiply by 1.0 to get a copy of orignal matrix (will be frame-independant) 
dougal2@223
   505
                Blender.Set('curframe', frame)
dougal2@223
   506
                if m1 != matrix:
dougal2@223
   507
                    print "  motion blur"
dougal2@223
   508
                    motion = m1
dougal2@223
   509
    
dougal2@223
   510
            if motion: # motion-blur only works with instances, so ensure mesh is exported as instance first
dougal2@223
   511
                if mesh_name in self.meshes:
dougal2@223
   512
                    del self.meshes[mesh_name]
dougal2@223
   513
                    mesh.getFromObject(obj, 0, 1)
dougal2@223
   514
                    mats = getMaterials(obj)
dougal2@223
   515
                    print "  blender-mesh: %s (%d vertices, %d faces)"%(mesh_name, len(mesh.verts), len(mesh.faces))
dougal2@223
   516
                    file.write("ObjectBegin \"%s\"\n"%mesh_name)
dougal2@223
   517
                    if (mesh_optimizing):
dougal2@223
   518
                        self.exportMeshOpt(file, mesh, mats, mesh_name)
dougal2@223
   519
                    else:
dougal2@223
   520
                        self.exportMesh(file, mesh, mats, mesh_name)
dougal2@223
   521
                    file.write("ObjectEnd # %s\n\n"%mesh_name)
dougal2@223
   522
dougal2@223
   523
            file.write("AttributeBegin # %s\n"%obj.getName())
dougal2@223
   524
            file.write("\tTransform [%s %s %s %s  %s %s %s %s  %s %s %s %s  %s %s %s %s]\n"\
dougal2@223
   525
                %(matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3],\
dougal2@223
   526
                  matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3],\
dougal2@223
   527
                  matrix[2][0], matrix[2][1], matrix[2][2], matrix[2][3],\
dougal2@223
   528
                    matrix[3][0], matrix[3][1], matrix[3][2], matrix[3][3]))
dougal2@223
   529
            if motion:
dougal2@223
   530
                file.write("\tTransformBegin\n")
dougal2@223
   531
                file.write("\t\tIdentity\n")
dougal2@223
   532
                file.write("\t\tTransform [%s %s %s %s  %s %s %s %s  %s %s %s %s  %s %s %s %s]\n"\
dougal2@223
   533
                    %(motion[0][0], motion[0][1], motion[0][2], motion[0][3],\
dougal2@223
   534
                      motion[1][0], motion[1][1], motion[1][2], motion[1][3],\
dougal2@223
   535
                      motion[2][0], motion[2][1], motion[2][2], motion[2][3],\
dougal2@223
   536
                        motion[3][0], motion[3][1], motion[3][2], motion[3][3]))
dougal2@223
   537
                file.write("\t\tCoordinateSystem \"%s\"\n"%(obj.getName()+"_motion"))
dougal2@223
   538
                file.write("\tTransformEnd\n")
dougal2@223
   539
            if mesh_name in self.meshes:
dougal2@223
   540
                mesh.getFromObject(obj, 0, 1)
dougal2@223
   541
                mats = getMaterials(obj)
dougal2@223
   542
                print "  blender-mesh: %s (%d vertices, %d faces)"%(mesh_name, len(mesh.verts), len(mesh.faces))
dougal2@223
   543
                if (mesh_optimizing):
dougal2@223
   544
                    self.exportMeshOpt(file, mesh, mats, mesh_name)
dougal2@223
   545
                else:
dougal2@223
   546
                    self.exportMesh(file, mesh, mats, mesh_name)
dougal2@223
   547
            else:
dougal2@223
   548
                print "  instance %s"%(mesh_name)
dougal2@223
   549
                if motion:
dougal2@223
   550
                    file.write("\tMotionInstance \"%s\" 0.0 1.0 \"%s\"\n"%(mesh_name, obj.getName()+"_motion"))
dougal2@223
   551
                else:
dougal2@223
   552
                    file.write("\tObjectInstance \"%s\"\n"%mesh_name)
dougal2@223
   553
            file.write("AttributeEnd\n\n")
dougal2@223
   554
        mesh.verts = None
dougal2@223
   555
dougal2@223
   556
    #-------------------------------------------------
dougal2@223
   557
    # exportPortals(self, file)
dougal2@223
   558
    # exports portals objects to the file
dougal2@223
   559
    #-------------------------------------------------
dougal2@223
   560
    def exportPortals(self, file):
dougal2@223
   561
        scn = Scene.GetCurrent()
dougal2@223
   562
        mesh_optimizing = luxProp(scn, "mesh_optimizing", True).get()
dougal2@223
   563
        mesh = Mesh.New('')
dougal2@223
   564
        for [obj, matrix] in self.portals:
dougal2@223
   565
            print "portal: %s"%(obj.getName())
dougal2@223
   566
            file.write("\tTransform [%s %s %s %s  %s %s %s %s  %s %s %s %s  %s %s %s %s]\n"\
dougal2@223
   567
                %(matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3],\
dougal2@223
   568
                  matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3],\
dougal2@223
   569
                  matrix[2][0], matrix[2][1], matrix[2][2], matrix[2][3],\
dougal2@223
   570
                    matrix[3][0], matrix[3][1], matrix[3][2], matrix[3][3]))
dougal2@223
   571
            mesh_name = obj.getData(name_only=True)
dougal2@223
   572
            mesh.getFromObject(obj, 0, 1)
dougal2@223
   573
            mats = getMaterials(obj) # mats = obj.getData().getMaterials()
dougal2@223
   574
            if (mesh_optimizing):
dougal2@223
   575
                self.exportMeshOpt(file, mesh, mats, mesh_name, True)
dougal2@223
   576
            else:
dougal2@223
   577
                self.exportMesh(file, mesh, mats, mesh_name, True)
dougal2@223
   578
        mesh.verts = None
dougal2@223
   579
dougal2@223
   580
    #-------------------------------------------------
dougal2@223
   581
    # exportLights(self, file)
dougal2@223
   582
    # exports lights to the file
dougal2@223
   583
    #-------------------------------------------------
dougal2@223
   584
    def exportLights(self, file):
dougal2@223
   585
        for [obj, matrix] in self.lights:
dougal2@223
   586
            ltype = obj.getData(mesh=1).getType() # data
dougal2@223
   587
            if (ltype == Lamp.Types["Lamp"]) or (ltype == Lamp.Types["Spot"]) or (ltype == Lamp.Types["Area"]):
dougal2@223
   588
                print "light: %s"%(obj.getName())
dougal2@223
   589
                if ltype == Lamp.Types["Area"]:
dougal2@223
   590
                    (str, link) = luxLight("", "", obj, None, 0)
dougal2@223
   591
                    file.write(str)
dougal2@223
   592
                if ltype == Lamp.Types["Area"]: file.write("AttributeBegin # %s\n"%obj.getName())
dougal2@223
   593
                else: file.write("TransformBegin # %s\n"%obj.getName())
dougal2@223
   594
                file.write("\tTransform [%s %s %s %s  %s %s %s %s  %s %s %s %s  %s %s %s %s]\n"\
dougal2@223
   595
                    %(matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3],\
dougal2@223
   596
                      matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3],\
dougal2@223
   597
                      matrix[2][0], matrix[2][1], matrix[2][2], matrix[2][3],\
dougal2@223
   598
                        matrix[3][0], matrix[3][1], matrix[3][2], matrix[3][3]))
dougal2@223
   599
                col = obj.getData(mesh=1).col # data
dougal2@223
   600
                energy = obj.getData(mesh=1).energy # data
dougal2@223
   601
                if ltype == Lamp.Types["Lamp"]:
dougal2@223
   602
                    lightgroup = luxProp(obj, "light.lightgroup", "default")
doughammond@325
   603
                    if luxProp(Scene.GetCurrent(), "nolg", "false").get()!="true":
doughammond@325
   604
                        file.write("LightGroup \"%s\"\n"%lightgroup.get())
dougal2@223
   605
                    (str, link) = luxLamp("", "", obj, None, 0)
dougal2@223
   606
                    file.write(str+"LightSource \"point\""+link+"\n")
dougal2@223
   607
                if ltype == Lamp.Types["Spot"]:
dougal2@223
   608
                    (str, link) = luxSpot("", "", obj, None, 0)
dougal2@223
   609
                    file.write(str)
dougal2@223
   610
                    proj = luxProp(obj, "light.usetexproj", "false")
doughammond@325
   611
                    if luxProp(Scene.GetCurrent(), "nolg", "false").get()!="true":
doughammond@325
   612
                        lightgroup = luxProp(obj, "light.lightgroup", "default")
dougal2@223
   613
                    file.write("LightGroup \"%s\"\n"%lightgroup.get())
dougal2@223
   614
                    if(proj.get() == "true"):
dougal2@223
   615
                        file.write("Rotate 180 0 1 0\n")
dougal2@223
   616
                        file.write("LightSource \"projection\" \"float fov\" [%f]"%(obj.getData(mesh=1).spotSize))
dougal2@223
   617
                    else:
dougal2@223
   618
                        file.write("LightSource \"spot\" \"point from\" [0 0 0] \"point to\" [0 0 -1] \"float coneangle\" [%f] \"float conedeltaangle\" [%f]"\
dougal2@223
   619
                            %(obj.getData(mesh=1).spotSize*0.5, obj.getData(mesh=1).spotSize*0.5*obj.getData(mesh=1).spotBlend)) # data
dougal2@223
   620
                    file.write(link+"\n")
dougal2@223
   621
                if ltype == Lamp.Types["Area"]:
dougal2@223
   622
                    lightgroup = luxProp(obj, "light.lightgroup", "default")
doughammond@325
   623
                    if luxProp(Scene.GetCurrent(), "nolg", "false").get()!="true":
doughammond@325
   624
                        file.write("LightGroup \"%s\"\n"%lightgroup.get())
dougal2@223
   625
                    file.write("\tAreaLightSource \"area\"")
dougal2@223
   626
                    file.write(link)
dougal2@223
   627
#                    file.write(luxLight("", "", obj, None, 0))
dougal2@223
   628
                    file.write("\n")
dougal2@223
   629
                    areax = obj.getData(mesh=1).getAreaSizeX()
dougal2@223
   630
                    # lamps "getAreaShape()" not implemented yet - so we can't detect shape! Using square as default
dougal2@223
   631
                    # todo: ideasman42
dougal2@223
   632
                    if (True): areay = areax
dougal2@223
   633
                    else: areay = obj.getData(mesh=1).getAreaSizeY()
dougal2@223
   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})
dougal2@223
   635
                if ltype == Lamp.Types["Area"]: file.write("AttributeEnd # %s\n"%obj.getName())
dougal2@223
   636
                else: file.write("TransformEnd # %s\n"%obj.getName())
dougal2@223
   637
                file.write("\n")
dougal2@223
   638
dougal2@223
   639
dougal2@223
   640
    #-------------------------------------------------
dougal2@223
   641
    # exportVolumes(self, file)
dougal2@223
   642
    # exports volumes to the file
dougal2@223
   643
    #-------------------------------------------------
dougal2@223
   644
    def exportVolumes(self, file):
dougal2@223
   645
        for [obj, matrix] in self.volumes:
dougal2@223
   646
            print "volume: %s"%(obj.getName())
dougal2@223
   647
            file.write("# Volume: %s\n"%(obj.getName()))
dougal2@223
   648
dougal2@223
   649
            # trickery to obtain objectspace boundingbox AABB
dougal2@223
   650
            mat = obj.matrixWorld.copy().invert()
dougal2@223
   651
            bb = [vec * mat for vec in obj.getBoundBox()]
dougal2@223
   652
            minx = miny = minz = 100000000000000.0
dougal2@223
   653
            maxx = maxy = maxz = -100000000000000.0
dougal2@223
   654
            for vec in bb:
dougal2@223
   655
                if (vec[0] < minx): minx = vec[0]
dougal2@223
   656
                if (vec[1] < miny): miny = vec[1]
dougal2@223
   657
                if (vec[2] < minz): minz = vec[2]
dougal2@223
   658
                if (vec[0] > maxx): maxx = vec[0]
dougal2@223
   659
                if (vec[1] > maxy): maxy = vec[1]
dougal2@223
   660
                if (vec[2] > maxz): maxz = vec[2]
dougal2@223
   661
dougal2@223
   662
            file.write("Transform [%s %s %s %s  %s %s %s %s  %s %s %s %s  %s %s %s %s]\n"\
dougal2@223
   663
                %(matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3],\
dougal2@223
   664
                  matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3],\
dougal2@223
   665
                  matrix[2][0], matrix[2][1], matrix[2][2], matrix[2][3],\
dougal2@223
   666
                    matrix[3][0], matrix[3][1], matrix[3][2], matrix[3][3]))
dougal2@223
   667
dougal2@223
   668
            str_opt = (" \"point p0\" [%f %f %f] \"point p1\" [%f %f %f]"%(minx, miny, minz, maxx, maxy, maxz))
dougal2@223
   669
            mats = getMaterials(obj)
dougal2@223
   670
            if (len(mats)>0) and (mats[0]!=None) and (luxProp(mats[0], "type", "").get()=="boundvolume"):
dougal2@223
   671
                mat = mats[0]
dougal2@223
   672
                (str, link) = luxMaterialBlock("", "", "", mat, None, 0, str_opt)
dougal2@223
   673
                file.write("%s"%link)
dougal2@223
   674
                file.write("\n\n")
jromang@0
   675
jromang@0
   676
radiance29@155
   677
# Note - radiance - this is a work in progress
radiance29@155
   678
def luxFlashBlock(camObj):
dougal2@223
   679
    str = ""
dougal2@223
   680
    str += "CoordSysTransform \"camera\"\n"
dougal2@223
   681
dougal2@223
   682
    str += "Texture \"camflashtex\" \"color\" \"blackbody\" \"float temperature\" [5500.0]"
dougal2@223
   683
    str += "AreaLightSource \"area\" \"texture L\" [\"camflashtex\"] \"float power\" [100.000000] \"float efficacy\" [17.000000] \"float gain\" [1.000000]\n"
dougal2@223
   684
dougal2@223
   685
    up = 10.0
dougal2@223
   686
dougal2@223
   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"
dougal2@223
   688
dougal2@223
   689
    return str
radiance29@155
   690
radiance29@72
   691
jromang@0
   692
######################################################
jromang@0
   693
# EXPORT
jromang@0
   694
######################################################
jromang@0
   695
jromang@0
   696
def save_lux(filename, unindexedname):
dougal2@223
   697
    
dougal2@223
   698
    export_total_steps = 12.0
dougal2@223
   699
    
zuegs@255
   700
    global meshlist, matnames, lxs_filename, geom_filename, geom_pfilename, mat_filename, mat_pfilename, vol_filename, vol_pfilename, LuxIsGUI
dougal2@223
   701
dougal2@223
   702
    print("Lux Render Export started...\n")
dougal2@223
   703
    time1 = Blender.sys.time()
dougal2@223
   704
    scn = Scene.GetCurrent()
dougal2@223
   705
dougal2@223
   706
    filepath = os.path.dirname(filename)
dougal2@223
   707
    filebase = os.path.splitext(os.path.basename(filename))[0]
dougal2@223
   708
zuegs@255
   709
    lxs_filename = filename
zuegs@255
   710
dougal2@223
   711
    geom_filename = os.path.join(filepath, filebase + "-geom.lxo")
dougal2@223
   712
    geom_pfilename = filebase + "-geom.lxo"
dougal2@223
   713
dougal2@223
   714
    mat_filename = os.path.join(filepath, filebase + "-mat.lxm")
dougal2@223
   715
    mat_pfilename = filebase + "-mat.lxm"
dougal2@223
   716
    
dougal2@223
   717
    vol_filename = os.path.join(filepath, filebase + "-vol.lxv")
dougal2@223
   718
    vol_pfilename = filebase + "-vol.lxv"
dougal2@223
   719
dougal2@223
   720
    ### Zuegs: initialization for export class
dougal2@223
   721
    export = luxExport(Blender.Scene.GetCurrent())
dougal2@223
   722
dougal2@223
   723
    # check if a light is present
dougal2@223
   724
    envtype = luxProp(scn, "env.type", "infinite").get()
dougal2@223
   725
    if envtype == "sunsky":
dougal2@223
   726
        sun = None
dougal2@223
   727
        for obj in scn.objects:
dougal2@223
   728
            if (obj.getType() == "Lamp") and ((obj.Layers & scn.Layers) > 0):
dougal2@223
   729
                if obj.getData(mesh=1).getType() == 1: # sun object # data
dougal2@223
   730
                    sun = obj
dougal2@223
   731
    if not(export.analyseScene()) and not(envtype == "infinite") and not((envtype == "sunsky") and (sun != None)):
dougal2@223
   732
        print("ERROR: No light source found")
dougal2@223
   733
        Draw.PupMenu("ERROR: No light source found%t|OK%x1")
dougal2@223
   734
        return False
dougal2@223
   735
dougal2@223
   736
    if LuxIsGUI: DrawProgressBar(0.0/export_total_steps,'Setting up Scene file')
dougal2@223
   737
    if luxProp(scn, "lxs", "true").get()=="true":
dougal2@223
   738
        ##### Determine/open files
dougal2@223
   739
        print("Exporting scene to '" + filename + "'...\n")
dougal2@223
   740
        file = open(filename, 'w')
dougal2@223
   741
dougal2@223
   742
        ##### Write Header ######
jensverwiebe@338
   743
        file.write("# Lux Render v0.6RC5 Scene File\n")
dougal2@223
   744
        file.write("# Exported by LuxBlend Blender Exporter\n")
dougal2@223
   745
        file.write("\n")
dougal2@223
   746
    
dougal2@223
   747
        ##### Write camera ######
dougal2@223
   748
        camObj = scn.getCurrentCamera()
dougal2@223
   749
dougal2@223
   750
        if LuxIsGUI: DrawProgressBar(1.0/export_total_steps,'Exporting Camera')
dougal2@223
   751
        if camObj:
dougal2@223
   752
            print "processing Camera..."
dougal2@223
   753
            cam = camObj.data
dougal2@223
   754
            cammblur = luxProp(cam, "cammblur", "true")
dougal2@223
   755
            usemblur = luxProp(cam, "usemblur", "false")
dougal2@223
   756
dougal2@223
   757
            matrix = camObj.getMatrix()
dougal2@223
   758
dougal2@223
   759
            motion = None
dougal2@223
   760
            if(cammblur.get() == "true" and usemblur.get() == "true"):
dougal2@223
   761
                # motion blur
dougal2@223
   762
                frame = Blender.Get('curframe')
dougal2@223
   763
                Blender.Set('curframe', frame+1)
dougal2@223
   764
                m1 = 1.0*matrix # multiply by 1.0 to get a copy of original matrix (will be frame-independant) 
dougal2@223
   765
                Blender.Set('curframe', frame)
dougal2@223
   766
                if m1 != matrix:
dougal2@223
   767
                    # Motion detected, write endtransform
dougal2@223
   768
                    print "  motion blur"
dougal2@223
   769
                    motion = m1
dougal2@223
   770
                    pos = m1[3]
dougal2@223
   771
                    forwards = -m1[2]
dougal2@223
   772
                    target = pos + forwards
dougal2@223
   773
                    up = m1[1]
dougal2@223
   774
                    file.write("TransformBegin\n")
dougal2@223
   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] ))
dougal2@223
   776
                    file.write("   CoordinateSystem \"CameraEndTransform\"\n")
dougal2@223
   777
                    file.write("TransformEnd\n\n")
dougal2@223
   778
dougal2@223
   779
            # Write original lookat transform
dougal2@223
   780
            pos = matrix[3]
dougal2@223
   781
            forwards = -matrix[2]
dougal2@223
   782
            target = pos + forwards
dougal2@223
   783
            up = matrix[1]
dougal2@223
   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] ))
dougal2@223
   785
            file.write(luxCamera(camObj.data, scn.getRenderingContext()))
dougal2@223
   786
            if motion:
dougal2@223
   787
                file.write("\n   \"string endtransform\" [\"CameraEndTransform\"]")
dougal2@223
   788
            file.write("\n")
dougal2@223
   789
        file.write("\n")
dougal2@223
   790
    
dougal2@223
   791
        if LuxIsGUI: DrawProgressBar(2.0/export_total_steps,'Exporting Film Settings')
dougal2@223
   792
        ##### Write film ######
dougal2@223
   793
        file.write(luxFilm(scn))
dougal2@223
   794
        file.write("\n")
dougal2@223
   795
dougal2@223
   796
        if LuxIsGUI: DrawProgressBar(3.0/export_total_steps,'Exporting Pixel Filter')
dougal2@223
   797
        ##### Write Pixel Filter ######
dougal2@223
   798
        file.write(luxPixelFilter(scn))
dougal2@223
   799
        file.write("\n")
dougal2@223
   800
    
dougal2@223
   801
        if LuxIsGUI: DrawProgressBar(4.0/export_total_steps,'Exporting Sampler')
dougal2@223
   802
        ##### Write Sampler ######
dougal2@223
   803
        file.write(luxSampler(scn))
dougal2@223
   804
        file.write("\n")
dougal2@223
   805
    
dougal2@223
   806
        if LuxIsGUI: DrawProgressBar(5.0/export_total_steps,'Exporting Surface Integrator')
dougal2@223
   807
        ##### Write Surface Integrator ######
dougal2@223
   808
        file.write(luxSurfaceIntegrator(scn))
dougal2@223
   809
        file.write("\n")
dougal2@223
   810
        
dougal2@223
   811
        if LuxIsGUI: DrawProgressBar(6.0/export_total_steps,'Exporting Volume Integrator')
dougal2@223
   812
        ##### Write Volume Integrator ######
dougal2@223
   813
        file.write(luxVolumeIntegrator(scn))
dougal2@223
   814
        file.write("\n")
dougal2@223
   815
        
dougal2@223
   816
        if LuxIsGUI: DrawProgressBar(7.0/export_total_steps,'Exporting Accelerator')
dougal2@223
   817
        ##### Write Acceleration ######
dougal2@223
   818
        file.write(luxAccelerator(scn))
dougal2@223
   819
        file.write("\n")    
dougal2@223
   820
    
dougal2@223
   821
        ########## BEGIN World
dougal2@223
   822
        file.write("\n")
dougal2@223
   823
        file.write("WorldBegin\n")
dougal2@223
   824
        file.write("\n")
dougal2@223
   825
dougal2@223
   826
        ########## World scale
dougal2@234
   827
        #scale = luxProp(scn, "global.scale", 1.0).get()
dougal2@234
   828
        #if scale != 1.0:
dougal2@234
   829
        #    # TODO: not working yet !!!
dougal2@234
   830
        #    # TODO: propabily scale needs to be applyed on camera coords too 
dougal2@234
   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))
dougal2@234
   832
        #    file.write("\n")
dougal2@223
   833
        
dougal2@223
   834
        if LuxIsGUI: DrawProgressBar(8.0/export_total_steps,'Exporting Environment')
dougal2@223
   835
        ##### Write World Background, Sunsky or Env map ######
dougal2@223
   836
        env = luxEnvironment(scn)
dougal2@223
   837
        if env != "":
dougal2@223
   838
            file.write("AttributeBegin\n")
dougal2@223
   839
            file.write(env)
dougal2@223
   840
            export.exportPortals(file)
dougal2@223
   841
            file.write("AttributeEnd\n")
dougal2@223
   842
            file.write("\n")    
dougal2@223
   843
dougal2@223
   844
    # Note - radiance - this is a work in progress
dougal2@223
   845
#        flash = luxFlashBlock(camObj)
dougal2@223
   846
#        if flash != "":
dougal2@223
   847
#            file.write("# Camera flash lamp\n")
dougal2@223
   848
#            file.write("AttributeBegin\n")
dougal2@223
   849
#            #file.write("CoordSysTransform \"camera\"\n")
dougal2@223
   850
#            file.write(flash)
dougal2@223
   851
#            file.write("AttributeEnd\n\n")
dougal2@223
   852
dougal2@223
   853
        #### Write material & geometry file includes in scene file
dougal2@223
   854
        file.write("Include \"%s\"\n\n" %(mat_pfilename))
dougal2@223
   855
        file.write("Include \"%s\"\n\n" %(geom_pfilename))
dougal2@223
   856
        file.write("Include \"%s\"\n\n" %(vol_pfilename))
dougal2@223
   857
        
dougal2@223
   858
        #### Write End Tag
dougal2@223
   859
        file.write("WorldEnd\n\n")
dougal2@223
   860
        file.close()
dougal2@223
   861
        
dougal2@223
   862
    if luxProp(scn, "lxm", "true").get()=="true":
dougal2@223
   863
        if LuxIsGUI: DrawProgressBar(9.0/export_total_steps,'Exporting Materials')
dougal2@223
   864
        ##### Write Material file #####
dougal2@223
   865
        print("Exporting materials to '" + mat_filename + "'...\n")
dougal2@223
   866
        mat_file = open(mat_filename, 'w')
dougal2@223
   867
        mat_file.write("")
dougal2@223
   868
        export.exportMaterials(mat_file)
dougal2@223
   869
        mat_file.write("")
dougal2@223
   870
        mat_file.close()
dougal2@223
   871
    
dougal2@223
   872
    if luxProp(scn, "lxo", "true").get()=="true":
dougal2@223
   873
        if LuxIsGUI: DrawProgressBar(10.0/export_total_steps,'Exporting Geometry')
dougal2@223
   874
        ##### Write Geometry file #####
dougal2@223
   875
        print("Exporting geometry to '" + geom_filename + "'...\n")
dougal2@223
   876
        geom_file = open(geom_filename, 'w')
dougal2@223
   877
        meshlist = []
dougal2@223
   878
        geom_file.write("")
dougal2@223
   879
        export.exportLights(geom_file)
dougal2@223
   880
        export.exportMeshes(geom_file)
dougal2@223
   881
        export.exportObjects(geom_file)
dougal2@223
   882
        geom_file.write("")
dougal2@223
   883
        geom_file.close()
dougal2@223
   884
dougal2@223
   885
    if luxProp(scn, "lxv", "true").get()=="true":
dougal2@223
   886
        if LuxIsGUI: DrawProgressBar(11.0/export_total_steps,'Exporting Volumes')
dougal2@223
   887
        ##### Write Volume file #####
dougal2@223
   888
        print("Exporting volumes to '" + vol_filename + "'...\n")
dougal2@223
   889
        vol_file = open(vol_filename, 'w')
dougal2@223
   890
        meshlist = []
dougal2@223
   891
        vol_file.write("")
dougal2@223
   892
        export.exportVolumes(vol_file)
dougal2@223
   893
        vol_file.write("")
dougal2@223
   894
        vol_file.close()
dougal2@223
   895
dougal2@223
   896
dougal2@223
   897
    if LuxIsGUI: DrawProgressBar(12.0/export_total_steps,'Export Finished')
dougal2@223
   898
    print("Finished.\n")
dougal2@223
   899
    del export
dougal2@223
   900
dougal2@223
   901
    time2 = Blender.sys.time()
dougal2@223
   902
    print("Processing time: %f\n" %(time2-time1))
dougal2@223
   903
    return True
jromang@0
   904
dougal2@257
   905
########################################################################
dougal2@257
   906
####  Construct server string argument
dougal2@257
   907
########################################################################
dougal2@257
   908
dougal2@257
   909
def networkstring(scn):
dougal2@257
   910
    servers_string = ""
dougal2@257
   911
    if  (luxProp(scn,"network","false").get() == "true"):
dougal2@257
   912
        if (luxProp(scn,"network_use_file","false").get() == "true"):
dougal2@257
   913
            print "read network servers from file: "+ luxProp(scn,"network_file_path","false").get()
dougal2@257
   914
            f = open(luxProp(scn,"network_file_path","false").get())
dougal2@257
   915
            for s in f:
dougal2@257
   916
                s = s.strip("\n")
dougal2@257
   917
                print "add server :" + s
dougal2@257
   918
                servers_string=servers_string+" -u "+ s
dougal2@257
   919
            f.close
dougal2@257
   920
        else : 
dougal2@257
   921
             if  luxProp(scn,"network_servers","").get():
dougal2@257
   922
                 for server in luxProp(scn,"network_servers","").get().split(","):
dougal2@257
   923
                    servers_string=servers_string+" -u "+ server
dougal2@257
   924
    return servers_string
jromang@0
   925
jromang@0
   926
jromang@0
   927
#########################################################################
dougal2@223
   928
###     LAUNCH LuxRender AND RENDER CURRENT SCENE
jromang@0
   929
#########################################################################
jromang@0
   930
jromang@0
   931
def launchLux(filename):
dougal2@223
   932
    ostype = osys.platform
dougal2@223
   933
    #get blenders 'bpydata' directory
dougal2@223
   934
    datadir=Blender.Get("datadir")
dougal2@223
   935
    
dougal2@223
   936
    scn = Scene.GetCurrent()
dougal2@223
   937
    ic = luxProp(scn, "lux", "").get()
dougal2@223
   938
    ic = Blender.sys.dirname(ic) + os.sep + "luxrender"
dougal2@257
   939
dougal2@257
   940
    servers_string = networkstring(scn)
dougal2@257
   941
    update_int=luxProp(scn,"newtork_interval",180).get()
dougal2@257
   942
dougal2@223
   943
    if ostype == "win32": ic = ic + ".exe"
dougal2@223
   944
    if ostype == "darwin": ic = ic + ".app/Contents/MacOS/luxrender"
dougal2@223
   945
    checkluxpath = luxProp(scn, "checkluxpath", True).get()
dougal2@223
   946
    if checkluxpath:
dougal2@223
   947
        if sys.exists(ic) != 1:
dougal2@223
   948
            Draw.PupMenu("Error: Lux renderer not found. Please set path on System page.%t|OK")
dougal2@223
   949
            return        
dougal2@223
   950
    autothreads = luxProp(scn, "autothreads", "true").get()
dougal2@223
   951
    threads = luxProp(scn, "threads", 1).get()
dougal2@223
   952
    luxnice = luxProp(scn, "luxnice", 0).get()
doug@307
   953
    noopengl = luxProp(scn, "noopengl", "false").get()
doug@307
   954
    if noopengl == "true":
doug@312
   955
        noopengl_str = " --noopengl"
doug@313
   956
    else:
doug@312
   957
        noopengl_str = ""
doug@307
   958
    
dougal2@223
   959
    if ostype == "win32":
dougal2@223
   960
        prio = ""
dougal2@223
   961
        if luxnice > 15: prio = "/low"
dougal2@223
   962
        elif luxnice > 5: prio = "/belownormal"
dougal2@223
   963
        elif luxnice > -5: prio = "/normal"
dougal2@223
   964
        elif luxnice > -15: prio = "/abovenormal"
dougal2@223
   965
        else: prio = "/high"
dougal2@223
   966
        if(autothreads=="true"):
doug@312
   967
            cmd = "start /b %s \"\" \"%s\" %s %s -i %d \"%s\" "%(prio, ic, noopengl_str, servers_string ,update_int, filename)        
dougal2@223
   968
        else:
doug@312
   969
            cmd = "start /b %s \"\" \"%s\" %s %s -i %d \"%s\" --threads=%d"%(prio, ic, noopengl_str, servers_string ,update_int ,filename, threads)        
dougal2@223
   970
dougal2@223
   971
    if ostype == "linux2" or ostype == "darwin":
dougal2@223
   972
        if(autothreads=="true"):
doug@312
   973
            cmd = "(nice -n %d \"%s\" %s %s -i %d \"%s\")&"%(luxnice, ic, noopengl_str, servers_string ,update_int, filename)
dougal2@257
   974
dougal2@223
   975
        else:
doug@312
   976
            cmd = "(nice -n %d \"%s\" --threads=%d %s %s -i %d \"%s\")&"%(luxnice, ic, threads, noopengl_str, servers_string ,update_int, filename)
dougal2@223
   977
dougal2@223
   978
    # call external shell script to start Lux    
dougal2@223
   979
    print("Running Luxrender:\n"+cmd)
dougal2@223
   980
    os.system(cmd)
jromang@0
   981
radiance29@115
   982
def launchLuxPiped():
dougal2@223
   983
    ostype = osys.platform
dougal2@223
   984
    #get blenders 'bpydata' directory
dougal2@223
   985
    datadir=Blender.Get("datadir")
dougal2@223
   986
    
dougal2@223
   987
    scn = Scene.GetCurrent()
dougal2@257
   988
dougal2@257
   989
    servers_string = networkstring(scn)
dougal2@257
   990
    update_int=luxProp(scn,"newtork_interval",180).get()
dougal2@257
   991
dougal2@223
   992
    ic = luxProp(scn, "lux", "").get()
dougal2@223
   993
    ic = Blender.sys.dirname(ic) + os.sep + "luxrender"
dougal2@223
   994
    if ostype == "win32": ic = ic + ".exe"
dougal2@223
   995
    if ostype == "darwin": ic = ic + ".app/Contents/MacOS/luxrender"
dougal2@223
   996
    checkluxpath = luxProp(scn, "checkluxpath", True).get()
dougal2@223
   997
    if checkluxpath:
dougal2@223
   998
        if sys.exists(ic) != 1:
dougal2@223
   999
            Draw.PupMenu("Error: Lux renderer not found. Please set path on System page.%t|OK")
dougal2@223
  1000
            return        
dougal2@223
  1001
    autothreads = luxProp(scn, "autothreads", "true").get()
dougal2@223
  1002
    threads = luxProp(scn, "threads", 1).get()
dougal2@223
  1003
dougal2@223
  1004
    if ostype == "win32":
dougal2@223
  1005
        if(autothreads=="true"):
dougal2@257
  1006
            cmd = "\"%s\" - %s -i %d "%(ic,servers_string,update_int)        
dougal2@223
  1007
        else:
dougal2@257
  1008
            cmd = "\"%s\" - %s -i %d --threads=%d"%(ic, threads)        
dougal2@223
  1009
dougal2@223
  1010
    if ostype == "linux2" or ostype == "darwin":
dougal2@223
  1011
        if(autothreads=="true"):
dougal2@257
  1012
            cmd = "(\"%s -u %s -i %d\" \"%s\")&"%(ic,servers_string,update_int, filename)
dougal2@223
  1013
        else:
dougal2@257
  1014
            cmd = "(\"%s\" --threads=%d -u %s -i %d \"%s\")&"%(ic, threads,servers_string,update_int, filename)
dougal2@223
  1015
dougal2@223
  1016
    # call external shell script to start Lux    
dougal2@223
  1017
    print("Running Luxrender:\n"+cmd)
dougal2@223
  1018
dougal2@223
  1019
    import subprocess, os
dougal2@223
  1020
dougal2@223
  1021
    PIPE = subprocess.PIPE
dougal2@223
  1022
    p = subprocess.Popen(cmd, stdin=PIPE)
dougal2@223
  1023
    
dougal2@223
  1024
    return p.stdin
radiance29@115
  1025
radiance29@101
  1026
def launchLuxWait(filename):
dougal2@223
  1027
    ostype = osys.platform
dougal2@223
  1028
    #get blenders 'bpydata' directory
dougal2@223
  1029
    datadir=Blender.Get("datadir")
radiance29@245
  1030
dougal2@223
  1031
    scn = Scene.GetCurrent()
radiance29@245
  1032
    luxbatchconsolemode = luxProp(scn, "luxbatchc", "false")
radiance29@245
  1033
dougal2@257
  1034
    servers_string = networkstring(scn)
dougal2@257
  1035
    update_int=luxProp(scn,"newtork_interval",180).get()
dougal2@257
  1036
dougal2@223
  1037
    ic = luxProp(scn, "lux", "").get()
radiance29@245
  1038
    if luxbatchconsolemode.get() == "false":
dougal2@258
  1039
        ic = Blender.sys.dirname(ic) + os.sep + "luxconsole"
dougal2@223
  1040
    if ostype == "win32": ic = ic + ".exe"
radiance29@248
  1041
    # radiance - comment out app install for luxconsole on OSX for jensverwiebe
radiance29@248
  1042
    #if ostype == "darwin": ic = ic + ".app/Contents/MacOS/luxconsole"
dougal2@223
  1043
    checkluxpath = luxProp(scn, "checkluxpath", True).get()
dougal2@223
  1044
    if checkluxpath:
dougal2@223
  1045
        if sys.exists(ic) != 1:
dougal2@223
  1046
            Draw.PupMenu("Error: Lux renderer not found. Please set path on System page.%t|OK")
dougal2@223
  1047
            return        
dougal2@223
  1048
    autothreads = luxProp(scn, "autothreads", "true").get()
dougal2@223
  1049
    threads = luxProp(scn, "threads", 1).get()
dougal2@223
  1050
dougal2@223
  1051
    if ostype == "win32":
dougal2@223
  1052
        if(autothreads=="true"):
dougal2@257
  1053
            cmd = "start /b /WAIT \"\" \"%s\" %s -i %d -f \"%s\" "%(ic,servers_string,update_int, filename)        
dougal2@223
  1054
        else:
dougal2@257
  1055
            cmd = "start /b /WAIT \"\" \"%s\"  %s -i %d -f \"%s\" --threads=%d"%(ic,servers_string,update_int, filename, threads)        
dougal2@223
  1056
        # call external shell script to start Lux    
dougal2@223
  1057
        #print("Running Luxrender:\n"+cmd)
dougal2@223
  1058
        #os.spawnv(os.P_WAIT, cmd, 0)
dougal2@223
  1059
        os.system(cmd)
dougal2@223
  1060
dougal2@223
  1061
    if ostype == "linux2" or ostype == "darwin":
dougal2@223
  1062
        if(autothreads=="true"):
dougal2@257
  1063
            cmd = "\"%s\" %s -i %d -f \"%s\""%(ic,servers_string,update_int, filename)
dougal2@223
  1064
        else:
dougal2@257
  1065
            cmd = "\"%s\" %s -i %d -f --threads=%d \"%s\""%(ic,servers_string,update_int,  threads, filename)
dougal2@223
  1066
        subprocess.call(cmd,shell=True)
dougal2@223
  1067
dougal2@223
  1068
#### SAVE ANIMATION ####    
jromang@0
  1069
def save_anim(filename):
dougal2@223
  1070
    global MatSaved
dougal2@223
  1071
    
dougal2@223
  1072
    MatSaved = 0
dougal2@223
  1073
    startF = Blender.Get('staframe')
dougal2@223
  1074
    endF = Blender.Get('endframe')
dougal2@223
  1075
    scn = Scene.GetCurrent()
dougal2@223
  1076
dougal2@223
  1077
    Run = luxProp(scn, "run", "true").get()
dougal2@223
  1078
dougal2@223
  1079
    print("\n\nRendering animation (frame %i to %i)\n\n"%(startF, endF))
dougal2@223
  1080
dougal2@223
  1081
    for i in range (startF, endF+1):
dougal2@223
  1082
        Blender.Set('curframe', i)
dougal2@223
  1083
        print("Rendering frame %i"%(i))
dougal2@223
  1084
        Blender.Redraw()
dougal2@223
  1085
        frameindex = ("-%05d" % (i)) + ".lxs"
dougal2@223
  1086
        indexedname = sys.makename(filename, frameindex)
dougal2@223
  1087
        unindexedname = filename
dougal2@223
  1088
        luxProp(scn, "filename", Blender.Get("filename")).set(sys.makename(filename, "-%05d" %  (Blender.Get('curframe'))))
dougal2@223
  1089
dougal2@223
  1090
        if Run == "true":
dougal2@223
  1091
            if save_lux(filename, unindexedname):
dougal2@223
  1092
                launchLuxWait(filename)
dougal2@223
  1093
        else:
dougal2@223
  1094
            save_lux(indexedname, unindexedname)
dougal2@223
  1095
dougal2@223
  1096
        MatSaved = 1
dougal2@223
  1097
dougal2@223
  1098
    print("\n\nFinished Rendering animation\n")
radiance29@101
  1099
jromang@0
  1100
#### SAVE STILL (hackish...) ####
jromang@0
  1101
def save_still(filename):
dougal2@223
  1102
    global MatSaved
dougal2@223
  1103
    scn = Scene.GetCurrent()
dougal2@223
  1104
    luxProp(scn, "filename", Blender.Get("filename")).set(sys.makename(filename, ""))
dougal2@223
  1105
    MatSaved = 0
dougal2@223
  1106
    unindexedname = filename
dougal2@223
  1107
    if save_lux(filename, unindexedname):
dougal2@223
  1108
        if runRenderAfterExport: #(run == None and luxProp(scn, "run", "true").get() == "true") or run:
dougal2@223
  1109
            launchLux(filename)
jromang@0
  1110
jromang@0
  1111
zuegs@45
  1112
######################################################
zuegs@45
  1113
# Icons
zuegs@45
  1114
######################################################
zuegs@45
  1115
zuegs@48
  1116
def base64value(char):
dougal2@223
  1117
    if 64 < ord(char) < 91: return ord(char)-65
dougal2@223
  1118
    if 96 < ord(char) < 123: return ord(char)-97+26
dougal2@223
  1119
    if 47 < ord(char) < 58: return ord(char)-48+52
dougal2@223
  1120
    if char == '+': return 62
dougal2@223
  1121
    return 63
zuegs@48
  1122
zuegs@45
  1123
def decodeIconStr(s):
dougal2@223
  1124
    buf = BGL.Buffer(BGL.GL_BYTE, [16,16,4])
dougal2@223
  1125
    offset = 0
dougal2@223
  1126
    for y in range(16):
dougal2@223
  1127
        for x in range(16):
dougal2@223
  1128
            for c in range(4):
dougal2@223
  1129
                buf[y][x][c] = int(base64value(s[offset])*4.048)
dougal2@223
  1130
                offset += 1
dougal2@223
  1131
    return buf
zuegs@45
  1132
radiance29@115
  1133
def decodeLogoStr(s):
dougal2@223
  1134
    buf = BGL.Buffer(BGL.GL_BYTE, [18,118,4])
dougal2@223
  1135
    offset = 0
dougal2@223
  1136
    for y in range(18):
dougal2@223
  1137
        for x in range(118):
dougal2@223
  1138
            for c in range(4):
dougal2@223
  1139
                buf[y][x][c] = int(base64value(s[offset])*4.048)
dougal2@223
  1140
                offset += 1
dougal2@223
  1141
    return buf
radiance29@115
  1142
radiance29@245
  1143
def decodeArrowStr(s):
radiance29@245
  1144
    buf = BGL.Buffer(BGL.GL_BYTE, [22,22,4])
radiance29@245
  1145
    offset = 0
radiance29@245
  1146
    for y in range(22):
radiance29@245
  1147
        for x in range(22):
radiance29@245
  1148
            for c in range(4):
radiance29@245
  1149
                buf[y][x][c] = int(base64value(s[offset])*4.048)
radiance29@245
  1150
                offset += 1
radiance29@245
  1151
    return buf
radiance29@245
  1152
radiance29@131
  1153
def decodeBarStr(s):
dougal2@223
  1154
    buf = BGL.Buffer(BGL.GL_BYTE, [17,138,4])
dougal2@223
  1155
    offset = 0
dougal2@223
  1156
    for y in range(17):
dougal2@223
  1157
        for x in range(138):
dougal2@223
  1158
            for c in range(4):
dougal2@223
  1159
                buf[y][x][c] = int(base64value(s[offset])*4.048)
dougal2@223
  1160
                offset += 1
dougal2@223
  1161
    return buf
radiance29@131
  1162
radiance29@245
  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")
radiance29@245
  1164
radiance29@245
  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")
radiance29@245
  1166
radiance29@115
  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")
radiance29@115
  1168
radiance29@115
  1169
zuegs@48
  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")
zuegs@48
  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")
zuegs@48
  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")
zuegs@48
  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")
zuegs@48
  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")
zuegs@48
  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")
zuegs@48
  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")
zuegs@48
  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")
zuegs@48
  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")
zuegs@48
  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")
zuegs@48
  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")
zuegs@48
  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")
zuegs@48
  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")
zuegs@45
  1183
radiance29@155
  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")
radiance29@155
  1185
radiance29@155
  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")
zuegs@45
  1187
radiance29@115
  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")
radiance29@115
  1189
radiance29@115
  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")
radiance29@115
  1191
radiance29@115
  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")
radiance29@115
  1193
radiance29@115
  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")
radiance29@115
  1195
radiance29@115
  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")
radiance29@115
  1197
radiance29@115
  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")
radiance29@115
  1199
radiance29@115
  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")
radiance29@115
  1201
radiance29@115
  1202
radiance29@131
  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")
radiance29@131
  1204
radiance29@150
  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//")
radiance29@131
  1206
radiance29@131
  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") 
radiance29@131
  1208
zuegs@45
  1209
def drawIcon(icon, x, y):
dougal2@223
  1210
    BGL.glEnable(BGL.GL_BLEND)
dougal2@223
  1211
    BGL.glBlendFunc(BGL.GL_SRC_ALPHA, BGL.GL_ONE_MINUS_SRC_ALPHA) 
dougal2@223
  1212
    BGL.glRasterPos2f(int(x)+0.5, int(y)+0.5)
dougal2@223
  1213
    BGL.glDrawPixels(16, 16, BGL.GL_RGBA, BGL.GL_UNSIGNED_BYTE, icon)
dougal2@223
  1214
    BGL.glDisable(BGL.GL_BLEND)
zuegs@45
  1215
radiance29@245
  1216
def drawArrow(icon, x, y):
radiance29@245
  1217
    BGL.glEnable(BGL.GL_BLEND)
radiance29@245
  1218
    BGL.glBlendFunc(BGL.GL_SRC_ALPHA, BGL.GL_ONE_MINUS_SRC_ALPHA) 
radiance29@245
  1219
    BGL.glRasterPos2f(int(x)+0.5, int(y)+0.5)
radiance29@245
  1220
    BGL.glDrawPixels(22, 22, BGL.GL_RGBA, BGL.GL_UNSIGNED_BYTE, icon)
radiance29@245
  1221
    BGL.glDisable(BGL.GL_BLEND)
radiance29@245
  1222
radiance29@115
  1223
def drawLogo(icon, x, y):
dougal2@223
  1224
    BGL.glEnable(BGL.GL_BLEND)
dougal2@223
  1225
    BGL.glBlendFunc(BGL.GL_SRC_ALPHA, BGL.GL_ONE_MINUS_SRC_ALPHA) 
dougal2@223
  1226
    BGL.glRasterPos2f(int(x)+0.5, int(y)+0.5)
dougal2@223
  1227
    BGL.glDrawPixels(118, 18, BGL.GL_RGBA, BGL.GL_UNSIGNED_BYTE, icon)
dougal2@223
  1228
    BGL.glDisable(BGL.GL_BLEND)
radiance29@115
  1229
radiance29@131
  1230
def drawBar(icon, x, y):
dougal2@223
  1231
    BGL.glEnable(BGL.GL_BLEND)
dougal2@223
  1232
    BGL.glBlendFunc(BGL.GL_SRC_ALPHA, BGL.GL_ONE_MINUS_SRC_ALPHA) 
dougal2@223
  1233
    BGL.glRasterPos2f(int(x)+0.5, int(y)+0.5)
dougal2@223
  1234
    BGL.glDrawPixels(138, 17, BGL.GL_RGBA, BGL.GL_UNSIGNED_BYTE, icon)
dougal2@223
  1235
    BGL.glDisable(BGL.GL_BLEND)
radiance29@131
  1236
zuegs@21
  1237
zuegs@143
  1238
zuegs@143
  1239
#-------------------------------------------------
zuegs@143
  1240
# luxImage()
zuegs@143
  1241
# helper class to handle images and icons for the GUI
zuegs@143
  1242
#-------------------------------------------------
zuegs@143
  1243
zuegs@143
  1244
class luxImage:
dougal2@223
  1245
    def resize(self, width, height):
dougal2@223
  1246
        self.width = width
dougal2@223
  1247
        self.height = height
dougal2@223
  1248
        self.buf = BGL.Buffer(BGL.GL_BYTE, [width,height,4]) # GL buffer
dougal2@223
  1249
    def __init__(self, width=0, height=0):
dougal2@223
  1250
        self.resize(width, height)
dougal2@223
  1251
    def draw(self, x, y):
dougal2@223
  1252
        BGL.glEnable(BGL.GL_BLEND)
dougal2@223
  1253
        BGL.glBlendFunc(BGL.GL_SRC_ALPHA, BGL.GL_ONE_MINUS_SRC_ALPHA) 
dougal2@223
  1254
        BGL.glRasterPos2f(int(x)+0.5, int(y)+0.5)
dougal2@223
  1255
        BGL.glDrawPixels(self.width, self.height, BGL.GL_RGBA, BGL.GL_UNSIGNED_BYTE, self.buf)
dougal2@223
  1256
        BGL.glDisable(BGL.GL_BLEND)        
dougal2@223
  1257
    def decodeStr(self, width, height, s):
dougal2@223
  1258
        self.resize(width, height)
dougal2@223
  1259
        offset = 0
dougal2@223
  1260
        for y in range(self.height):
dougal2@223
  1261
            for x in range(self.width):
dougal2@223
  1262
                for c in range(4):
dougal2@223
  1263
                    self.buf[y][x][c] = int(base64value(s[offset])*4.048)
dougal2@223
  1264
                    offset += 1
dougal2@223
  1265
dougal2@223
  1266
    def decodeLuxConsole(self, width, height, data):
dougal2@223
  1267
        self.resize(width, height)
dougal2@223
  1268
        offset = 0
dougal2@223
  1269
        for y in range(self.height-1,-1,-1):
dougal2@223
  1270
            for x in range(self.width):
dougal2@223
  1271
                for c in range(3):
dougal2@223
  1272
                    self.buf[y][x][c] = ord(data[offset])
dougal2@223
  1273
                    offset += 1
dougal2@223
  1274
                self.buf[y][x][3] = 255
zuegs@143
  1275
zuegs@143
  1276
zuegs@143
  1277
previewCache = {}  # dictionary that will hold all preview images
zuegs@143
  1278
zuegs@143
  1279
jromang@0
  1280
######################################################
zuegs@21
  1281
# New GUI by Zuegs
jromang@0
  1282
######################################################
jromang@0
  1283
zuegs@11
  1284
from types import *
zuegs@11
  1285
zuegs@22
  1286
evtLuxGui = 99
zuegs@22
  1287
evtSavePreset = 98
zuegs@22
  1288
evtDeletePreset = 97
zuegs@22
  1289
evtSaveMaterial = 96
zuegs@22
  1290
evtLoadMaterial = 95
zuegs@22
  1291
evtDeleteMaterial = 94
zuegs@83
  1292
evtConvertMaterial = 92
zuegs@167
  1293
evtSaveMaterial2 = 91
zuegs@167
  1294
evtLoadMaterial2 = 90
zuegs@22
  1295
zuegs@22
  1296
zuegs@21
  1297
# default settings
zuegs@25
  1298
defaultsExclude = ['preset','filename','page','link']
zuegs@11
  1299
try:
dougal2@223
  1300
    luxdefaults = Blender.Registry.GetKey('luxblend', True)
dougal2@223
  1301
    if not(type(luxdefaults) is DictType):
dougal2@223
  1302
        luxdefaults = {}
zuegs@11
  1303
except:
dougal2@223
  1304
    luxdefaults = {}
zuegs@25
  1305
newluxdefaults = luxdefaults.copy()
zuegs@25
  1306
zuegs@11
  1307
zuegs@21
  1308
def saveluxdefaults():
dougal2@223
  1309
    try: del newluxdefaults['page']
dougal2@223
  1310
    except: pass
dougal2@223
  1311
    try: Blender.Registry.SetKey('luxblend', newluxdefaults, True)
dougal2@223
  1312
    except: pass
zuegs@11
  1313
zuegs@21
  1314
zuegs@22
  1315
zuegs@22
  1316
zuegs@22
  1317
zuegs@22
  1318
# *** PRESETS **************************************
zuegs@25
  1319
presetsExclude = ['preset','lux','datadir','threads','filename','page','RGC','film.gamma','colorclamp','link']
zuegs@22
  1320
def getPresets(key):
dougal2@223
  1321
    presets = Blender.Registry.GetKey(key, True)
dougal2@223
  1322
    if not(type(presets) is DictType):
dougal2@223
  1323
        presets = {}
dougal2@223
  1324
    return presets
zuegs@22
  1325
def getScenePresets():
dougal2@223
  1326
    presets = getPresets('luxblend_presets').copy()
dougal2@223
  1327
dougal2@223
  1328
    # radiance's hardcoded render presets:
dougal2@223
  1329
dougal2@223
  1330
    presets['0 Preview - Direct Lighting'] = {
dougal2@223
  1331
    'film.displayinterval': 4,
dougal2@223
  1332
    'haltspp': 0,
dougal2@223
  1333
    'useparamkeys': 'false',
dougal2@223
  1334
    'sampler.showadvanced': 'false',
dougal2@223
  1335
    'sintegrator.showadvanced': 'false',
dougal2@223
  1336
    'pixelfilter.showadvanced': 'false',
dougal2@223
  1337
dougal2@223
  1338
    'sampler.type': 'lowdiscrepancy',
dougal2@223
  1339
    'sampler.lowdisc.pixelsamples': 1,
dougal2@223
  1340
    'sampler.lowdisc.pixelsampler': 'lowdiscrepancy',
dougal2@223
  1341
dougal2@223
  1342
    'sintegrator.type': 'directlighting',
dougal2@223
  1343
    'sintegrator.dlighting.maxdepth': 5,
dougal2@223
  1344
dougal2@223
  1345
    'pixelfilter.type': 'mitchell',
radiance@316
  1346
    'pixelfilter.mitchell.sharp': 0.250, 
dougal2@223
  1347
    'pixelfilter.mitchell.xwidth': 2.0, 
dougal2@223
  1348
    'pixelfilter.mitchell.ywidth': 2.0, 
dougal2@223
  1349
    'pixelfilter.mitchell.optmode': "slider" }
dougal2@223
  1350
dougal2@223
  1351
    presets['1 Final - MLT/Bidir Path Tracing (interior) (recommended)'] =  {
dougal2@223
  1352
    'film.displayinterval': 8,
dougal2@223
  1353
    'haltspp': 0,
dougal2@223
  1354
    'useparamkeys': 'false',
dougal2@223
  1355
    'sampler.showadvanced': 'false',
dougal2@223
  1356
    'sintegrator.showadvanced': 'false',
dougal2@223
  1357
    'pixelfilter.showadvanced': 'false',
dougal2@223
  1358
dougal2@223
  1359
    'sampler.type': 'metropolis',
dougal2@223
  1360
    'sampler.metro.strength': 0.6,
dougal2@223
  1361
    'sampler.metro.lmprob': 0.4,
dougal2@223
  1362
    'sampler.metro.maxrejects': 512,
dougal2@223
  1363
    'sampler.metro.initsamples': 262144,
dougal2@223
  1364
    'sampler.metro.usevariance': "false",
dougal2@223
  1365
dougal2@223
  1366
    'sintegrator.type': 'bidirectional',
radiance29@246
  1367
    'sintegrator.bidir.bounces': 16,
radiance29@246
  1368
    'sintegrator.bidir.eyedepth': 16,
radiance29@246
  1369
    'sintegrator.bidir.lightdepth': 16,
dougal2@223
  1370
dougal2@223
  1371
    'pixelfilter.type': 'mitchell',
radiance@316
  1372
    'pixelfilter.mitchell.sharp': 0.250, 
dougal2@223
  1373
    'pixelfilter.mitchell.xwidth': 2.0, 
dougal2@223
  1374
    'pixelfilter.mitchell.ywidth': 2.0, 
dougal2@223
  1375
    'pixelfilter.mitchell.optmode': "slider" }
dougal2@223
  1376
dougal2@223
  1377
    presets['2 Final - MLT/Path Tracing (exterior)'] =  {
dougal2@223
  1378
    'film.displayinterval': 8,
dougal2@223
  1379
    'haltspp': 0,
dougal2@223
  1380
    'useparamkeys': 'false',
dougal2@223
  1381
    'sampler.showadvanced': 'false',
dougal2@223
  1382
    'sintegrator.showadvanced': 'false',
dougal2@223
  1383
    'pixelfilter.showadvanced': 'false',
dougal2@223
  1384
dougal2@223
  1385
    'sampler.type': 'metropolis',
dougal2@223
  1386
    'sampler.metro.strength': 0.6,
dougal2@223
  1387
    'sampler.metro.lmprob': 0.4,
dougal2@223
  1388
    'sampler.metro.maxrejects': 512,
dougal2@223
  1389
    'sampler.metro.initsamples': 262144,
dougal2@223
  1390
    'sampler.metro.usevariance': "false",
dougal2@223
  1391
dougal2@223
  1392
    'sintegrator.type': 'path',
dougal2@223
  1393
    'sintegrator.bidir.bounces': 10,
dougal2@223
  1394
    'sintegrator.bidir.maxdepth': 10,
dougal2@223
  1395
dougal2@223
  1396
    'pixelfilter.type': 'mitchell',
radiance@316
  1397
    'pixelfilter.mitchell.sharp': 0.250, 
dougal2@223
  1398
    'pixelfilter.mitchell.xwidth': 2.0, 
dougal2@223
  1399
    'pixelfilter.mitchell.ywidth': 2.0, 
dougal2@223
  1400
    'pixelfilter.mitchell.optmode': "slider" }
dougal2@223
  1401
    
dougal2@223
  1402
    presets['4 '] = { }
dougal2@223
  1403
dougal2@223
  1404
    presets['5 Progressive - Bidir Path Tracing (interior)'] =  {
dougal2@223
  1405
    'film.displayinterval': 8,
dougal2@223
  1406
    'haltspp': 0,
dougal2@223
  1407
    'useparamkeys': 'false',
dougal2@223
  1408
    'sampler.showadvanced': 'false',
dougal2@223
  1409
    'sintegrator.showadvanced': 'false',
dougal2@223
  1410
    'pixelfilter.showadvanced': 'false',
dougal2@223
  1411
dougal2@223
  1412
    'sampler.type': 'lowdiscrepancy',
dougal2@223
  1413
    'sampler.lowdisc.pixelsamples': 1,
dougal2@223
  1414
    'sampler.lowdisc.pixelsampler': 'lowdiscrepancy',
dougal2@223
  1415
dougal2@223
  1416
    'sintegrator.type': 'bidirectional',
radiance29@246
  1417
    'sintegrator.bidir.bounces': 16,
radiance29@246
  1418
    'sintegrator.bidir.eyedepth': 16,
radiance29@246
  1419
    'sintegrator.bidir.lightdepth': 16,
dougal2@223
  1420
dougal2@223
  1421
    'pixelfilter.type': 'mitchell',
radiance@316
  1422
    'pixelfilter.mitchell.sharp': 0.250, 
dougal2@223
  1423
    'pixelfilter.mitchell.xwidth': 2.0, 
dougal2@223
  1424
    'pixelfilter.mitchell.ywidth': 2.0, 
dougal2@223
  1425
    'pixelfilter.mitchell.optmode': "slider" }
dougal2@223
  1426
dougal2@223
  1427
    presets['6 Progressive - Path Tracing (exterior)'] =  {
dougal2@223
  1428
    'film.displayinterval': 8,
dougal2@223
  1429
    'haltspp': 0,
dougal2@223
  1430
    'useparamkeys': 'false',
dougal2@223
  1431
    'sampler.showadvanced': 'false',
dougal2@223
  1432
    'sintegrator.showadvanced': 'false',
dougal2@223
  1433
    'pixelfilter.showadvanced': 'false',
dougal2@223
  1434
dougal2@223
  1435
    'sampler.type': 'lowdiscrepancy',
dougal2@223
  1436
    'sampler.lowdisc.pixelsamples': 1,
dougal2@223
  1437
    'sampler.lowdisc.pixelsampler': 'lowdiscrepancy',
dougal2@223
  1438
dougal2@223
  1439
    'sintegrator.type': 'path',
dougal2@223
  1440
    'sintegrator.bidir.bounces': 10,
dougal2@223
  1441
    'sintegrator.bidir.maxdepth': 10,
dougal2@223
  1442
dougal2@223
  1443
    'pixelfilter.type': 'mitchell',
radiance@316
  1444
    'pixelfilter.mitchell.sharp': 0.250, 
dougal2@223
  1445
    'pixelfilter.mitchell.xwidth': 2.0, 
dougal2@223
  1446
    'pixelfilter.mitchell.ywidth': 2.0, 
dougal2@223
  1447
    'pixelfilter.mitchell.optmode': "slider" }
dougal2@223
  1448
dougal2@223
  1449
    presets['7 '] = { }
dougal2@223
  1450
dougal2@223
  1451
    presets['8 Bucket - Bidir Path Tracing (interior)'] =  {
dougal2@223
  1452
    'film.displayinterval': 8,
dougal2@223
  1453
    'haltspp': 0,
dougal2@223
  1454
    'useparamkeys': 'false',
dougal2@223
  1455
    'sampler.showadvanced': 'false',
dougal2@223
  1456
    'sintegrator.showadvanced': 'false',
dougal2@223
  1457
    'pixelfilter.showadvanced': 'false',
dougal2@223
  1458
dougal2@223
  1459
    'sampler.type': 'lowdiscrepancy',
dougal2@223
  1460
    'sampler.lowdisc.pixelsamples': 64,
dougal2@223
  1461
    'sampler.lowdisc.pixelsampler': 'hilbert',
dougal2@223
  1462
dougal2@223
  1463
    'sintegrator.type': 'bidirectional',
dougal2@223
  1464
    'sintegrator.bidir.bounces': 8,
dougal2@223
  1465
    'sintegrator.bidir.eyedepth': 8,
dougal2@223
  1466
    'sintegrator.bidir.lightdepth': 10,
dougal2@223
  1467
dougal2@223
  1468
    'pixelfilter.type': 'mitchell',
radiance@316
  1469
    'pixelfilter.mitchell.sharp': 0.250, 
dougal2@223
  1470
    'pixelfilter.mitchell.xwidth': 2.0, 
dougal2@223
  1471
    'pixelfilter.mitchell.ywidth': 2.0, 
dougal2@223
  1472
    'pixelfilter.mitchell.optmode': "slider" }
dougal2@223
  1473
dougal2@223
  1474
    presets['9 Bucket - Path Tracing (exterior)'] =  {
dougal2@223
  1475
    'film.displayinterval': 8,
dougal2@223
  1476
    'haltspp': 0,
dougal2@223
  1477
    'useparamkeys': 'false',
dougal2@223
  1478
    'sampler.showadvanced': 'false',
dougal2@223
  1479
    'sintegrator.showadvanced': 'false',
dougal2@223
  1480
    'pixelfilter.showadvanced': 'false',
dougal2@223
  1481
dougal2@223
  1482
    'sampler.type': 'lowdiscrepancy',
dougal2@223
  1483
    'sampler.lowdisc.pixelsamples': 64,
dougal2@223
  1484
    'sampler.lowdisc.pixelsampler': 'hilbert',
dougal2@223
  1485
dougal2@223
  1486
    'sintegrator.type': 'path',
dougal2@223
  1487
    'sintegrator.bidir.bounces': 8,
dougal2@223
  1488
    'sintegrator.bidir.maxdepth': 8,
dougal2@223
  1489
dougal2@223
  1490
    'pixelfilter.type': 'mitchell',
dougal2@223
  1491
    'pixelfilter.mitchell.sharp': 0.333, 
dougal2@223
  1492
    'pixelfilter.mitchell.xwidth': 2.0, 
dougal2@223
  1493
    'pixelfilter.mitchell.ywidth': 2.0, 
dougal2@223
  1494
    'pixelfilter.mitchell.optmode': "slider" }
dougal2@223
  1495
dougal2@223
  1496
    presets['A '] = { }
dougal2@223
  1497
dougal2@223
  1498
    presets['B Anim - Distributed/GI low Q'] =  {
dougal2@223
  1499
    'film.displayinterval': 8,
dougal2@223
  1500
    'haltspp': 1,
dougal2@223
  1501
    'useparamkeys': 'false',
dougal2@223
  1502
    'sampler.showadvanced': 'false',
dougal2@223
  1503
    'sintegrator.showadvanced': 'false',
dougal2@223
  1504
    'pixelfilter.showadvanced': 'false',
dougal2@223
  1505
dougal2@223
  1506
    'sampler.type': 'lowdiscrepancy',
dougal2@223
  1507
    'sampler.lowdisc.pixelsamples': 16,
dougal2@223
  1508
    'sampler.lowdisc.pixelsampler': 'hilbert',
dougal2@223
  1509
dougal2@223
  1510
    'sintegrator.type': 'distributedpath',
dougal2@223
  1511
    'sintegrator.distributedpath.causticsonglossy': 'true',
dougal2@223
  1512
    'sintegrator.distributedpath.diffuserefractdepth': 5,
dougal2@223
  1513
    'sintegrator.distributedpath.indirectglossy': 'true',
dougal2@223
  1514
    'sintegrator.distributedpath.directsamples': 1,
dougal2@223
  1515
    'sintegrator.distributedpath.diffuserefractsamples': 1,
dougal2@223
  1516
    'sintegrator.distributedpath.glossyreflectdepth': 2,
dougal2@223
  1517
    'sintegrator.distributedpath.causticsondiffuse': 'false',
dougal2@223
  1518
    'sintegrator.distributedpath.directsampleall': 'true',
dougal2@223
  1519
    'sintegrator.distributedpath.indirectdiffuse': 'true',
dougal2@223
  1520
    'sintegrator.distributedpath.specularreflectdepth': 3,
dougal2@223
  1521
    'sintegrator.distributedpath.diffusereflectsamples': 1,
dougal2@223
  1522
    'sintegrator.distributedpath.glossyreflectsamples': 1,
dougal2@223
  1523
    'sintegrator.distributedpath.glossyrefractdepth': 5,
dougal2@223
  1524
    'sintegrator.distributedpath.diffusereflectdepth': '2',
dougal2@223
  1525
    'sintegrator.distributedpath.indirectsamples': 1,
dougal2@223
  1526
    'sintegrator.distributedpath.indirectsampleall': 'false',
dougal2@223
  1527
    'sintegrator.distributedpath.glossyrefractsamples': 1,
dougal2@223
  1528
    'sintegrator.distributedpath.directdiffuse': 'true',
dougal2@223
  1529
    'sintegrator.distributedpath.directglossy': 'true',
dougal2@223
  1530
    'sintegrator.distributedpath.strategy': 'auto',
dougal2@223
  1531
    'sintegrator.distributedpath.specularrefractdepth': 5,
dougal2@223
  1532
dougal2@223
  1533
    'pixelfilter.type': 'mitchell',
dougal2@223
  1534
    'pixelfilter.mitchell.sharp': 0.333, 
dougal2@223
  1535
    'pixelfilter.mitchell.xwidth': 2.0, 
dougal2@223
  1536
    'pixelfilter.mitchell.ywidth': 2.0, 
dougal2@223
  1537
    'pixelfilter.mitchell.optmode': "slider" }
dougal2@223
  1538
dougal2@223
  1539
    presets['C Anim - Distributed/GI medium Q'] =  {
dougal2@223
  1540
    'film.displayinterval': 8,
dougal2@223
  1541
    'haltspp': 1,
dougal2@223
  1542
    'useparamkeys': 'false',
dougal2@223
  1543
    'sampler.showadvanced': 'false',
dougal2@223
  1544
    'sintegrator.showadvanced': 'false',
dougal2@223
  1545
    'pixelfilter.showadvanced': 'false',
dougal2@223
  1546
dougal2@223
  1547
    'sampler.type': 'lowdiscrepancy',
dougal2@223
  1548
    'sampler.lowdisc.pixelsamples': 64,
dougal2@223
  1549
    'sampler.lowdisc.pixelsampler': 'hilbert',
dougal2@223
  1550
dougal2@223
  1551
    'sintegrator.type': 'distributedpath',
dougal2@223
  1552
    'sintegrator.distributedpath.causticsonglossy': 'true',
dougal2@223
  1553
    'sintegrator.distributedpath.diffuserefractdepth': 5,
dougal2@223
  1554
    'sintegrator.distributedpath.indirectglossy': 'true',
dougal2@223
  1555
    'sintegrator.distributedpath.directsamples': 1,
dougal2@223
  1556
    'sintegrator.distributedpath.diffuserefractsamples': 1,
dougal2@223
  1557
    'sintegrator.distributedpath.glossyreflectdepth': 2,
dougal2@223
  1558
    'sintegrator.distributedpath.causticsondiffuse': 'false',
dougal2@223
  1559
    'sintegrator.distributedpath.directsampleall': 'true',
dougal2@223
  1560
    'sintegrator.distributedpath.indirectdiffuse': 'true',
dougal2@223
  1561
    'sintegrator.distributedpath.specularreflectdepth': 3,
dougal2@223
  1562
    'sintegrator.distributedpath.diffusereflectsamples': 1,
dougal2@223
  1563
    'sintegrator.distributedpath.glossyreflectsamples': 1,
dougal2@223
  1564
    'sintegrator.distributedpath.glossyrefractdepth': 5,
dougal2@223
  1565
    'sintegrator.distributedpath.diffusereflectdepth': '2',
dougal2@223
  1566
    'sintegrator.distributedpath.indirectsamples': 1,
dougal2@223
  1567
    'sintegrator.distributedpath.indirectsampleall': 'false',
dougal2@223
  1568
    'sintegrator.distributedpath.glossyrefractsamples': 1,
dougal2@223
  1569
    'sintegrator.distributedpath.directdiffuse': 'true',
dougal2@223
  1570
    'sintegrator.distributedpath.directglossy': 'true',
dougal2@223
  1571
    'sintegrator.distributedpath.strategy': 'auto',
dougal2@223
  1572
    'sintegrator.distributedpath.specularrefractdepth': 5,
dougal2@223
  1573
dougal2@223
  1574
    'pixelfilter.type': 'mitchell',
dougal2@223
  1575
    'pixelfilter.mitchell.sharp': 0.333, 
dougal2@223
  1576
    'pixelfilter.mitchell.xwidth': 2.0, 
dougal2@223
  1577
    'pixelfilter.mitchell.ywidth': 2.0, 
dougal2@223
  1578
    'pixelfilter.mitchell.optmode': "slider" }
dougal2@223
  1579
    
dougal2@223
  1580
    presets['D Anim - Distributed/GI high Q'] =  {
dougal2@223
  1581
    'film.displayinterval': 8,
dougal2@223
  1582
    'haltspp': 1,
dougal2@223
  1583
    'useparamkeys': 'false',
dougal2@223
  1584
    'sampler.showadvanced': 'false',
dougal2@223
  1585
    'sintegrator.showadvanced': 'false',
dougal2@223
  1586
    'pixelfilter.showadvanced': 'false',
dougal2@223
  1587
dougal2@223
  1588
    'sampler.type': 'lowdiscrepancy',
dougal2@223
  1589
    'sampler.lowdisc.pixelsamples': 256,
dougal2@223
  1590
    'sampler.lowdisc.pixelsampler': 'hilbert',
dougal2@223
  1591
dougal2@223
  1592
    'sintegrator.type': 'distributedpath',
dougal2@223
  1593
    'sintegrator.distributedpath.causticsonglossy': 'true',
dougal2@223
  1594
    'sintegrator.distributedpath.diffuserefractdepth': 5,
dougal2@223
  1595
    'sintegrator.distributedpath.indirectglossy': 'true',
dougal2@223
  1596
    'sintegrator.distributedpath.directsamples': 1,
dougal2@223
  1597
    'sintegrator.distributedpath.diffuserefractsamples': 1,
dougal2@223
  1598
    'sintegrator.distributedpath.glossyreflectdepth': 2,
dougal2@223
  1599
    'sintegrator.distributedpath.causticsondiffuse': 'false',
dougal2@223
  1600
    'sintegrator.distributedpath.directsampleall': 'true',
dougal2@223
  1601
    'sintegrator.distributedpath.indirectdiffuse': 'true',
dougal2@223
  1602
    'sintegrator.distributedpath.specularreflectdepth': 3,
dougal2@223
  1603
    'sintegrator.distributedpath.diffusereflectsamples': 1,
dougal2@223
  1604
    'sintegrator.distributedpath.glossyreflectsamples': 1,
dougal2@223
  1605
    'sintegrator.distributedpath.glossyrefractdepth': 5,
dougal2@223
  1606
    'sintegrator.distributedpath.diffusereflectdepth': '2',
dougal2@223
  1607
    'sintegrator.distributedpath.indirectsamples': 1,
dougal2@223
  1608
    'sintegrator.distributedpath.indirectsampleall': 'false',
dougal2@223
  1609
    'sintegrator.distributedpath.glossyrefractsamples': 1,
dougal2@223
  1610
    'sintegrator.distributedpath.directdiffuse': 'true',
dougal2@223
  1611
    'sintegrator.distributedpath.directglossy': 'true',
dougal2@223
  1612
    'sintegrator.distributedpath.strategy': 'auto',
dougal2@223
  1613
    'sintegrator.distributedpath.specularrefractdepth': 5,
dougal2@223
  1614
dougal2@223
  1615
    'pixelfilter.type': 'mitchell',
dougal2@223
  1616
    'pixelfilter.mitchell.sharp': 0.333, 
dougal2@223
  1617
    'pixelfilter.mitchell.xwidth': 2.0, 
dougal2@223
  1618
    'pixelfilter.mitchell.ywidth': 2.0, 
dougal2@223
  1619
    'pixelfilter.mitchell.optmode': "slider" }
dougal2@223
  1620
dougal2@223
  1621
    presets['E Anim - Distributed/GI very high Q'] =  {
dougal2@223
  1622
    'film.displayinterval': 8,
dougal2@223
  1623
    'haltspp': 1,
dougal2@223
  1624
    'useparamkeys': 'false',
dougal2@223
  1625
    'sampler.showadvanced': 'false',
dougal2@223
  1626
    'sintegrator.showadvanced': 'false',
dougal2@223
  1627
    'pixelfilter.showadvanced': 'false',
dougal2@223
  1628
dougal2@223
  1629
    'sampler.type': 'lowdiscrepancy',
dougal2@223
  1630
    'sampler.lowdisc.pixelsamples': 512,
dougal2@223
  1631
    'sampler.lowdisc.pixelsampler': 'hilbert',
dougal2@223
  1632
dougal2@223
  1633
    'sintegrator.type': 'distributedpath',
dougal2@223
  1634
    'sintegrator.distributedpath.causticsonglossy': 'true',
dougal2@223
  1635
    'sintegrator.distributedpath.diffuserefractdepth': 5,
dougal2@223
  1636
    'sintegrator.distributedpath.indirectglossy': 'true',
dougal2@223
  1637
    'sintegrator.distributedpath.directsamples': 1,
dougal2@223
  1638
    'sintegrator.distributedpath.diffuserefractsamples': 1,
dougal2@223
  1639
    'sintegrator.distributedpath.glossyreflectdepth': 2,
dougal2@223
  1640
    'sintegrator.distributedpath.causticsondiffuse': 'false',
dougal2@223
  1641
    'sintegrator.distributedpath.directsampleall': 'true',
dougal2@223
  1642
    'sintegrator.distributedpath.indirectdiffuse': 'true',
dougal2@223
  1643
    'sintegrator.distributedpath.specularreflectdepth': 3,
dougal2@223
  1644
    'sintegrator.distributedpath.diffusereflectsamples': 1,
dougal2@223
  1645
    'sintegrator.distributedpath.glossyreflectsamples': 1,
dougal2@223
  1646
    'sintegrator.distributedpath.glossyrefractdepth': 5,
dougal2@223
  1647
    'sintegrator.distributedpath.diffusereflectdepth': '2',
dougal2@223
  1648
    'sintegrator.distributedpath.indirectsamples': 1,
dougal2@223
  1649
    'sintegrator.distributedpath.indirectsampleall': 'false',
dougal2@223
  1650
    'sintegrator.distributedpath.glossyrefractsamples': 1,
dougal2@223
  1651
    'sintegrator.distributedpath.directdiffuse': 'true',
dougal2@223
  1652
    'sintegrator.distributedpath.directglossy': 'true',
dougal2@223
  1653
    'sintegrator.distributedpath.strategy': 'auto',
dougal2@223
  1654
    'sintegrator.distributedpath.specularrefractdepth': 5,
dougal2@223
  1655
dougal2@223
  1656
    'pixelfilter.type': 'mitchell',
dougal2@223
  1657
    'pixelfilter.mitchell.sharp': 0.333, 
dougal2@223
  1658
    'pixelfilter.mitchell.xwidth': 2.0, 
dougal2@223
  1659
    'pixelfilter.mitchell.ywidth': 2.0, 
dougal2@223
  1660
    'pixelfilter.mitchell.optmode': "slider" }
dougal2@223
  1661
dougal2@223
  1662
    return presets
radiance29@157
  1663
zuegs@22
  1664
def getMaterialPresets():
dougal2@223
  1665
    return getPresets('luxblend_materials')
zuegs@22
  1666
zuegs@22
  1667
def savePreset(key, name, d):
dougal2@223
  1668
    try:
dougal2@223
  1669
        presets = getPresets(key)
dougal2@223
  1670
        if d:
dougal2@223
  1671
            presets[name] = d.copy()
dougal2@223
  1672
        else:
dougal2@223
  1673
            del presets[name]
dougal2@223
  1674
        Blender.Registry.SetKey(key, presets, True)
dougal2@223
  1675
    except: pass    
zuegs@22
  1676
def saveScenePreset(name, d):
dougal2@223
  1677
    try:
dougal2@223
  1678
        for n in presetsExclude:
dougal2@223
  1679
            try: del d[n];
dougal2@223
  1680
            except: pass
dougal2@223
  1681
        savePreset('luxblend_presets', name, d)
dougal2@223
  1682
    except: pass
zuegs@22
  1683
def saveMaterialPreset(name, d):
dougal2@223
  1684
    try:
dougal2@223
  1685
        for n in presetsExclude:
dougal2@223
  1686
            try: del d[n];
dougal2@223
  1687
            except: pass
dougal2@223
  1688
        savePreset('luxblend_materials', name, d)
dougal2@223
  1689
    except: pass
zuegs@22
  1690
radiance29@115
  1691
zuegs@22
  1692
# **************************************************
zuegs@22
  1693
zuegs@22
  1694
zuegs@21
  1695
zuegs@21
  1696
zuegs@22
  1697
zuegs@22
  1698
usedproperties = {} # global variable to collect used properties for storing presets
zuegs@167
  1699
usedpropertiesfilterobj = None # assign a object to only collect the properties that are assigned to this object
zuegs@75
  1700
zuegs@21
  1701
# class to access properties (for lux settings)
zuegs@21
  1702
class luxProp:
dougal2@223
  1703
    def __init__(self, obj, name, default):
dougal2@223
  1704
        self.obj = obj
dougal2@223
  1705
        self.name = name
dougal2@223
  1706
#        if len(name)>31: print "Warning: property-name \"%s\" has more than 31 chars."%(name)
dougal2@223
  1707
        self.hashmode = len(name)>31   # activate hash mode for keynames longer 31 chars (limited by blenders ID-prop)
dougal2@223
  1708
        self.hashname = "__hash:%x"%(name.__hash__())
dougal2@223
  1709
        self.default = default
dougal2@223
  1710
    def parseassignment(self, s, name):
dougal2@223
  1711
        l = s.split(" = ")
dougal2@223
  1712
        if l[0] != name: print "Warning: property-name \"%s\" has hash-collide with \"%s\"."%(name, l[0])
dougal2@223
  1713
        return l[1]
dougal2@223
  1714
    def createassignment(self, name, value):
dougal2@223
  1715
        return "%s = %s"%(name, value)
dougal2@223
  1716
    def get(self):
dougal2@223
  1717
        global usedproperties, usedpropertiesfilterobj, luxdefaults
dougal2@223
  1718
        if self.obj:
dougal2@223
  1719
            try:
dougal2@223
  1720
                value = self.obj.properties['luxblend'][self.name]
dougal2@223
  1721
                if not(usedpropertiesfilterobj) or (usedpropertiesfilterobj == self.obj):
dougal2@223
  1722
                    usedproperties[self.name] = value
dougal2@223
  1723
                return value
dougal2@223
  1724
            except KeyError:
dougal2@223
  1725
                try:
dougal2@223
  1726
                    value = self.parseassignment(self.obj.properties['luxblend'][self.hashname], self.name)
dougal2@223
  1727
                    if not(usedpropertiesfilterobj) or (usedpropertiesfilterobj == self.obj):
dougal2@223
  1728
                        usedproperties[self.name] = value
dougal2@223
  1729
                    return value
dougal2@223
  1730
                except KeyError:
dougal2@223
  1731
                    if self.obj.__class__.__name__ == "Scene": # luxdefaults only for global setting
dougal2@223
  1732
                        try:
dougal2@223
  1733
                            value = luxdefaults[self.name]
dougal2@223
  1734
                            if not(usedpropertiesfilterobj) or (usedpropertiesfilterobj == self.obj):
dougal2@223
  1735
                                usedproperties[self.name] = value
dougal2@223
  1736
                            return value
dougal2@223
  1737
                        except KeyError:
dougal2@223
  1738
                            if not(usedpropertiesfilterobj) or (usedpropertiesfilterobj == self.obj):
dougal2@223
  1739
                                usedproperties[self.name] = self.default
dougal2@223
  1740
                            return self.default
dougal2@223
  1741
                    if not(usedpropertiesfilterobj) or (usedpropertiesfilterobj == self.obj):
dougal2@223
  1742
                        usedproperties[self.name] = self.default
dougal2@223
  1743
                    return self.default
dougal2@223
  1744
        return None
dougal2@223
  1745
    def getobj(self):
dougal2@223
  1746
        if self.obj:
dougal2@223
  1747
            return self.obj
dougal2@223
  1748
        else:
dougal2@223
  1749
            return None
dougal2@223
  1750
    def getname(self):
dougal2@223
  1751
        if self.name:
dougal2@223
  1752
            return self.name
dougal2@223
  1753
        else:
dougal2@223
  1754
            return None
dougal2@223
  1755
    def set(self, value):
dougal2@223
  1756
        global newluxdefaults
dougal2@223
  1757
        if self.obj:
dougal2@223
  1758
            if self.hashmode: n, v = self.hashname, self.createassignment(self.name, value)
dougal2@223
  1759
            else: n, v = self.name, value
dougal2@223
  1760
            if value is not None:
dougal2@223
  1761
                try: self.obj.properties['luxblend'][n] = v
dougal2@223
  1762
                except (KeyError, TypeError):
dougal2@223
  1763
                    self.obj.properties['luxblend'] = {}
dougal2@223
  1764
                    self.obj.properties['luxblend'][n] = v
dougal2@223
  1765
            else:
dougal2@223
  1766
                try: del self.obj.properties['luxblend'][n]
dougal2@223
  1767
                except:    pass
dougal2@223
  1768
            if self.obj.__class__.__name__ == "Scene": # luxdefaults only for global setting
dougal2@223
  1769
                # value has changed, so this are user settings, remove preset reference
dougal2@223
  1770
                if not(self.name in defaultsExclude):
dougal2@223
  1771
                    newluxdefaults[self.name] = value
dougal2@223
  1772
                    try: self.obj.properties['luxblend']['preset']=""
dougal2@223
  1773
                    except: pass
dougal2@223
  1774
    def delete(self):
dougal2@223
  1775
        if self.obj:
dougal2@223
  1776
            try: del self.obj.properties['luxblend'][self.name]
dougal2@223
  1777
            except:    pass
dougal2@223
  1778
            try: del self.obj.properties['luxblend'][self.hashname]
dougal2@223
  1779
            except:    pass
dougal2@223
  1780
    def getFloat(self):
dougal2@223
  1781
        v = self.get()
dougal2@223
  1782
        if type(v) == types.FloatType: return float(v)
dougal2@223
  1783
        try:
dougal2@223
  1784
            if type(v) == types.StringType: return float(v.split(" ")[0])
dougal2@223
  1785
        except: pass
dougal2@223
  1786
        v = self.default
dougal2@223
  1787
        if type(v) == types.FloatType: return float(v)
dougal2@223
  1788
        try:
dougal2@223
  1789
            if type(v) == types.StringType: return float(v.split(" ")[0])
dougal2@223
  1790
        except: pass
dougal2@223
  1791
        return 0.0
dougal2@223
  1792
    def getInt(self):
dougal2@223
  1793
        try: return int(self.get())
dougal2@223
  1794
        except: return int(self.default)
dougal2@223
  1795
    def getRGB(self):
dougal2@223
  1796
        return self.getVector()
dougal2@223
  1797
    def getVector(self):
dougal2@223
  1798
        v = self.get()
dougal2@223
  1799
        if type(v) in [types.FloatType, types.IntType]: return (float(v), float(v), float(v))
dougal2@223
  1800
        l = None
dougal2@223
  1801
        try:
dougal2@223
  1802
            if type(v) == types.StringType: l = self.get().split(" ")
dougal2@223
  1803
        except: pass
dougal2@233
  1804
        try:
dougal2@233
  1805
            if (l==None) or (len(l) != 3): l = self.default.split(" ")
dougal2@233
  1806
            return (float(l[0]), float(l[1]), float(l[2]))
dougal2@233
  1807
        except AttributeError:
dougal2@233
  1808
            return (float(l[0]), float(l[0]), float(l[0]))
dougal2@233
  1809
        
dougal2@223
  1810
    def getVectorStr(self):
dougal2@223
  1811
        return "%f %f %f"%self.getVector()
dougal2@223
  1812
    def isFloat(self):
dougal2@223
  1813
        return type(self.get()) == types.FloatType
dougal2@223
  1814
    def getRGC(self):
dougal2@223
  1815
        col = self.getRGB()
dougal2@223
  1816
        return "%f %f %f"%(rg(col[0]), rg(col[1]),rg(col[2]))
dougal2@223
  1817
    def setRGB(self, value):
dougal2@223
  1818
        self.set("%f %f %f"%(value[0], value[1], value[2]))
dougal2@223
  1819
    def setVector(self, value):
dougal2@223
  1820
        self.set("%f %f %f"%(value[0], value[1], value[2]))
zuegs@21
  1821
zuegs@21
  1822
zuegs@21
  1823
# class to access blender attributes (for lux settings)
zuegs@21
  1824
class luxAttr:
dougal2@223
  1825
    def __init__(self, obj, name):
dougal2@223
  1826
        self.obj = obj
dougal2@223
  1827
        self.name = name
dougal2@223
  1828
    def get(self):
dougal2@223
  1829
        if self.obj:
dougal2@223
  1830
            return getattr(self.obj, self.name)
dougal2@223
  1831
        else:
dougal2@223
  1832
            return None
dougal2@223
  1833
    def getFloat(self):
dougal2@223
  1834
        return float(self.get())
dougal2@223
  1835
    def getInt(self):
dougal2@223
  1836
        return int(self.get())
dougal2@223
  1837
    def getobj(self):
dougal2@223
  1838
        if self.obj:
dougal2@223
  1839
            return self.obj
dougal2@223
  1840
        else:
dougal2@223
  1841
            return None
dougal2@223
  1842
    def getname(self):
dougal2@223
  1843
        if self.name:
dougal2@223
  1844
            return self.name
dougal2@223
  1845
        else:
dougal2@223
  1846
            return None
dougal2@223
  1847
    def set(self, value):
dougal2@223
  1848
        if self.obj:
dougal2@223
  1849
            setattr(self.obj, self.name, value)
dougal2@223
  1850
            Window.QRedrawAll()
zuegs@11
  1851
zuegs@21
  1852
zuegs@21
  1853
# class for dynamic gui
zuegs@21
  1854
class luxGui:
dougal2@223
  1855
    def __init__(self, y=200):
dougal2@223
  1856
        self.x = 110 # left start position after captions
dougal2@223
  1857
        self.xmax = 110+2*(140+4)
dougal2@223
  1858
        self.y = y
dougal2@223
  1859
        self.w = 140 # default element width in pixels
dougal2@223
  1860
        self.h = 18  # default element height in pixels
dougal2@223
  1861
        self.hmax = 0
dougal2@223
  1862
        self.xgap = 4
dougal2@223
  1863
        self.ygap = 4
dougal2@223
  1864
        self.resethmax = False
dougal2@223
  1865
    def getRect(self, wu, hu):
dougal2@223
  1866
        w = int(self.w * wu + self.xgap * (wu-1))
dougal2@223
  1867
        h = int(self.h * hu + self.ygap * (hu-1))
dougal2@223
  1868
        if self.x + w > self.xmax: self.newline()
dougal2@223
  1869
        if self.resethmax: self.hmax = 0; self.resethmax = False
dougal2@223
  1870
        rect = [int(self.x), int(self.y-h), int(w), int(h)]
dougal2@223
  1871
        self.x += int(w + self.xgap)
dougal2@223
  1872
        if h+self.ygap > self.hmax: self.hmax = int(h+self.ygap)
dougal2@223
  1873
        return rect
dougal2@223
  1874
    def newline(self, title="", distance=0, level=0, icon=None, color=None):
dougal2@223
  1875
        self.x = 110
dougal2@223
  1876
        if not(self.resethmax): self.y -= int(self.hmax + distance)
dougal2@223
  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)
dougal2@223
  1878
        if icon!=None: drawIcon(icon, 2+level*10, self.y-16)
dougal2@223
  1879
        self.resethmax = True
dougal2@223
  1880
        if title!="":
dougal2@223
  1881
            self.getRect(0, 1)
dougal2@223
  1882
            BGL.glColor3f(0.9,0.9,0.9); BGL.glRasterPos2i(20+level*10,self.y-self.h+5); Draw.Text(title)
dougal2@223
  1883
    
radiance29@115
  1884
def luxHelp(name, lux, caption, hint, gui, width=1.0):
dougal2@223
  1885
    if gui:
dougal2@223
  1886
        r = gui.getRect(width, 1)
dougal2@223
  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)]))
dougal2@223
  1888
        drawIcon(icon_help, r[0], r[1])
dougal2@223
  1889
dougal2@223
  1890
    return "\n   \"bool %s\" [\"%s\"]"%(name, lux.get())
zuegs@21
  1891
zuegs@21
  1892
# lux parameter types
zuegs@21
  1893
def luxOption(name, lux, options, caption, hint, gui, width=1.0):
dougal2@223
  1894
    if gui:
dougal2@223
  1895
        menustr = caption+": %t"
dougal2@223
  1896
        for i, v in enumerate(options): menustr = "%s %%x%d|%s"%(v, i, menustr)
dougal2@223
  1897
        try:
dougal2@223
  1898
            i = options.index(lux.get())
dougal2@223
  1899
        except ValueError:
dougal2@223
  1900
            try:
dougal2@223
  1901
                lux.set(lux.default) # not found, so try default value
dougal2@223
  1902
                i = options.index(lux.get())
dougal2@223
  1903
            except ValueError:
dougal2@223
  1904
                print "value %s not found in options list"%(lux.get())
dougal2@223
  1905
                i = 0
dougal2@223
  1906
        r = gui.getRect(width, 1)
dougal2@223
  1907
        Draw.Menu(menustr, evtLuxGui, r[0], r[1], r[2], r[3], i, hint, lambda e,v: lux.set(options[v]))
dougal2@223
  1908
    return "\n   \"string %s\" [\"%s\"]"%(name, lux.get())
zuegs@11
  1909
radiance29@115
  1910
def luxOptionRect(name, lux, options, caption, hint, gui, x, y, xx, yy):
dougal2@223
  1911
    if gui:
dougal2@223
  1912
        menustr = caption+": %t"
dougal2@223
  1913
        for i, v in enumerate(options): menustr = "%s %%x%d|%s"%(v, i, menustr)
dougal2@223
  1914
        try:
dougal2@223
  1915
            i = options.index(lux.get())
dougal2@223
  1916
        except ValueError:
dougal2@223
  1917
            try:
dougal2@223
  1918
                lux.set(lux.default) # not found, so try default value
dougal2@223
  1919
                i = options.index(lux.get())
dougal2@223
  1920
            except ValueError:
dougal2@223
  1921
                print "value %s not found in options list"%(lux.get())
dougal2@223
  1922
                i = 0
dougal2@223
  1923
        Draw.Menu(menustr, evtLuxGui, x, y, xx, yy, i, hint, lambda e,v: lux.set(options[v]))
dougal2@223
  1924
    return "\n   \"string %s\" [\"%s\"]"%(name, lux.get())
radiance29@115
  1925
radiance29@115
  1926
def luxIdentifier(name, lux, options, caption, hint, gui, icon=None, width=1.0):
dougal2@223
  1927
    if gui: gui.newline(caption+":", 8, 0, icon, [0.75,0.5,0.25])
dougal2@223
  1928
    luxOption(name, lux, options, caption, hint, gui, width)
dougal2@223
  1929
    return "\n%s \"%s\""%(name, lux.get())
zuegs@11
  1930
radiance29@121
  1931
def luxFloat(name, lux, min, max, caption, hint, gui, width=1.0, useslider=0):
dougal2@223
  1932
    if gui:
dougal2@223
  1933
        if (luxProp(Scene.GetCurrent(), "useparamkeys", "false").get()=="true"):
dougal2@223
  1934
            r = gui.getRect(width-0.12, 1)
dougal2@223
  1935
        else:
dougal2@223
  1936
            r = gui.getRect(width, 1)
dougal2@223
  1937
dougal2@223
  1938
        # Value
dougal2@223
  1939
        if(useslider==1):
dougal2@223
  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))
dougal2@223
  1941
        else:
dougal2@223
  1942
            Draw.Number(caption+": ", evtLuxGui, r[0], r[1], r[2], r[3], lux.getFloat(), min, max, hint, lambda e,v: lux.set(v))
dougal2@223
  1943
        if (luxProp(Scene.GetCurrent(), "useparamkeys", "false").get()=="true"):
dougal2@223
  1944
            # IPO Curve
dougal2@223
  1945
            obj = lux.getobj()
dougal2@223
  1946
            keyname = lux.getname()
dougal2@223
  1947
    
dougal2@223
  1948
            useipo = luxProp(obj, keyname+".IPOuse", "false")
dougal2@223
  1949
            i = gui.getRect(0.12, 1)
dougal2@223
  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)]))
dougal2@223
  1951
            
dougal2@223
  1952
            if useipo.get() == "true":
dougal2@223
  1953
                if gui: gui.newline(caption+"IPO:", 8, 0, None, [0.5,0.45,0.35])
dougal2@223
  1954
                curve = luxProp(obj, keyname+".IPOCurveName", "") 
dougal2@223
  1955
                if curve.get() == "":
dougal2@223
  1956
                    c = gui.getRect(2.0, 1)
dougal2@223
  1957
                else:
dougal2@223
  1958
                    c = gui.getRect(1.1, 1)
dougal2@223
  1959
                
dougal2@223
  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))
dougal2@223
  1961
                
dougal2@223
  1962
                usemapping = luxProp(obj, keyname+".IPOmap", "false")
dougal2@223
  1963
                icu_value = 0
dougal2@223
  1964
    
dougal2@223
  1965
                # Apply IPO to value
dougal2@223
  1966
                if curve.get() != "":
dougal2@223
  1967
                    try:
dougal2@223
  1968
                        ipoob = Blender.Ipo.Get(curve.get())
dougal2@223
  1969
                    except: 
dougal2@223
  1970
                        curve.set("")
dougal2@223
  1971
                    pass
dougal2@223
  1972
                    if curve.get() != "":
dougal2@223
  1973
                        names = list([x[0] for x in ipoob.curveConsts.items()])
dougal2@223
  1974
                        ipotype = luxProp(obj, keyname+".IPOCurveType", "OB_LOCZ")
dougal2@223
  1975
                        luxOption("ipocurve", ipotype, names, "IPO Curve", "Set IPO Curve", gui, 0.6)
dougal2@223
  1976
    
dougal2@223
  1977
                        icu = ipoob[eval("Blender.Ipo.%s" % (ipotype.get()))]
dougal2@223
  1978
                        icu_value = icu[Blender.Get('curframe')]
dougal2@223
  1979
                        if usemapping.get() == "false": # if true is set during mapping below
dougal2@223
  1980
                            lux.set(icu_value)    
dougal2@223
  1981
    
dougal2@223
  1982
                        # Mapping options
dougal2@223
  1983
                        m = gui.getRect(0.3, 1)
dougal2@223
  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)]))
dougal2@223
  1985
                        if usemapping.get() == "true":
dougal2@223
  1986
                            if gui: gui.newline(caption+"IPO:", 8, 0, None, [0.5,0.45,0.35])
dougal2@223
  1987
                            fmin = luxProp(obj, keyname+".IPOCurvefmin", 0.0)
dougal2@223
  1988
                            luxFloatNoIPO("ipofmin", fmin, -100, 100, "fmin", "Map minimum value from Curve", gui, 0.5)
dougal2@223
  1989
                            fmax = luxProp(obj, keyname+".IPOCurvefmax", 1.0)
dougal2@223
  1990
                            luxFloatNoIPO("ipofmax", fmax, -100, 100, "fmax", "Map maximum value from Curve", gui, 0.5)
dougal2@223
  1991
                            tmin = luxProp(obj, keyname+".IPOCurvetmin", min)
dougal2@223
  1992
                            luxFloatNoIPO("ipotmin", tmin, min, max, "tmin", "Map miminum value to", gui, 0.5)
dougal2@223
  1993
                            tmax = luxProp(obj, keyname+".IPOCurvetmax", max)
dougal2@223
  1994
                            luxFloatNoIPO("ipotmax", tmax, min, max, "tmax", "Map maximum value to", gui, 0.5)
dougal2@223
  1995
    
dougal2@223
  1996
                            sval = (icu_value - fmin.getFloat()) / (fmax.getFloat() - fmin.getFloat())
dougal2@223
  1997
                            lux.set(tmin.getFloat() + (sval * (tmax.getFloat() - tmin.getFloat())))
dougal2@223
  1998
dougal2@223
  1999
                            # invert
dougal2@223
  2000
                            #v = gui.getRect(0.5, 1)
dougal2@223
  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)]))
dougal2@223
  2002
    else:
dougal2@223
  2003
        if (luxProp(Scene.GetCurrent(), "useparamkeys", "false").get()=="true"):
dougal2@223
  2004
            obj = lux.getobj()
dougal2@223
  2005
            keyname = lux.getname()
dougal2@223
  2006
            useipo = luxProp(obj, keyname+".IPOuse", "false")
dougal2@223
  2007
            if useipo.get() == "true":
dougal2@223
  2008
                curve = luxProp(obj, keyname+".IPOCurveName", "") 
dougal2@223
  2009
                try:
dougal2@223
  2010
                    ipoob = Blender.Ipo.Get(curve.get())
dougal2@223
  2011
                except: 
dougal2@223
  2012
                    curve.set("")
dougal2@223
  2013
                pass
dougal2@223
  2014
                usemapping = luxProp(obj, keyname+".IPOmap", "false")
dougal2@223
  2015
                icu_value = 0
dougal2@223
  2016
                if curve.get() != "":
dougal2@223
  2017
                    names = list([x[0] for x in ipoob.curveConsts.items()])
dougal2@223
  2018
                    ipotype = luxProp(obj, keyname+".IPOCurveType", "OB_LOCZ")
dougal2@223
  2019
    
dougal2@223
  2020
                    icu = ipoob[eval("Blender.Ipo.%s" % (ipotype.get()))]
dougal2@223
  2021
                    icu_value = icu[Blender.Get('curframe')]
dougal2@223
  2022
                    if usemapping.get() == "false": # if true is set during mapping below
dougal2@223
  2023
                        lux.set(icu_value)    
dougal2@223
  2024
    
dougal2@223
  2025
                if usemapping.get() == "true":
dougal2@223
  2026
                    if gui: gui.newline(caption+"IPO:", 8, 0, None, [0.5,0.45,0.35])
dougal2@223
  2027
                    fmin = luxProp(obj, keyname+".IPOCurvefmin", 0.0)
dougal2@223
  2028
                    fmax = luxProp(obj, keyname+".IPOCurvefmax", 1.0)
dougal2@223
  2029
                    tmin = luxProp(obj, keyname+".IPOCurvetmin", min)
dougal2@223
  2030
                    tmax = luxProp(obj, keyname+".IPOCurvetmax", max)
dougal2@223
  2031
                    sval = (icu_value - fmin.getFloat()) / (fmax.getFloat() - fmin.getFloat())
dougal2@223
  2032
                    lux.set(tmin.getFloat() + (sval * (tmax.getFloat() - tmin.getFloat())))
dougal2@223
  2033
dougal2@223
  2034
    return "\n   \"float %s\" [%f]"%(name, lux.getFloat())
radiance29@111
  2035
radiance29@121
  2036
def luxFloatNoIPO(name, lux, min, max, caption, hint, gui, width=1.0, useslider=0):
dougal2@223
  2037
    if gui:
dougal2@223
  2038
        r = gui.getRect(width, 1)
dougal2@223
  2039
        if(useslider==1):
dougal2@223
  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))
dougal2@223
  2041
        else:
dougal2@223
  2042
            Draw.Number(caption+": ", evtLuxGui, r[0], r[1], r[2], r[3], lux.getFloat(), min, max, hint, lambda e,v: lux.set(v))
dougal2@223
  2043
    return "\n   \"float %s\" [%f]"%(name, lux.getFloat())
zuegs@11
  2044
radiance29@111
  2045
radiance29@111
  2046
zuegs@21
  2047
def luxInt(name, lux, min, max, caption, hint, gui, width=1.0):
dougal2@223
  2048
    if gui:
dougal2@223
  2049
        r = gui.getRect(width, 1)
dougal2@223
  2050
        Draw.Number(caption+": ", evtLuxGui, r[0], r[1], r[2], r[3], lux.getInt(), min, max, hint, lambda e,v: lux.set(v))
dougal2@223
  2051
    return "\n   \"integer %s\" [%d]"%(name, lux.getInt())
zuegs@11
  2052
zuegs@21
  2053
def luxBool(name, lux, caption, hint, gui, width=1.0):
dougal2@223
  2054
    if gui:
dougal2@223
  2055
        r = gui.getRect(width, 1)
dougal2@223
  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)]))
dougal2@223
  2057
    return "\n   \"bool %s\" [\"%s\"]"%(name, lux.get())
jromang@0
  2058
radiance29@245
  2059
def luxCollapse(name, lux, caption, hint, gui, width=1.0):
radiance29@245
  2060
    if gui:
dougal2@258
  2061
        r = gui.getRect(width, 1)
dougal2@259
  2062
        if lux.get() == "true":
dougal2@259
  2063
            drawArrow(arrow_down, r[0]-22, r[1]-2)
dougal2@259
  2064
        else:
dougal2@259
  2065
            drawArrow(arrow_right, r[0]-22, r[1]-2)
dougal2@258
  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)]))
radiance29@245
  2067
    return "\n   \"bool %s\" [\"%s\"]"%(name, lux.get())
radiance29@245
  2068
zuegs@21
  2069
def luxString(name, lux, caption, hint, gui, width=1.0):
dougal2@223
  2070
    if gui:
dougal2@223
  2071
        r = gui.getRect(width, 1)
dougal2@223
  2072
        Draw.String(caption+": ", evtLuxGui, r[0], r[1], r[2], r[3], lux.get(), 250, hint, lambda e,v: lux.set(v))
dougal2@223
  2073
    if lux.get()==lux.default: return ""
dougal2@223
  2074
    else: return "\n   \"string %s\" [\"%s\"]"%(name, luxstr(lux.get()))
jromang@0
  2075
zuegs@21
  2076
def luxFile(name, lux, caption, hint, gui, width=1.0):
dougal2@223
  2077
    if gui:
dougal2@223
  2078
        r = gui.getRect(width, 1)
dougal2@223
  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))
dougal2@223
  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()))
zuegs@255
  2081
    return "\n   \"string %s\" [\"%s\"]"%(name, luxstr(luxFilePath(lux.get())))
zuegs@11
  2082
zuegs@163
  2083
def luxPath(name, lux, caption, hint, gui, width=1.0):
dougal2@223
  2084
    if gui:
dougal2@223
  2085
        r = gui.getRect(width, 1)
dougal2@223
  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))
dougal2@223
  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()))
dougal2@223
  2088
    return "\n   \"string %s\" [\"%s\"]"%(name, luxstr(lux.get()))
zuegs@163
  2089
zuegs@21
  2090
def luxRGB(name, lux, max, caption, hint, gui, width=2.0):
dougal2@223
  2091
    if gui:
dougal2@223
  2092
        r = gui.getRect(width, 1)
dougal2@223
  2093
        scale = 1.0
dougal2@223
  2094
        rgb = lux.getRGB()
dougal2@223
  2095
        if max > 1.0:
dougal2@223
  2096
            for i in range(3):
dougal2@223
  2097
                if rgb[i] > scale: scale = rgb[i]
dougal2@223
  2098
            rgb = (rgb[0]/scale, rgb[1]/scale, rgb[2]/scale)
dougal2@223
  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)))
dougal2@223
  2100
        w = int((r[2]-r[3])/3); m = max
dougal2@223
  2101
        if max > 1.0:
dougal2@223
  2102
            w = int((r[2]-r[3])/4); m = 1.0
dougal2@223
  2103
        drawR, drawG, drawB, drawS = Draw.Create(rgb[0]), Draw.Create(rgb[1]), Draw.Create(rgb[2]), Draw.Create(scale)
dougal2@223
  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)))
dougal2@223
  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)))
dougal2@223
  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)))
dougal2@223
  2107
        if max > 1.0:
dougal2@223
  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)))
dougal2@223
  2109
    if max <= 1.0:
dougal2@223
  2110
        return "\n   \"color %s\" [%s]"%(name, lux.getRGC())
dougal2@223
  2111
    return "\n   \"color %s\" [%s]"%(name, lux.get())
zuegs@11
  2112
zuegs@39
  2113
def luxVector(name, lux, min, max, caption, hint, gui, width=2.0):
dougal2@223
  2114
    if gui:
dougal2@223
  2115
        r = gui.getRect(width, 1)
dougal2@223
  2116
        vec = lux.getVector()
dougal2@223
  2117
        w = int(r[2]/3)
dougal2@223
  2118
        drawX, drawY, drawZ = Draw.Create(vec[0]), Draw.Create(vec[1]), Draw.Create(vec[2])
dougal2@223
  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)))
dougal2@223
  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)))
dougal2@223
  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)))
dougal2@223
  2122
    return "\n   \"vector %s\" [%s]"%(name, lux.get())
zuegs@39
  2123
zuegs@200
  2124
def luxVectorUniform(name, lux, min, max, caption, hint, gui, width=2.0):
dougal2@223
  2125
    def setUniform(lux, value):
dougal2@223
  2126
        if value: lux.set(lux.getFloat())
dougal2@223
  2127
        else: lux.setVector(lux.getVector())
dougal2@223
  2128
    if gui:
dougal2@223
  2129
        r = gui.getRect(width, 1)
dougal2@223
  2130
        vec = lux.getVector()
dougal2@223
  2131
        Draw.Toggle("U", evtLuxGui, r[0], r[1], gui.h, gui.h, lux.isFloat(), "uniform", lambda e,v: setUniform(lux, v))
dougal2@223
  2132
        if lux.isFloat():
dougal2@223
  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))
dougal2@223
  2134
        else:
dougal2@223
  2135
            w = int((r[2]-gui.h)/3)
dougal2@223
  2136
            drawX, drawY, drawZ = Draw.Create(vec[0]), Draw.Create(vec[1]), Draw.Create(vec[2])
dougal2@223
  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)))
dougal2@223
  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)))
dougal2@223
  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)))
dougal2@223
  2140
    return "\n   \"vector %s\" [%s]"%(name, lux.getVectorStr())
jromang@0
  2141
jromang@0
  2142
zuegs@21
  2143
# lux individual identifiers
zuegs@21
  2144
def luxCamera(cam, context, gui=None):
dougal2@223
  2145
    global icon_c_camera
dougal2@223
  2146
    str = ""
dougal2@223
  2147
    if cam:
dougal2@223
  2148
        camtype = luxProp(cam, "camera.type", "perspective")
dougal2@260
  2149
        # Radiance - remarked 'realistic' for v0.6 release
radiance29@243
  2150
        #str = luxIdentifier("Camera", camtype, ["perspective","orthographic","environment","realistic"], "CAMERA", "select camera type", gui, icon_c_camera)
radiance29@243
  2151
        str = luxIdentifier("Camera", camtype, ["perspective","orthographic","environment"], "CAMERA", "select camera type", gui, icon_c_camera)
dougal2@223
  2152
        scale = 1.0
dougal2@223
  2153
        if camtype.get() == "perspective":
dougal2@223
  2154
            if gui: gui.newline("  View:")
dougal2@223
  2155
            str += luxFloat("fov", luxAttr(cam, "angle"), 8.0, 170.0, "fov", "camera field-of-view angle", gui)
dougal2@223
  2156
            fl = luxAttr(cam, "lens")
dougal2@223
  2157
            if gui:
dougal2@223
  2158
                luxFloat("lens", fl, 1.0, 250.0, "focallength", "camera focal length", gui)
dougal2@223
  2159
            
dougal2@223
  2160
        if camtype.get() == "orthographic" :
dougal2@223
  2161
            str += luxFloat("scale", luxAttr(cam, "scale"), 0.01, 1000.0, "scale", "orthographic camera scale", gui)
dougal2@223
  2162
            scale = cam.scale / 2
dougal2@223
  2163
        if camtype.get() == "realistic":
dougal2@223
  2164
            
dougal2@223
  2165
            if gui: gui.newline("  View:")
dougal2@223
  2166
            fov = luxAttr(cam, "angle")
dougal2@223
  2167
            str += luxFloat("fov", fov, 8.0, 170.0, "fov", "camera field-of-view angle", gui)
dougal2@223
  2168
            if gui: luxFloat("lens", luxAttr(cam, "lens"), 1.0, 250.0, "focallength", "camera focal length", gui)
dougal2@223
  2169
            
dougal2@223
  2170
            
dougal2@223
  2171
            if gui: gui.newline()
dougal2@223
  2172
            str += luxFile("specfile", luxProp(cam, "camera.realistic.specfile", ""), "spec-file", "", gui, 1.0)
dougal2@223
  2173
#            if gui: gui.newline()
dougal2@223
  2174
# auto calc        str += luxFloat("filmdistance", luxProp(cam, "camera.realistic.filmdistance", 70.0), 0.1, 1000.0, "film-dist", "film-distance [mm]", gui)
dougal2@223
  2175
            filmdiag = luxProp(cam, "camera.realistic.filmdiag", 35.0)
dougal2@223
  2176
            str += luxFloat("filmdiag", filmdiag, 0.1, 1000.0, "film-diag", "[mm]", gui)
dougal2@223
  2177
            if gui: gui.newline()
dougal2@223
  2178
            fstop = luxProp(cam, "camera.realistic.fstop", 1.0)
dougal2@223
  2179
            luxFloat("aperture_diameter", fstop, 0.1, 100.0, "f-stop", "", gui)
dougal2@223
  2180
            dofdist = luxAttr(cam, "dofDist")
dougal2@223
  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)
dougal2@223
  2182
            if gui:
dougal2@223
  2183
                Draw.Button("S", evtLuxGui, gui.x, gui.y-gui.h, gui.h, gui.h, "focus selected object", lambda e,v:setFocus("S"))
dougal2@223
  2184
                Draw.Button("C", evtLuxGui, gui.x+gui.h, gui.y-gui.h, gui.h, gui.h, "focus cursor", lambda e,v:setFocus("C"))
dougal2@223
  2185
            focal = filmdiag.get()*0.001 / math.tan(fov.get() * math.pi / 360.0) / 2.0
dougal2@223
  2186
            print "calculated focal length: %f mm"%(focal * 1000.0)
dougal2@223
  2187
            aperture_diameter = focal / fstop.get()
dougal2@223
  2188
            print "calculated aperture diameter: %f mm"%(aperture_diameter * 1000.0)
dougal2@223
  2189
            str += "\n   \"float aperture_diameter\" [%f]"%(aperture_diameter*1000.0)
dougal2@223
  2190
            filmdistance = dofdist.get() * focal / (dofdist.get() - focal)
dougal2@223
  2191
            print "calculated film distance: %f mm"%(filmdistance * 1000.0)
dougal2@223
  2192
            str += "\n   \"float filmdistance\" [%f]"%(filmdistance*1000.0)
dougal2@223
  2193
dougal2@223
  2194
        # Clipping
dougal2@223
  2195
        useclip = luxProp(cam, "useclip", "false")
radiance29@245
  2196
        luxCollapse("useclip", useclip, "Near & Far Clipping", "Enable Camera near and far clipping options", gui, 2.0)
dougal2@223
  2197
        if(useclip.get() == "true"):
dougal2@223
  2198
            if gui: gui.newline("  Clipping:")
dougal2@223
  2199
            str += luxFloat("hither", luxAttr(cam, "clipStart"), 0.0, 100.0, "start", "near clip distance", gui)
dougal2@223
  2200
            str += luxFloat("yon", luxAttr(cam, "clipEnd"), 1.0, 10000.0, "end", "far clip distance", gui)
dougal2@223
  2201
dougal2@223
  2202
        # Depth of Field
dougal2@223
  2203
        usedof = luxProp(cam, "usedof", "false")
dougal2@223
  2204
        
dougal2@223
  2205
        if camtype.get() in ["perspective", "orthographic"]:
radiance29@245
  2206
            luxCollapse("usedof", usedof, "Depth of Field & Bokeh", "Enable Depth of Field & Aperture options", gui, 2.0)
dougal2@223
  2207
            
dougal2@223
  2208
            
dougal2@223
  2209
            if usedof.get() == "true":
dougal2@223
  2210
                
dougal2@223
  2211
                if gui: gui.newline("  DOF:")
dougal2@223
  2212
                
dougal2@223
  2213
                lr = luxProp(cam, "camera.lensradius", 0.01)
dougal2@223
  2214
                fs = luxProp(cam, "camera.fstop", 2.8)
dougal2@223
  2215
                
dougal2@223
  2216
                if camtype.get() == "perspective":
dougal2@223
  2217
                    
dougal2@223
  2218
                    usefstop = luxProp(cam, "usefstop", "false")
dougal2@223
  2219
                    luxBool("usefstop", usefstop, "Use f/stop", "Use f/stop to define DOF effect", gui, 1.0)
dougal2@223
  2220
                    
dougal2@223
  2221
                    LR_SCALE = 1000.0       # lr in metres -> mm
dougal2@223
  2222
                    FL_SCALE = 1.0          # fl in mm -> mm
dougal2@223
  2223
                    
dougal2@223
  2224
                    def lr_2_fs(fl, lr):
dougal2@223
  2225
                        lr += 0.00000001
dougal2@223
  2226
                        return fl / ( 2.0 * lr )
dougal2@223
  2227
                    
dougal2@223
  2228
                    def fs_2_lr(fl, fs):
dougal2@223
  2229
                        return fl / ( 2.0 * fs )
dougal2@223
  2230
                    
dougal2@223
  2231
                    if usefstop.get() == 'true':
dougal2@223
  2232
                        lr.set(fs_2_lr(fl.get() * FL_SCALE, fs.get()) / LR_SCALE)
dougal2@223
  2233
                        luxFloat("fstop", fs, 0.9, 64.0, "fstop", "Defines the lens aperture.", gui)
dougal2@223
  2234
                        str += luxFloat("lensradius", lr, 0.0, 1.0, "", "", None)
dougal2@223
  2235
                    else:
dougal2@223
  2236
                        fs.set(lr_2_fs(fl.get() * FL_SCALE, lr.get() * LR_SCALE))
dougal2@223
  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)
dougal2@223
  2238
                else:
dougal2@223
  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)
dougal2@223
  2240
                
dougal2@223
  2241
                focustype = luxProp(cam, "camera.focustype", "autofocus")
dougal2@223
  2242
                luxOption("focustype", focustype, ["autofocus", "manual", "object"], "Focus Type", "Choose the focus behaviour", gui)
dougal2@223
  2243
                
dougal2@223
  2244
    
dougal2@223
  2245
                if focustype.get() == "autofocus":
dougal2@223
  2246
                    str += luxBool("autofocus",luxProp(cam, "camera.autofocus", "true"), "autofocus", "Enable automatic focus", gui)
dougal2@223
  2247
                if focustype.get() == "object":
dougal2@223
  2248
                    objectfocus = luxProp(cam, "camera.objectfocus", "")
dougal2@223
  2249
                    luxString("objectfocus", objectfocus, "object", "Always focus camera on named object", gui, 1.0)
dougal2@223
  2250
                    dofdist = luxAttr(cam, "dofDist")
dougal2@223
  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)
dougal2@223
  2252
                    if objectfocus.get() != "":
dougal2@223
  2253
                        setFocus(objectfocus.get())
dougal2@223
  2254
                if focustype.get() == "manual":
dougal2@223
  2255
                    dofdist = luxAttr(cam, "dofDist")
dougal2@223
  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)
dougal2@223
  2257
                    if gui:
dougal2@223
  2258
                        Draw.Button("S", evtLuxGui, gui.x, gui.y-gui.h, gui.h, gui.h, "focus selected object", lambda e,v:setFocus("S"))
dougal2@223
  2259
                        Draw.Button("C", evtLuxGui, gui.x+gui.h, gui.y-gui.h, gui.h, gui.h, "focus cursor", lambda e,v:setFocus("C"))
dougal2@223
  2260
dougal2@223
  2261
        if camtype.get() == "perspective" and usedof.get() == "true":
dougal2@223
  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)
dougal2@223
  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)
dougal2@223
  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)
dougal2@223
  2265
dougal2@223
  2266
        useaspect = luxProp(cam, "useaspectratio", "false")
dougal2@223
  2267
        aspectratio = luxProp(cam, "ratio", 1.3333)
dougal2@223
  2268
        if camtype.get() in ["perspective", "orthographic"]:
dougal2@223
  2269
            useshift = luxProp(cam, "camera.useshift", "false")
radiance29@245
  2270
            luxCollapse("useshift", useshift, "Architectural (Lens Shift) & Aspect Ratio", "Enable Lens Shift and Aspect Ratio options", gui, 2.0)
dougal2@223
  2271
            if(useshift.get() == "true"):
dougal2@223
  2272
                if gui: gui.newline("  Shift:")
dougal2@223
  2273
                luxFloat("X", luxAttr(cam, "shiftX"), -2.0, 2.0, "X", "horizontal lens shift", gui)
dougal2@223
  2274
                luxFloat("Y", luxAttr(cam, "shiftY"), -2.0, 2.0, "Y", "vertical lens shift", gui)
dougal2@223
  2275
dougal2@223
  2276
                if gui: gui.newline("  AspectRatio:")
dougal2@223
  2277
                luxBool("useaspectratio", useaspect, "Custom", "Define a custom frame aspect ratio", gui)
dougal2@223
  2278
                if useaspect.get() == "true":
dougal2@223
  2279
                    str += luxFloat("frameaspectratio", aspectratio, 0.0001, 3.0, "aspectratio", "Frame aspect ratio", gui)
dougal2@223
  2280
            if context:
dougal2@223
  2281
                if useaspect.get() == "true":
dougal2@223
  2282
                    ratio = 1./aspectratio.get()
dougal2@223
  2283
                else:
dougal2@223
  2284
                        ratio = float(context.sizeY)/float(context.sizeX)
dougal2@223
  2285
                if ratio < 1.0:
dougal2@223
  2286
                    screenwindow = [(2*cam.shiftX-1)*scale, (2*cam.shiftX+1)*scale, (2*cam.shiftY-ratio)*scale, (2*cam.shiftY+ratio)*scale]
dougal2@223
  2287
                else:
dougal2@223
  2288
                    screenwindow = [(2*cam.shiftX-1/ratio)*scale, (2*cam.shiftX+1/ratio)*scale, (2*cam.shiftY-1)*scale, (2*cam.shiftY+1)*scale]
dougal2@223
  2289
                # render region option
dougal2@223
  2290
                if context.borderRender:
dougal2@223
  2291
                    (x1,y1,x2,y2) = context.border
dougal2@223
  2292
                    screenwindow = [screenwindow[0]*(1-x1)+screenwindow[1]*x1, screenwindow[0]*(1-x2)+screenwindow[1]*x2,\
dougal2@223
  2293
                            screenwindow[2]*(1-y1)+screenwindow[3]*y1, screenwindow[2]*(1-y2)+screenwindow[3]*y2]
dougal2@223
  2294
                str += "\n   \"float screenwindow\" [%f %f %f %f]"%(screenwindow[0], screenwindow[1], screenwindow[2], screenwindow[3])
dougal2@223
  2295
dougal2@223
  2296
        # Note - radiance - this is a work in progress
dougal2@223
  2297
        # Flash lamp option for perspective and ortho cams
dougal2@223
  2298
#        if camtype.get() in ["perspective", "orthographic"]:
dougal2@223
  2299
#            useflash = luxProp(cam, "useflash", "false")
dougal2@223
  2300
#            luxBool("useflash", useflash, "Flash Lamp", "Enable Camera mounted flash lamp options", gui, 2.0)
dougal2@223
  2301
dougal2@223
  2302
        # Motion Blur Options (common to all cameras)
dougal2@223
  2303
        usemblur = luxProp(cam, "usemblur", "false")
radiance29@245
  2304
        luxCollapse("usemblur", usemblur, "Motion Blur", "Enable Motion Blur", gui, 2.0)
dougal2@223
  2305
        if(usemblur.get() == "true"):    
dougal2@223
  2306
            if gui: gui.newline("  Shutter:")
dougal2@223
  2307
            mblurpreset = luxProp(cam, "mblurpreset", "true")
dougal2@223
  2308
            luxBool("mblurpreset", mblurpreset, "Preset", "Enable use of Shutter Presets", gui, 0.4)
dougal2@223
  2309
            if(mblurpreset.get() == "true"):
dougal2@223
  2310
                shutterpresets = ["full frame", "half frame", "quarter frame", "1/25", "1/30", "1/45", "1/60", "1/85", "1/125", "1/250", "1/500"]        
dougal2@223
  2311
                shutterpreset = luxProp(cam, "camera.shutterspeedpreset", "full frame")
dougal2@223
  2312
                luxOption("shutterpreset", shutterpreset, shutterpresets, "shutterspeed", "Choose the Shutter speed preset.", gui, 1.0)
dougal2@223
  2313
dougal2@223
  2314
                fpspresets = ["10 FPS", "12 FPS", "20 FPS", "25 FPS", "29.99 FPS", "30 FPS", "50 FPS", "60 FPS"]
dougal2@223
  2315
                shutfps = luxProp(cam, "camera.shutfps", "25 FPS")
dougal2@223
  2316
                luxOption("shutfps", shutfps, fpspresets, "@", "Choose the number of frames per second as the time base.", gui, 0.6)
dougal2@223
  2317
dougal2@223
  2318
                sfps = shutfps.get()
dougal2@223
  2319
                fps = 25
dougal2@223
  2320
                if sfps == "10 FPS": fps = 10
dougal2@223
  2321
                elif sfps == "12 FPS": fps = 12
dougal2@223
  2322
                elif sfps == "20 FPS": fps = 20
dougal2@223
  2323
                elif sfps == "25 FPS": fps = 25
dougal2@223
  2324
                elif sfps == "29.99 FPS": fps = 29.99
dougal2@223
  2325
                elif sfps == "30 FPS": fps = 30
dougal2@223
  2326
                elif sfps == "50 FPS": fps = 50
dougal2@223
  2327
                elif sfps == "60 FPS": fps = 60
dougal2@223
  2328
dougal2@223
  2329
                spre = shutterpreset.get()
dougal2@223
  2330
                open = 0.0
dougal2@223
  2331
                close = 1.0
dougal2@223
  2332
                if spre == "full frame": close = 1.0
dougal2@223
  2333
                elif spre == "half frame": close = 0.5
dougal2@223
  2334
                elif spre == "quarter frame": close = 0.25
dougal2@223
  2335
                elif spre == "1/25": close = 1.0 / 25.0 * fps
dougal2@223
  2336
                elif spre == "1/30": close = 1.0 / 30.0 * fps
dougal2@223
  2337
                elif spre == "1/45": close = 1.0 / 45.0 * fps
dougal2@223
  2338
                elif spre == "1/60": close = 1.0 / 60.0 * fps
dougal2@223
  2339
                elif spre == "1/85": close = 1.0 / 85.0 * fps
dougal2@223
  2340
                elif spre == "1/125": close = 1.0 / 125.0 * fps
dougal2@223
  2341
                elif spre == "1/250": close = 1.0 / 250.0 * fps
dougal2@223
  2342
                elif spre == "1/500": close = 1.0 / 500.0 * fps
dougal2@223
  2343
dougal2@223
  2344
                str += "\n   \"float shutteropen\" [%f]\n   \"float shutterclose\" [%f] "%(open,close)
dougal2@223
  2345
dougal2@223
  2346
            else:
dougal2@223
  2347
                str += luxFloat("shutteropen", luxProp(cam, "camera.shutteropen", 0.0), 0.0, 100.0, "open", "time in seconds when shutter opens", gui, 0.8)
dougal2@223
  2348
                str += luxFloat("shutterclose", luxProp(cam, "camera.shutterclose", 1.0), 0.0, 100.0, "close", "time in seconds when shutter closes", gui, 0.8)
dougal2@223
  2349
dougal2@223
  2350
            str += luxOption("shutterdistribution", luxProp(cam, "camera.shutterdistribution", "uniform"), ["uniform", "gaussian"], "distribution", "Choose the shutter sampling distribution.", gui, 2.0)
dougal2@223
  2351
            objectmblur = luxProp(cam, "objectmblur", "true")
dougal2@223
  2352
            luxBool("objectmblur", objectmblur, "Object", "Enable Motion Blur for scene object motions", gui, 1.0)
dougal2@223
  2353
            cammblur = luxProp(cam, "cammblur", "true")
dougal2@223
  2354
            luxBool("cammblur", cammblur, "Camera", "Enable Motion Blur for Camera motion", gui, 1.0)
dougal2@223
  2355
    return str
jromang@0
  2356
zuegs@31
  2357
zuegs@21
  2358
def luxFilm(scn, gui=None):
dougal2@223
  2359
    str = ""
dougal2@223
  2360
    if scn:
dougal2@223
  2361
        filmtype = luxProp(scn, "film.type", "fleximage")
dougal2@223
  2362
        str = luxIdentifier("Film", filmtype, ["fleximage"], "FILM", "select film type", gui)
dougal2@223
  2363
        if filmtype.get() == "fleximage":
dougal2@223
  2364
            context = scn.getRenderingContext()
dougal2@223
  2365
            if context:
dougal2@223
  2366
                if gui: gui.newline("  Resolution:")
dougal2@223
  2367
                luxInt("xresolution", luxAttr(context, "sizeX"), 0, 8192, "X", "width of the render", gui, 0.666)
dougal2@223
  2368
                luxInt("yresolution", luxAttr(context, "sizeY"), 0, 8192, "Y", "height of the render", gui, 0.666)
dougal2@223
  2369
                scale = luxProp(scn, "film.scale", "100 %")
radiance29@245
  2370
                luxOption("", scale, ["400 %", "200 %", "100 %", "75 %", "50 %", "25 %"], "scale", "scale resolution", gui, 0.666)
dougal2@223
  2371
                scale = int(scale.get()[:-1])
dougal2@223
  2372
                # render region option
dougal2@223
  2373
                if context.borderRender:
dougal2@223
  2374
                    (x1,y1,x2,y2) = context.border
dougal2@223
  2375
                    if (x1==x2) and (y1==y2): print "WARNING: empty render-region, use SHIFT-B to set render region in Blender."
dougal2@223
  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))
dougal2@223
  2377
                else:
dougal2@223
  2378
                    str += "\n   \"integer xresolution\" [%d] \n   \"integer yresolution\" [%d]"%(luxAttr(context, "sizeX").get()*scale/100, luxAttr(context, "sizeY").get()*scale/100)
dougal2@223
  2379
dougal2@223
  2380
            if gui: gui.newline("  Halt:")
dougal2@223
  2381
            str += luxInt("haltspp", luxProp(scn, "haltspp", 0), 0, 32768, "haltspp", "Stop rendering after specified amount of samples per pixel / 0 = never halt", gui)
radiance29@245
  2382
            palpha = luxProp(scn, "film.premultiplyalpha", "false")
dougal2@223
  2383
            str += luxBool("premultiplyalpha", palpha, "premultiplyalpha", "Pre multiply film alpha channel during normalization", gui)
dougal2@223
  2384
    
dougal2@223
  2385
            if gui: gui.newline("  Tonemap:")
dougal2@223
  2386
            tonemapkernel =    luxProp(scn, "film.tonemapkernel", "reinhard")
dougal2@223
  2387
            str += luxOption("tonemapkernel", tonemapkernel, ["reinhard", "linear", "contrast", "maxwhite"], "Tonemapping Kernel", "Select the tonemapping kernel to use", gui, 2.0)
dougal2@223
  2388
            if tonemapkernel.get() == "reinhard":
dougal2@223
  2389
                autoywa = luxProp(scn, "film.reinhard.autoywa", "true")
radiance@319
  2390
                #str += luxBool("reinhard_autoywa", autoywa, "auto Ywa", "Automatically determine World Adaption Luminance", gui)
dougal2@223
  2391
                if autoywa.get() == "false":
dougal2@223
  2392
                    str += luxFloat("reinhard_ywa", luxProp(scn, "film.reinhard.ywa", 0.1), 0.001, 1.0, "Ywa", "Display/World Adaption Luminance", gui)
dougal2@223
  2393
                str += luxFloat("reinhard_prescale", luxProp(scn, "film.reinhard.prescale", 1.0), 0.0, 10.0, "preScale", "Image scale before tonemap operator", gui)
dougal2@223
  2394
                str += luxFloat("reinhard_postscale", luxProp(scn, "film.reinhard.postscale", 1.2), 0.0, 10.0, "postScale", "Image scale after tonemap operator", gui)
dougal2@223
  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)
dougal2@223
  2396
            elif tonemapkernel.get() == "linear":
tomb@251
  2397
                str += luxFloat("linear_sensitivity", luxProp(scn, "film.linear.sensitivity", 50.0), 0.0, 1000.0, "sensitivity", "Adaption/Sensitivity", gui)
dougal2@223
  2398
                str += luxFloat("linear_exposure", luxProp(scn, "film.linear.exposure", 1.0), 0.001, 1.0, "exposure", "Exposure duration in seconds", gui)
dougal2@223
  2399
                str += luxFloat("linear_fstop", luxProp(scn, "film.linear.fstop", 2.8), 0.1, 64.0, "Fstop", "F-Stop", gui)
dougal2@223
  2400
                str += luxFloat("linear_gamma", luxProp(scn, "film.linear.gamma", 1.0), 0.0, 8.0, "gamma", "Tonemap operator gamma correction", gui)
dougal2@223
  2401
            elif tonemapkernel.get() == "contrast":
dougal2@223
  2402
                str += luxFloat("contrast_ywa", luxProp(scn, "film.contrast.ywa", 0.1), 0.001, 1.0, "Ywa", "Display/World Adaption Luminance", gui)
dougal2@223
  2403
dougal2@223
  2404
            if gui: gui.newline("  Display:")
dougal2@223
  2405
            str += luxInt("displayinterval", luxProp(scn, "film.displayinterval", 12), 4, 3600, "interval", "Set display Interval (seconds)", gui)
dougal2@223
  2406
            
dougal2@223
  2407
            if gui: gui.newline("  Write:")
dougal2@223
  2408
            str += luxInt("writeinterval", luxProp(scn, "film.writeinterval", 120), 12, 3600, "interval", "Set display Interval (seconds)", gui)
dougal2@223
  2409
dougal2@258
  2410
        # Image File Outputs
dougal2@258
  2411
dougal2@258
  2412
        # LDR clamping method
dougal2@258
  2413
        if gui: gui.newline("  Clamping:")
dougal2@258
  2414
        ldrclampmethod = luxProp(scn, "film.ldr_clamp_method", "lum")
dougal2@258
  2415
        str += luxOption("ldr_clamp_method", ldrclampmethod, ["lum", "hue", "cut"], "LDR clamping", "Method to clamp high luminance values for LDR output", gui, 0.5)
dougal2@258
  2416
        if gui: gui.newline()
dougal2@258
  2417
dougal2@258
  2418
        # OpenEXR Output
dougal2@258
  2419
        saveexr = luxProp(scn, "film.write_exr", "false")
dougal2@258
  2420
        str += luxCollapse("write_exr", saveexr, "OpenEXR Output", "Enable OpenEXR output", gui, 2.0)
dougal2@258
  2421
dougal2@258
  2422
        if saveexr.get() == "true":
dougal2@258
  2423
            if gui: gui.newline("  OpenEXR:")
dougal2@258
  2424
dougal2@258
  2425
            exrchannels = luxProp(scn, "film.write_exr_channels", "RGBA")
dougal2@258
  2426
            str += luxOption("write_exr_channels", exrchannels, ["Y", "YA", "RGB", "RGBA"], "Channels", "Select channels type to write", gui, 0.5)
dougal2@258
  2427
            exrres = luxProp(scn, "film.write_exr_halftype", "true")
dougal2@258
  2428
            str += luxBool("write_exr_halftype", exrres, "16bit Half", "Enable 16bit Half resolution output, otherwise 32bit float", gui, 0.5)
dougal2@258
  2429
            exrcompression = luxProp(scn, "film.write_exr_compression", "PIZ (lossless)")
dougal2@258
  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)
dougal2@258
  2431
dougal2@258
  2432
            exrimaging = luxProp(scn, "film.write_exr_imaging", "true")
dougal2@258
  2433
            str += luxBool("write_exr_applyimaging", exrimaging, "Apply Imaging/Tonemapping", "Apply Imaging and Tonemapping pipeline", gui, 1.2)
dougal2@259
  2434
        
dougal2@259
  2435
            if exrimaging.get()=="true":
dougal2@259
  2436
                exrgamutclamp = luxProp(scn, "film.write_exr_gamutclamp", "true")
dougal2@259
  2437
                str += luxBool("write_exr_gamutclamp", exrgamutclamp, "Gamut Clamp", "Clamp out of gamut (bright) pixel values", gui, 0.8)
dougal2@259
  2438
dougal2@259
  2439
            if gui: gui.newline()
dougal2@259
  2440
            # Zbuf output
dougal2@259
  2441
            exrZ = luxProp(scn, "film.write_exr_Z", "true")
dougal2@259
  2442
            str += luxBool("write_exr_ZBuf", exrZ, "ZBuf", "Enable Z Depth Buffer channel", gui, 0.8)
dougal2@259
  2443
            if exrZ.get() == "true":
dougal2@259
  2444
                exrZNormalize = luxProp(scn, "film.write_exr_ZNorm", "None")
dougal2@259
  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)
dougal2@258
  2446
dougal2@258
  2447
        # PNG Output
dougal2@258
  2448
        savepng = luxProp(scn, "film.write_png", "true")
dougal2@258
  2449
        str += luxCollapse("write_png", savepng, "PNG Output", "Enable PNG (Portable Network Graphics) output", gui, 2.0)
dougal2@258
  2450
dougal2@258
  2451
        if savepng.get() == "true":
dougal2@258
  2452
            if gui: gui.newline("  PNG:")
dougal2@258
  2453
            pngchannels = luxProp(scn, "film.write_png_channels", "RGB")
dougal2@258
  2454
            str += luxOption("write_png_channels", pngchannels, ["Y", "YA", "RGB", "RGBA"], "Channels", "Select channels type to write", gui, 0.5)
dougal2@258
  2455
            png16bit = luxProp(scn, "film.write_png_16bit", "false")
dougal2@258
  2456
            str += luxBool("write_png_16bit", png16bit, "16bit", "Enable 16bits per channel resolution PNG output", gui, 0.5)
dougal2@258
  2457
            pnggamutclamp = luxProp(scn, "film.write_png_gamutclamp", "true")
dougal2@258
  2458
            str += luxBool("write_png_gamutclamp", pnggamutclamp, "Gamut Clamp", "Clamp out of gamut (bright) pixel values", gui, 1.0)
dougal2@258
  2459
dougal2@258
  2460
        # Zbuf output
dougal2@258
  2461
        #pngZ = luxProp(scn, "film.write_png_ZBuf", "false")
dougal2@258
  2462
        #str += luxBool("write_png_ZBuf", pngZ, "ZBuf (Separate)", "Enable Z Depth Buffer channel", gui, 0.8)
dougal2@258
  2463
        #if pngZ.get() == "true":
dougal2@258
  2464
        #    pngZNormalize = luxProp(scn, "film.write_png_ZNorm", "Min/Max")
dougal2@258
  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)
dougal2@258
  2466
dougal2@258
  2467
        # TGA Output
dougal2@258
  2468
        savetga = luxProp(scn, "film.write_tga", "false")
dougal2@258
  2469
        str += luxCollapse("write_tga", savetga, "TGA Output", "Enable TGA output", gui, 2.0)
dougal2@258
  2470
dougal2@258
  2471
        if savetga.get() == "true":
dougal2@258
  2472
            if gui: gui.newline("  TGA:")
dougal2@258
  2473
            tgachannels = luxProp(scn, "film.write_tga_channels", "RGB")
dougal2@258
  2474
            str += luxOption("write_tga_channels", tgachannels, ["Y", "RGB", "RGBA"], "Channels", "Select channels type to write", gui, 0.5)
dougal2@258
  2475
            tgagamutclamp = luxProp(scn, "film.write_tga_gamutclamp", "true")
dougal2@258
  2476
            str += luxBool("write_tga_gamutclamp", tgagamutclamp, "Gamut Clamp", "Clamp out of gamut (bright) pixel values", gui, 1.5)
dougal2@258
  2477
dougal2@258
  2478
        # Zbuf output
dougal2@258
  2479
        #tgaZ = luxProp(scn, "film.write_tga_ZBuf", "false")
dougal2@258
  2480
        #str += luxBool("write_tga_ZBuf", tgaZ, "ZBuf (Separate)", "Enable Z Depth Buffer channel", gui, 0.8)
dougal2@258
  2481
        #if tgaZ.get() == "true":
dougal2@258
  2482
        #    tgaZNormalize = luxProp(scn, "film.write_tga_ZNorm", "Min/Max")
dougal2@258
  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)
dougal2@258
  2484
dougal2@258
  2485
dougal2@258
  2486
        # override output image dir in case of command line batch mode 
dougal2@258
  2487
        overrideop = luxProp(scn, "overrideoutputpath", "")
dougal2@258
  2488
        if overrideop.get() != "":
dougal2@258
  2489
            filebase = os.path.splitext(os.path.basename(Blender.Get('filename')))[0]
dougal2@258
  2490
            filename = overrideop.get() + "/" + filebase + "-%05d" %  (Blender.Get('curframe'))
dougal2@258
  2491
            str += "\n   \"string filename\" [\"%s\"]"%(filename)
dougal2@258
  2492
        else:
dougal2@258
  2493
            fn = luxProp(scn, "filename", "default-%05d" %  (Blender.Get('curframe')))
dougal2@258
  2494
            str += luxString("filename", fn, "File name", "save file name", None)
dougal2@258
  2495
    
dougal2@258
  2496
        if gui: gui.newline("  Resume:")
dougal2@258
  2497
        resumeflm = luxProp(scn, "film.write_resume_flm", "false")
dougal2@258
  2498
        str += luxBool("write_resume_flm", resumeflm, "Write/Use FLM", "Write a resume fleximage .flm file, or resume rendering if it already exists", gui)
dougal2@258
  2499
        restartflm = luxProp(scn, "film.restart_resume_flm", "true")
dougal2@258
  2500
        str += luxBool("restart_resume_flm", restartflm, "Restart/Erase", "Restart with a black flm, even it a previous flm exists", gui)
dougal2@258
  2501
        if gui: gui.newline("  Reject:")
dougal2@258
  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)
dougal2@258
  2503
        debugmode = luxProp(scn, "film.debug", "false")
dougal2@258
  2504
        str += luxBool("debug", debugmode, "debug", "Turn on debug reporting and switch off reject", gui)
dougal2@258
  2505
    
dougal2@258
  2506
        # Colorspace
dougal2@258
  2507
        if gui: gui.newline("  Colorspace:")
dougal2@258
  2508
    
dougal2@258
  2509
        cspaceusepreset = luxProp(scn, "film.colorspaceusepreset", "true")
dougal2@258
  2510
        luxBool("colorspaceusepreset", cspaceusepreset, "Preset", "Select from a list of predefined presets", gui, 0.4)
dougal2@258
  2511
    
dougal2@258
  2512
        # Default values for 'sRGB - HDTV (ITU-R BT.709-5)'
dougal2@258
  2513
        cspacewhiteX = luxProp(scn, "film.cspacewhiteX", 0.314275)
dougal2@258
  2514
        cspacewhiteY = luxProp(scn, "film.cspacewhiteY", 0.329411)
dougal2@258
  2515
        cspaceredX = luxProp(scn, "film.cspaceredX", 0.63)
dougal2@258
  2516
        cspaceredY = luxProp(scn, "film.cspaceredY", 0.34)
dougal2@258
  2517
        cspacegreenX = luxProp(scn, "film.cspacegreenX", 0.31)
dougal2@258
  2518
        cspacegreenY = luxProp(scn, "film.cspacegreenY", 0.595)
dougal2@258
  2519
        cspaceblueX = luxProp(scn, "film.cspaceblueX", 0.155)
dougal2@258
  2520
        cspaceblueY = luxProp(scn, "film.cspaceblueY", 0.07)
dougal2@258
  2521
        gamma = luxProp(scn, "film.gamma", 2.2)
dougal2@258
  2522
    
dougal2@258
  2523
        if(cspaceusepreset.get() == "true"):
dougal2@258
  2524
            # preset controls
dougal2@258
  2525
            cspace = luxProp(scn, "film.colorspace", "sRGB - HDTV (ITU-R BT.709-5)")
dougal2@258
  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"]
dougal2@258
  2527
            luxOption("colorspace", cspace, cspaces, "Colorspace", "select output working colorspace", gui, 1.6)
dougal2@258
  2528
    
dougal2@258
  2529
            if cspace.get()=="ROMM RGB":
dougal2@258
  2530
                cspacewhiteX.set(0.346); cspacewhiteY.set(0.359) # D50
dougal2@258
  2531
                cspaceredX.set(0.7347); cspaceredY.set(0.2653)
dougal2@258
  2532
                cspacegreenX.set(0.1596); cspacegreenY.set(0.8404)
dougal2@258
  2533
                cspaceblueX.set(0.0366); cspaceblueY.set(0.0001)
dougal2@258
  2534
            elif cspace.get()=="Adobe RGB 98":
dougal2@258
  2535
                cspacewhiteX.set(0.313); cspacewhiteY.set(0.329) # D65
dougal2@258
  2536
                cspaceredX.set(0.64); cspaceredY.set(0.34)
dougal2@258
  2537
                cspacegreenX.set(0.21); cspacegreenY.set(0.71)
dougal2@258
  2538
                cspaceblueX.set(0.15); cspaceblueY.set(0.06)
dougal2@258
  2539
            elif cspace.get()=="Apple RGB":
dougal2@258
  2540
                cspacewhiteX.set(0.313); cspacewhiteY.set(0.329) # D65
dougal2@258
  2541
                cspaceredX.set(0.625); cspaceredY.set(0.34)
dougal2@258
  2542
                cspacegreenX.set(0.28); cspacegreenY.set(0.595)
dougal2@258
  2543
                cspaceblueX.set(0.155); cspaceblueY.set(0.07)
dougal2@258
  2544
            elif cspace.get()=="NTSC (FCC 1953, ITU-R BT.470-2 System M)":
dougal2@258
  2545
                cspacewhiteX.set(0.310); cspacewhiteY.set(0.316) # C
dougal2@258
  2546
                cspaceredX.set(0.67); cspaceredY.set(0.33)
dougal2@258
  2547
                cspacegreenX.set(0.21); cspacegreenY.set(0.71)
dougal2@258
  2548
                cspaceblueX.set(0.14); cspaceblueY.set(0.08)
dougal2@258
  2549
            elif cspace.get()=="NTSC (1979) (SMPTE C, SMPTE-RP 145)":
dougal2@258
  2550
                cspacewhiteX.set(0.313); cspacewhiteY.set(0.329) # D65
dougal2@258
  2551
                cspaceredX.set(0.63); cspaceredY.set(0.34)
dougal2@258
  2552
                cspacegreenX.set(0.31); cspacegreenY.set(0.595)
dougal2@258
  2553
                cspaceblueX.set(0.155); cspaceblueY.set(0.07)
dougal2@258
  2554
            elif cspace.get()=="PAL/SECAM (EBU 3213, ITU-R BT.470-6)":
dougal2@258
  2555
                cspacewhiteX.set(0.313); cspacewhiteY.set(0.329) # D65
dougal2@258
  2556
                cspaceredX.set(0.64); cspaceredY.set(0.33)
dougal2@258
  2557
                cspacegreenX.set(0.29); cspacegreenY.set(0.60)
dougal2@258
  2558
                cspaceblueX.set(0.15); cspaceblueY.set(0.06)
dougal2@258
  2559
            elif cspace.get()=="CIE (1931) E":
dougal2@258
  2560
                cspacewhiteX.set(0.333); cspacewhiteY.set(0.333) # E
dougal2@258
  2561
                cspaceredX.set(0.7347); cspaceredY.set(0.2653)
dougal2@258
  2562
                cspacegreenX.set(0.2738); cspacegreenY.set(0.7174)
dougal2@258
  2563
                cspaceblueX.set(0.1666); cspaceblueY.set(0.0089)
dougal2@258
  2564
    
dougal2@258
  2565
            whitepointusecspace = luxProp(scn, "film.whitepointusecolorspace", "true")
dougal2@258
  2566
            luxBool("whitepointusecolorspace", whitepointusecspace, "Colorspace Whitepoint", "Use default whitepoint for selected colorspace", gui, 1.0)
dougal2@258
  2567
            gammausecspace = luxProp(scn, "film.gammausecolorspace", "true")
dougal2@258
  2568
            luxBool("gammausecolorspace", gammausecspace, "Colorspace Gamma", "Use default output gamma for selected colorspace", gui, 1.0)
dougal2@258
  2569
    
dougal2@258
  2570
            if(whitepointusecspace.get() == "false"):
dougal2@258
  2571
                if gui: gui.newline("  Whitepoint:")
dougal2@258
  2572
                whitepointusepreset = luxProp(scn, "film.whitepointusepreset", "true")
dougal2@258
  2573
                luxBool("whitepointusepreset", whitepointusepreset, "Preset", "Select from a list of predefined presets", gui, 0.4)
dougal2@258
  2574
    
dougal2@258
  2575
                if(whitepointusepreset.get() == "true"):
dougal2@258
  2576
                    whitepointpresets = ["E", "D50", "D55", "D65", "D75", "A", "B", "C", "9300", "F2", "F7", "F11"]
dougal2@258
  2577
                    whitepointpreset = luxProp(scn, "film.whitepointpreset", "D65")
dougal2@258
  2578
                    luxOption("whitepointpreset", whitepointpreset, whitepointpresets, "  PRESET", "select Whitepoint preset", gui, 1.6)
dougal2@258
  2579
    
dougal2@258
  2580
                    if whitepointpreset.get()=="E": cspacewhiteX.set(0.333); cspacewhiteY.set(0.333)
dougal2@258
  2581
                    elif whitepointpreset.get()=="D50": cspacewhiteX.set(0.346); cspacewhiteY.set(0.359)
dougal2@258
  2582
                    elif whitepointpreset.get()=="D55": cspacewhiteX.set(0.332); cspacewhiteY.set(0.347)
dougal2@258
  2583
                    elif whitepointpreset.get()=="D65": cspacewhiteX.set(0.313); cspacewhiteY.set(0.329)
dougal2@258
  2584
                    elif whitepointpreset.get()=="D75": cspacewhiteX.set(0.299); cspacewhiteY.set(0.315)
dougal2@258
  2585
                    elif whitepointpreset.get()=="A": cspacewhiteX.set(0.448); cspacewhiteY.set(0.407)
dougal2@258
  2586
                    elif whitepointpreset.get()=="B": cspacewhiteX.set(0.348); cspacewhiteY.set(0.352)
dougal2@258
  2587
                    elif whitepointpreset.get()=="C": cspacewhiteX.set(0.310); cspacewhiteY.set(0.316)
dougal2@258
  2588
                    elif whitepointpreset.get()=="9300": cspacewhiteX.set(0.285); cspacewhiteY.set(0.293)
dougal2@258
  2589
                    elif whitepointpreset.get()=="F2": cspacewhiteX.set(0.372); cspacewhiteY.set(0.375)
dougal2@258
  2590
                    elif whitepointpreset.get()=="F7": cspacewhiteX.set(0.313); cspacewhiteY.set(0.329)
dougal2@258
  2591
                    elif whitepointpreset.get()=="F11": cspacewhiteX.set(0.381); cspacewhiteY.set(0.377)
dougal2@258
  2592
                else:
dougal2@258
  2593
                    luxFloat("white X", cspacewhiteX, 0.0, 1.0, "white X", "Whitepoint X weight", gui, 0.8)
dougal2@258
  2594
                    luxFloat("white Y", cspacewhiteY, 0.0, 1.0, "white Y", "Whitepoint Y weight", gui, 0.8)
dougal2@258
  2595
    
dougal2@258
  2596
            if(gammausecspace.get() == "false"):
dougal2@223
  2597
                if gui: gui.newline("  Gamma:")
dougal2@223
  2598
                luxFloat("gamma", gamma, 0.1, 6.0, "gamma", "Output and RGC Gamma", gui, 2.0)
dougal2@258
  2599
        else:
dougal2@258
  2600
            # manual controls
dougal2@258
  2601
            luxFloat("white X", cspacewhiteX, 0.0, 1.0, "white X", "Whitepoint X weight", gui, 0.8)
dougal2@258
  2602
            luxFloat("white Y", cspacewhiteY, 0.0, 1.0, "white Y", "Whitepoint Y weight", gui, 0.8)
dougal2@258
  2603
            luxFloat("red X", cspaceredX, 0.0, 1.0, "red X", "Red component X weight", gui, 1.0)
dougal2@258
  2604
            luxFloat("red Y", cspaceredY, 0.0, 1.0, "red Y", "Red component Y weight", gui, 1.0)
dougal2@258
  2605
            luxFloat("green X", cspacegreenX, 0.0, 1.0, "green X", "Green component X weight", gui, 1.0)
dougal2@258
  2606
            luxFloat("green Y", cspacegreenY, 0.0, 1.0, "green Y", "Green component Y weight", gui, 1.0)
dougal2@258
  2607
            luxFloat("blue X", cspaceblueX, 0.0, 1.0, "blue X", "Blue component X weight", gui, 1.0)
dougal2@258
  2608
            luxFloat("blue Y", cspaceblueY, 0.0, 1.0, "blue Y", "Blue component Y weight", gui, 1.0)
dougal2@258
  2609
            if gui: gui.newline("  Gamma:")
dougal2@258
  2610
            luxFloat("gamma", gamma, 0.1, 6.0, "gamma", "Output and RGC Gamma", gui, 2.0)
dougal2@258
  2611
            
dougal2@258
  2612
        str += "\n   \"float colorspace_white\" [%f %f]"%(cspacewhiteX.get(), cspacewhiteY.get())
dougal2@258
  2613
        str += "\n   \"float colorspace_red\" [%f %f]"%(cspaceredX.get(), cspaceredY.get())
dougal2@258
  2614
        str += "\n   \"float colorspace_green\" [%f %f]"%(cspacegreenX.get(), cspacegreenY.get())
dougal2@258
  2615
        str += "\n   \"float colorspace_blue\" [%f %f]"%(cspaceblueX.get(), cspaceblueY.get())
dougal2@258
  2616
        str += "\n   \"float gamma\" [%f]"%(gamma.get())
dougal2@223
  2617
dougal2@223
  2618
    return str
jromang@7
  2619
jromang@7
  2620
zuegs@21
  2621
def luxPixelFilter(scn, gui=None):
dougal2@223
  2622
    global icon_c_filter
dougal2@223
  2623
    str = ""
dougal2@223
  2624
    if scn:
dougal2@223
  2625
        filtertype = luxProp(scn, "pixelfilter.type", "mitchell")
dougal2@223
  2626
        str = luxIdentifier("PixelFilter", filtertype, ["box", "gaussian", "mitchell", "sinc", "triangle"], "FILTER", "select pixel filter type", gui, icon_c_filter)
dougal2@223
  2627
dougal2@223
  2628
        # Advanced toggle
dougal2@223
  2629
        parammodeadvanced = luxProp(scn, "parammodeadvanced", "false")
dougal2@223
  2630
        showadvanced = luxProp(scn, "pixelfilter.showadvanced", parammodeadvanced.get())
dougal2@223
  2631
        luxBool("advanced", showadvanced, "Advanced", "Show advanced options", gui, 0.6)
dougal2@223
  2632
        # Help toggle
dougal2@223
  2633
        showhelp = luxProp(scn, "pixelfilter.showhelp", "false")
dougal2@223
  2634
        luxHelp("help", showhelp, "Help", "Show Help Information", gui, 0.4)
dougal2@223
  2635
dougal2@223
  2636
        if filtertype.get() == "box":
dougal2@223
  2637
            if showadvanced.get()=="true":
dougal2@223
  2638
                # Advanced parameters
dougal2@223
  2639
                if gui: gui.newline()
dougal2@223
  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)
dougal2@223
  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)
dougal2@223
  2642
        if filtertype.get() == "gaussian":
dougal2@223
  2643
            if showadvanced.get()=="true":
dougal2@223
  2644
                # Advanced parameters
dougal2@223
  2645
                if gui: gui.newline()
dougal2@223
  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)
dougal2@223
  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)
dougal2@223
  2648
                if gui: gui.newline()
dougal2@223
  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)
dougal2@223
  2650
        if filtertype.get() == "mitchell":
dougal2@223
  2651
            if showadvanced.get()=="false":
dougal2@223
  2652
                # Default parameters
dougal2@223
  2653
                if gui: gui.newline("", 8, 0, None, [0.4,0.4,0.4])
radiance@318
  2654
                slidval = luxProp(scn, "pixelfilter.mitchell.sharp", 0.25)
dougal2@223
  2655
                luxFloat("sharpness", slidval, 0.0, 1.0, "sharpness", "Specify amount between blurred (left) and sharp/ringed (right)", gui, 2.0, 1)
dougal2@223
  2656
                # rule: B + 2*c = 1.0
dougal2@223
  2657
                C = slidval.getFloat() * 0.5
dougal2@223
  2658
                B = 1.0 - slidval.getFloat()
dougal2@223
  2659
                str += "\n   \"float B\" [%f]"%(B)
dougal2@223
  2660
                str += "\n   \"float C\" [%f]"%(C)
dougal2@223
  2661
dougal2@223
  2662
            if showadvanced.get()=="true":
dougal2@223
  2663
                # Advanced parameters
dougal2@223
  2664
                if gui: gui.newline()
dougal2@223
  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)
dougal2@223
  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)
dougal2@223
  2667
                if gui: gui.newline()
dougal2@223
  2668
    
dougal2@223
  2669
                optmode = luxProp(scn, "pixelfilter.mitchell.optmode", "slider")
dougal2@223
  2670
                luxOption("optmode", optmode, ["slider", "preset", "manual"], "Mode", "Mode of configuration", gui, 0.5)
dougal2@223
  2671
    
dougal2@223
  2672
                if(optmode.get() == "slider"):
dougal2@223
  2673
                    slidval = luxProp(scn, "pixelfilter.mitchell.sharp", 0.33)
dougal2@223
  2674
                    luxFloat("sharpness", slidval, 0.0, 1.0, "sharpness", "Specify amount between blurred (left) and sharp/ringed (right)", gui, 1.5, 1)
dougal2@223
  2675
                    # rule: B + 2*c = 1.0
dougal2@223
  2676
                    C = slidval.getFloat() * 0.5
dougal2@223
  2677
                    B = 1.0 - slidval.getFloat()
dougal2@223
  2678
                    str += "\n   \"float B\" [%f]"%(B)
dougal2@223
  2679
                    str += "\n   \"float C\" [%f]"%(C)
dougal2@223
  2680
                elif(optmode.get() == "preset"):
dougal2@223
  2681
                    print "not implemented"
dougal2@223
  2682
                else:
dougal2@223
  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)
dougal2@223
  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)
dougal2@223
  2685
dougal2@223
  2686
        if filtertype.get() == "sinc":
dougal2@223
  2687
            if showadvanced.get()=="true":
dougal2@223
  2688
                # Advanced parameters
dougal2@223
  2689
                if gui: gui.newline()
dougal2@223
  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)
dougal2@223
  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)
dougal2@223
  2692
                if gui: gui.newline()
dougal2@223
  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)
dougal2@223
  2694
        if filtertype.get() == "triangle":
dougal2@223
  2695
            if showadvanced.get()=="true":
dougal2@223
  2696
                # Advanced parameters
dougal2@223
  2697
                if gui: gui.newline()
dougal2@223
  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)
dougal2@223
  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)
dougal2@223
  2700
    return str            
jromang@0
  2701
zuegs@21
  2702
def luxSampler(scn, gui=None):
dougal2@223
  2703
    global icon_c_sampler, icon_help
dougal2@223
  2704
    str = ""
dougal2@223
  2705
    if scn:
dougal2@223
  2706
        samplertype = luxProp(scn, "sampler.type", "metropolis")
dougal2@223
  2707
        str = luxIdentifier("Sampler", samplertype, ["metropolis", "erpt", "lowdiscrepancy", "random"], "SAMPLER", "select sampler type", gui, icon_c_sampler)
dougal2@223
  2708
dougal2@223
  2709
        # Advanced toggle
dougal2@223
  2710
        parammodeadvanced = luxProp(scn, "parammodeadvanced", "false")
dougal2@223
  2711
        showadvanced = luxProp(scn, "sampler.showadvanced", parammodeadvanced.get())
dougal2@223
  2712
        luxBool("advanced", showadvanced, "Advanced", "Show advanced options", gui, 0.6)
dougal2@223
  2713
        # Help toggle
dougal2@223
  2714
        showhelp = luxProp(scn, "sampler.showhelp", "false")
dougal2@223
  2715
        luxHelp("help", showhelp, "Help", "Show Help Information", gui, 0.4)
dougal2@223
  2716
dougal2@223
  2717
        if samplertype.get() == "metropolis":
dougal2@223
  2718
            if showadvanced.get()=="false":
dougal2@223
  2719
                # Default parameters
dougal2@223
  2720
                if gui: gui.newline("  Mutation:", 8, 0, None, [0.4,0.4,0.4])
dougal2@223
  2721
                strength = luxProp(scn, "sampler.metro.strength", 0.6)
dougal2@223
  2722
                luxFloat("strength", strength, 0.0, 1.0, "strength", "Mutation Strength (lmprob = 1.0-strength)", gui, 2.0, 1)
dougal2@223
  2723
                v = 1.0 - strength.get()
dougal2@223
  2724
                str += "\n   \"float largemutationprob\" [%f]"%v
dougal2@223
  2725
            if showadvanced.get()=="true":
dougal2@223
  2726
                # Advanced parameters
dougal2@223
  2727
                if gui: gui.newline("  Mutation:")
dougal2@223
  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)
dougal2@223
  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)
dougal2@223
  2730
                if gui: gui.newline("  Screen:")
dougal2@223
  2731
                str += luxInt("initsamples", luxProp(scn, "sampler.metro.initsamples", 262144), 1, 1000000, "initsamples", "", gui)
dougal2@223
  2732
                str += luxBool("usevariance",luxProp(scn, "sampler.metro.usevariance", "false"), "usevariance", "Accept based on variance", gui, 1.0)
dougal2@223
  2733
dougal2@223
  2734
            if showhelp.get()=="true":
dougal2@223
  2735
                if gui: gui.newline("  Description:", 8, 0, icon_help, [0.4,0.5,0.56])
dougal2@223
  2736
                r = gui.getRect(2,1); BGL.glRasterPos2i(r[0],r[1]+5) 
dougal2@223
  2737
                Draw.Text("A Metropolis-Hastings mutating sampler which implements MLT", 'small')    
dougal2@223
  2738
dougal2@223
  2739
        if samplertype.get() == "erpt":
dougal2@223
  2740
            str += luxInt("initsamples", luxProp(scn, "sampler.erpt.initsamples", 100000), 1, 1000000, "initsamples", "", gui)
dougal2@223
  2741
            if gui: gui.newline("  Mutation:")
dougal2@223
  2742
            str += luxInt("chainlength", luxProp(scn, "sampler.erpt.chainlength", 512), 1, 32768, "chainlength", "The number of mutations from a given seed", gui)
dougal2@223
  2743
            if gui: gui.newline()
dougal2@223
  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)
dougal2@223
  2745
dougal2@223
  2746
        if samplertype.get() == "lowdiscrepancy":
dougal2@223
  2747
            if gui: gui.newline("  PixelSampler:")
dougal2@223
  2748
            str += luxOption("pixelsampler", luxProp(scn, "sampler.lowdisc.pixelsampler", "lowdiscrepancy"), ["linear", "tile", "random", "vegas","lowdiscrepancy","hilbert"], "pixel-sampler", "select pixel-sampler", gui)
dougal2@223
  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)
dougal2@223
  2750
dougal2@223
  2751
        if samplertype.get() == "random":
dougal2@223
  2752
            if gui: gui.newline("  PixelSampler:")
dougal2@223
  2753
            str += luxOption("pixelsampler", luxProp(scn, "sampler.random.pixelsampler", "vegas"), ["linear", "tile", "random", "vegas","lowdiscrepancy","hilbert"], "pixel-sampler", "select pixel-sampler", gui)
dougal2@223
  2754
            if gui: gui.newline()
dougal2@223
  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)
dougal2@223
  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)
dougal2@223
  2757
    return str            
zuegs@21
  2758
zuegs@21
  2759
def luxSurfaceIntegrator(scn, gui=None):
dougal2@223
  2760
    global icon_c_integrator
dougal2@223
  2761
    str = ""
dougal2@223
  2762
    if scn:
dougal2@223
  2763
        integratortype = luxProp(scn, "sintegrator.type", "bidirectional")
dougal2@258
  2764
        
jeanphi@311
  2765
        str = luxIdentifier("SurfaceIntegrator", integratortype, ["directlighting", "path", "bidirectional", "exphotonmap", "distributedpath", "igi" ], "INTEGRATOR", "select surface integrator type", gui, icon_c_integrator)
dougal2@223
  2766
dougal2@223
  2767
        # Advanced toggle
dougal2@223
  2768
        parammodeadvanced = luxProp(scn, "parammodeadvanced", "false")
dougal2@223
  2769
        showadvanced = luxProp(scn, "sintegrator.showadvanced", parammodeadvanced.get())
dougal2@223
  2770
        luxBool("advanced", showadvanced, "Advanced", "Show advanced options", gui, 0.6)
dougal2@223
  2771
        # Help toggle
dougal2@223
  2772
        showhelp = luxProp(scn, "sintegrator.showhelp", "false")
dougal2@223
  2773
        luxHelp("help", showhelp, "Help", "Show Help Information", gui, 0.4)
dougal2@223
  2774
dougal2@223
  2775
        if integratortype.get() == "directlighting":
dougal2@223
  2776
            if showadvanced.get()=="false":
dougal2@223
  2777
                # Default parameters
dougal2@223
  2778
                if gui: gui.newline("  Depth:", 8, 0, None, [0.4,0.4,0.4])
dougal2@223
  2779
                str += luxInt("maxdepth", luxProp(scn, "sintegrator.dlighting.maxdepth", 8), 0, 2048, "bounces", "The maximum recursion depth for ray casting", gui, 2.0)
dougal2@223
  2780
dougal2@223
  2781
            if showadvanced.get()=="true":
dougal2@223
  2782
                # Advanced parameters
dougal2@223
  2783
                str += luxOption("strategy", luxProp(scn, "sintegrator.dlighting.strategy", "auto"), ["one", "all", "auto"], "strategy", "select directlighting strategy", gui)
dougal2@223
  2784
                if gui: gui.newline("  Depth:")
dougal2@223
  2785
                str += luxInt("maxdepth", luxProp(scn, "sintegrator.dlighting.maxdepth", 8), 0, 2048, "max-depth", "The maximum recursion depth for ray casting", gui)
dougal2@223
  2786
                if gui: gui.newline()
dougal2@223
  2787
dougal2@223
  2788
        if integratortype.get() == "path":
dougal2@223
  2789
            if showadvanced.get()=="false":
dougal2@223
  2790
                # Default parameters
dougal2@223
  2791
                if gui: gui.newline("  Depth:", 8, 0, None, [0.4,0.4,0.4])
radiance29@238
  2792
                str += luxInt("maxdepth", luxProp(scn, "sintegrator.path.maxdepth", 10), 0, 2048, "bounces", "The maximum recursion depth for ray casting", gui, 1.0)
dougal2@240
  2793
                ienv = luxProp(scn, "sintegrator.path.ienvironment", "true")
dougal2@240
  2794
                str += luxBool("includeenvironment", ienv, "Include Environment", "Enable/Disable rendering of environment lightsources", gui)
dougal2@223
  2795
dougal2@223
  2796
            if showadvanced.get()=="true":
dougal2@223
  2797
                # Advanced parameters
dougal2@223
  2798
                if gui: gui.newline("  Depth:")
dougal2@223
  2799
                str += luxInt("maxdepth", luxProp(scn, "sintegrator.path.maxdepth", 10), 0, 2048, "maxdepth", "The maximum recursion depth for ray casting", gui)
dougal2@223
  2800
                str += luxOption("strategy", luxProp(scn, "sintegrator.path.strategy", "auto"), ["one", "all", "auto"], "strategy", "select directlighting strategy", gui)
dougal2@223
  2801
                if gui: gui.newline("  RR:")
dougal2@223
  2802
                rrstrat = luxProp(scn, "sintegrator.path.rrstrategy", "efficiency")
dougal2@223
  2803
                str += luxOption("rrstrategy", rrstrat, ["efficiency", "probability", "none"], "RR strategy", "select Russian Roulette path termination strategy", gui)
dougal2@223
  2804
                if rrstrat.get() == "probability":
dougal2@223
  2805
                    str += luxFloat("rrcontinueprob", luxProp(scn, "sintegrator.path.rrcontinueprob", 0.65), 0.0, 1.0, "rrprob", "Russian roulette continue probability", gui)
dougal2@240
  2806
                ienv = luxProp(scn, "sintegrator.path.ienvironment", "true")
dougal2@240
  2807
                str += luxBool("includeenvironment", ienv, "Include Environment", "Enable/Disable rendering of environment lightsources", gui)
dougal2@223
  2808
dougal2@223
  2809
        if integratortype.get() == "bidirectional":
dougal2@223
  2810
            if showadvanced.get()=="false":
dougal2@223
  2811
                # Default parameters
dougal2@223
  2812
                if gui: gui.newline("  Depth:", 8, 0, None, [0.4,0.4,0.4])
radiance29@249
  2813
                bounces = luxProp(scn, "sintegrator.bidir.bounces", 16)
dougal2@223
  2814
                luxInt("bounces", bounces, 5, 32, "bounces", "The maximum recursion depth for ray casting (in both directions)", gui, 2.0)
dougal2@223
  2815
                str += "\n   \"integer eyedepth\" [%i]\n"%bounces.get()
dougal2@223
  2816
                str += "   \"integer lightdepth\" [%i]"%bounces.get()
dougal2@223
  2817
dougal2@223
  2818
            if showadvanced.get()=="true":
dougal2@223
  2819
                # Advanced parameters
dougal2@223
  2820
                if gui: gui.newline("  Depth:")
radiance29@249
  2821
                str += luxInt("eyedepth", luxProp(scn, "sintegrator.bidir.eyedepth", 16), 0, 2048, "eyedepth", "The maximum recursion depth for ray casting", gui)
radiance29@249
  2822
                str += luxInt("lightdepth", luxProp(scn, "sintegrator.bidir.lightdepth", 16), 0, 2048, "lightdepth", "The maximum recursion depth for light ray casting", gui)
dougal2@223
  2823
                str += luxOption("strategy", luxProp(scn, "sintegrator.bidir.strategy", "auto"), ["one", "all", "auto"], "strategy", "select directlighting strategy", gui)
dougal2@223
  2824
dougal2@223
  2825
        if integratortype.get() == "exphotonmap":
jeanphi@306
  2826
            if gui: gui.newline("  Render:")
jeanphi@306
  2827
            str += luxOption("renderingmode", luxProp(scn, "sintegrator.photonmap.renderingmode", "directlighting"), ["directlighting", "path"], "renderingmode", "select rendering mode", gui)
jeanphi@306
  2828
            str += luxOption("strategy", luxProp(scn, "sintegrator.photonmap.strategy", "auto"), ["one", "all", "auto"], "strategy", "select directlighting strategy", gui)
jeanphi@306
  2829
            str += luxInt("maxphotondepth", luxProp(scn, "sintegrator.photonmap.maxphotondepth", 10), 1, 1024, "maxphotondepth", "The maximum recursion depth of photon tracing", gui)
jeanphi@306
  2830
            str += luxInt("maxdepth", luxProp(scn, "sintegrator.photonmap.maxdepth", 6), 1, 1024, "maxdepth", "The maximum recursion depth of specular reflection and refraction", gui)
jeanphi@306
  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)
jeanphi@306
  2832
            str += luxInt("nused", luxProp(scn, "sintegrator.photonmap.nused", 50), 0, 1000000, "nused", "The number of photons to use in density estimation", gui)
jeanphi@306
  2833
dougal2@223
  2834
            if gui: gui.newline("  Photons:")
dougal2@223
  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)
dougal2@223
  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)
dougal2@223
  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)
dougal2@223
  2838
            if gui: gui.newline("  FinalGather:")
dougal2@223
  2839
            fg = luxProp(scn, "sintegrator.photonmap.fgather", "true")
dougal2@223
  2840
            str += luxBool("finalgather", fg, "finalgather", "Enable use of final gather during rendering", gui)
dougal2@223
  2841
            if fg.get() == "true":
dougal2@223
  2842
                rrstrat = luxProp(scn, "sintegrator.photonmap.gatherrrstrategy", "efficiency")
dougal2@223
  2843
                str += luxOption("gatherrrstrategy", rrstrat, ["efficiency", "probability", "none"], "RR strategy", "select Russian Roulette gather termination strategy", gui)
jeanphi@306
  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)
dougal2@223
  2845
                str += luxFloat("gatherangle", luxProp(scn, "sintegrator.photonmap.gangle", 10.0), 0.0, 360.0, "gatherangle", "Angle for final gather", gui)
jeanphi@306
  2846
                if rrstrat.get() == "probability":
jeanphi@306
  2847
                    str += luxFloat("gatherrrcontinueprob", luxProp(scn, "sintegrator.photonmap.gatherrrcontinueprob", 0.65), 0.0, 1.0, "rrcontinueprob", "Probability for russian roulette particle tracing termination", gui)
dougal2@223
  2848
dougal2@223
  2849
        if integratortype.get() == "distributedpath":
dougal2@223
  2850
            str += luxOption("strategy", luxProp(scn, "sintegrator.distributedpath.strategy", "auto"), ["one", "all", "auto"], "strategy", "select directlighting strategy", gui)
dougal2@223
  2851
            if gui: gui.newline("  Direct:")
dougal2@223
  2852
            str += luxBool("directsampleall",luxProp(scn, "sintegrator.distributedpath.directsampleall", "true"), "Direct ALL", "Include diffuse direct light sample at first vertex", gui, 0.75)
dougal2@223
  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)
dougal2@223
  2854
            str += luxBool("indirectsampleall",luxProp(scn, "sintegrator.distributedpath.indirectsampleall", "false"), "Indirect ALL", "Include diffuse direct light sample at first vertex", gui, 0.75)
dougal2@223
  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)
dougal2@223
  2856
            if gui: gui.newline("  Diffuse:")
dougal2@223
  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)
dougal2@223
  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)
dougal2@223
  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)
dougal2@223
  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)
dougal2@223
  2861
            str += luxBool("directdiffuse",luxProp(scn, "sintegrator.distributedpath.directdiffuse", "true"), "DL", "Include diffuse direct light sample at first vertex", gui, 0.25)
dougal2@223
  2862
            str += luxBool("indirectdiffuse",luxProp(scn, "sintegrator.distributedpath.indirectdiffuse", "true"), "IDL", "Include diffuse indirect light sample at first vertex", gui, 0.25)
dougal2@223
  2863
            if gui: gui.newline("  Glossy:")
dougal2@223
  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)
dougal2@223
  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)
dougal2@223
  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)
dougal2@223
  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)
dougal2@223
  2868
            str += luxBool("directglossy",luxProp(scn, "sintegrator.distributedpath.directglossy", "true"), "DL", "Include glossy direct light sample at first vertex", gui, 0.25)
dougal2@223
  2869
            str += luxBool("indirectglossy",luxProp(scn, "sintegrator.distributedpath.indirectglossy", "true"), "IDL", "Include glossy indirect light sample at first vertex", gui, 0.25)
dougal2@223
  2870
            if gui: gui.newline("  Specular:")
dougal2@223
  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)
dougal2@223
  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)
radiance29@245
  2873
            #if gui: gui.newline("  Caustics:")
radiance29@245
  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)
radiance29@245
  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)
radiance29@245
  2876
radiance29@245
  2877
            usereject = luxProp(scn, "sintegrator.distributedpath.usereject", "false")
radiance29@245
  2878
            luxCollapse("usereject", usereject, "Rejection", "Enable Rejection system to eliminate bright contributions", gui, 2.0)
radiance29@245
  2879
dougal2@259
  2880
            if usereject.get()=="true":
dougal2@259
  2881
                if gui: gui.newline("  Diffuse:")
dougal2@259
  2882
                
dougal2@259
  2883
                diffusereflectreject = luxProp(scn, "sintegrator.distributedpath.difreflreject", "false")
dougal2@259
  2884
                str += luxBool("diffusereflectreject", diffusereflectreject, "Reflect", "Enable Rejection for Diffuse Reflection", gui, 0.4)
dougal2@259
  2885
                if diffusereflectreject.get()=="true":
dougal2@259
  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)
dougal2@258
  2887
            
dougal2@259
  2888
                diffuserefractreject = luxProp(scn, "sintegrator.distributedpath.difrefrreject", "false")
dougal2@259
  2889
                str += luxBool("diffuserefractreject", diffuserefractreject, "Refract", "Enable Rejection for Diffuse Refraction", gui, 0.4)
dougal2@259
  2890
                if diffuserefractreject.get()=="true":
dougal2@259
  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)
dougal2@258
  2892
            
dougal2@259
  2893
                if gui: gui.newline("  Glossy:")
dougal2@259
  2894
                
dougal2@259
  2895
                glossyreflectreject = luxProp(scn, "sintegrator.distributedpath.glosreflreject", "false")
dougal2@259
  2896
                str += luxBool("glossyreflectreject", glossyreflectreject, "Reflect", "Enable Rejection for Glossy Reflection", gui, 0.4)
dougal2@259
  2897
                if glossyreflectreject.get()=="true":
dougal2@259
  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)
dougal2@259
  2899
            
dougal2@259
  2900
                glossyrefractreject = luxProp(scn, "sintegrator.distributedpath.glosrefrreject", "false")
dougal2@259
  2901
                str += luxBool("glossyrefractreject", glossyrefractreject, "Refract", "Enable Rejection for Glossy Refraction", gui, 0.4)
dougal2@259
  2902
                if glossyrefractreject.get()=="true":
dougal2@259
  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)
dougal2@258
  2904
    
jeanphi@311
  2905
        if integratortype.get() == "igi":
jeanphi@311
  2906
            if gui: gui.newline("  Depth:", 8, 0, None, [0.4,0.4,0.4])
jeanphi@311
  2907
            depth = luxProp(scn, "sintegrator.igi.maxdepth", 5)
jeanphi@311
  2908
            luxInt("maxdepth", depth, 1, 32, "maxdepth", "The maximum recursion depth for ray casting", gui, 2.0)
jeanphi@311
  2909
            if showadvanced.get()=="true":
jeanphi@311
  2910
                # Advanced parameters
jeanphi@311
  2911
                if gui: gui.newline("  VLights:")
jeanphi@311
  2912
                str += luxInt("nsets", luxProp(scn, "sintegrator.igi.nsets", 4), 1, 100, "nsets", "The number of virtual lights sets", gui)
jeanphi@311
  2913
                str += luxInt("nlights", luxProp(scn, "sintegrator.igi.nlights", 64), 1, 1000, "nlights", "The number of light paths per light set", gui)
jeanphi@311
  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)
jeanphi@311
  2915
dougal2@258
  2916
    
dougal2@223
  2917
    return str
zuegs@21
  2918
radiance29@64
  2919
def luxVolumeIntegrator(scn, gui=None):
dougal2@223
  2920
    global icon_c_volumeintegrator
dougal2@223
  2921
    str = ""
dougal2@223
  2922
    if scn:
dougal2@223
  2923
        integratortype = luxProp(scn, "vintegrator.type", "single")
dougal2@223
  2924
        str = luxIdentifier("VolumeIntegrator", integratortype, ["emission", "single"], "VOLUME INT", "select volume integrator type", gui, icon_c_volumeintegrator)
dougal2@223
  2925
        if integratortype.get() == "emission":
dougal2@223
  2926
            str += luxFloat("stepsize", luxProp(scn, "vintegrator.emission.stepsize", 1.0), 0.0, 100.0, "stepsize", "Stepsize for volumes", gui)
dougal2@223
  2927
        if integratortype.get() == "single":
dougal2@223
  2928
            str += luxFloat("stepsize", luxProp(scn, "vintegrator.emission.stepsize", 1.0), 0.0, 100.0, "stepsize", "Stepsize for volumes", gui)
dougal2@223
  2929
    return str
radiance29@64
  2930
zuegs@21
  2931
def luxEnvironment(scn, gui=None):
dougal2@223
  2932
    global icon_c_environment
dougal2@223
  2933
    str = ""
dougal2@223
  2934
    if scn:
dougal2@223
  2935
        envtype = luxProp(scn, "env.type", "infinite")
dougal2@232
  2936
        lsstr = luxIdentifier("LightSource", envtype, ["none", "infinite", "sunsky"], "ENVIRONMENT", "select environment light type", gui, icon_c_environment)
dougal2@223
  2937
        if gui: gui.newline()
dougal2@223
  2938
        str = ""
dougal2@231
  2939
        
dougal2@223
  2940
        if envtype.get() != "none":
dougal2@223
  2941
            
dougal2@223
  2942
            if envtype.get() in ["infinite", "sunsky"]:
dougal2@232
  2943
                env_lg = luxProp(scn, "env.lightgroup", "default")
dougal2@232
  2944
                luxString("env.lightgroup", env_lg, "lightgroup", "Environment light group", gui)
doughammond@325
  2945
                if luxProp(scn, "nolg", "false").get()!="true":
doughammond@325
  2946
                    lsstr = '\nLightGroup "' + env_lg.get() + '"' + lsstr
doug@328
  2947
                rotZ = luxProp(scn, "env.rotation", 0.0)
doug@328
  2948
                rotY = luxProp(scn, "env.rotationY", 0.0)
doug@328
  2949
                rotX = luxProp(scn, "env.rotationX", 0.0)
doug@328
  2950
                if gui: gui.newline()
doug@328
  2951
                luxFloat("rotation", rotX, 0.0, 360.0, "rot X", "environment rotation X", gui, 0.66)
doug@328
  2952
                luxFloat("rotation", rotY, 0.0, 360.0, "rot Y", "environment rotation Y", gui, 0.66)
doug@328
  2953
                luxFloat("rotation", rotZ, 0.0, 360.0, "rot Z", "environment rotation Z", gui, 0.66)
doug@328
  2954
                if rotZ.get() != 0 or rotY.get() != 0 or rotX.get() != 0:
doug@328
  2955
                    str += "\tRotate %d 1 0 0\n"%(rotX.get())
doug@328
  2956
                    str += "\tRotate %d 0 1 0\n"%(rotY.get())
doug@328
  2957
                    str += "\tRotate %d 0 0 1\n"%(rotZ.get())
dougal2@223
  2958
            str += "\t"+lsstr
dougal2@223
  2959
dougal2@223
  2960
            infinitehassun = 0
dougal2@223
  2961
            if envtype.get() == "infinite":
dougal2@223
  2962
                mapping = luxProp(scn, "env.infinite.mapping", "latlong")
dougal2@223
  2963
                mappings = ["latlong","angular","vcross"]
dougal2@232
  2964
                mapstr = luxOption("mapping", mapping, mappings, "mapping", "Select mapping type", gui, 0.5)
dougal2@223
  2965
                map = luxProp(scn, "env.infinite.mapname", "")
dougal2@232
  2966
                mapstr += luxFile("mapname", map, "map-file", "filename of the environment map", gui, 1.5)
dougal2@223
  2967
                mapstr += luxFloat("gamma", luxProp(scn, "env.infinite.gamma", 1.0), 0.0, 6.0, "gamma", "", gui, 1.0)
dougal2@223
  2968
                
dougal2@223
  2969
                if map.get() != "":
dougal2@223
  2970
                    str += mapstr
dougal2@223
  2971
                else:
dougal2@223
  2972
                    try:
dougal2@223
  2973
                        worldcolor = Blender.World.Get('World').getHor()
dougal2@223
  2974
                        str += "\n   \"color L\" [%g %g %g]" %(worldcolor[0], worldcolor[1], worldcolor[2])
dougal2@223
  2975
                    except: pass
dougal2@223
  2976
radiance29@245
  2977
                str += luxFloat("gain", luxProp(scn, "env.infinite.gain", 1.0), 0.0001, 100.0, "gain", "", gui, 1.0)
dougal2@223
  2978
dougal2@223
  2979
                infinitesun = luxProp(scn, "env.infinite.hassun", "false")
radiance29@245
  2980
                luxCollapse("infinitesun", infinitesun, "Sun Component", "Add Sunlight Component", gui, 2.0)
dougal2@223
  2981
                if(infinitesun.get() == "true"):
dougal2@232
  2982
                    sun_lg = luxProp(scn, "env.sun_lightgroup", "default")
dougal2@232
  2983
                    luxString("env.lightgroup", sun_lg, "lightgroup", "Sun component light group", gui)
doughammond@325
  2984
                    if luxProp(scn, "nolg", "false").get()!="true":
doughammond@325
  2985
                        str += '\nLightGroup "' + sun_lg.get() + '"'
dougal2@231
  2986
                    str += "\nLightSource \"sun\" "
dougal2@223
  2987
                    infinitehassun = 1
dougal2@223
  2988
dougal2@223
  2989
dougal2@223
  2990
            if envtype.get() == "sunsky" or infinitehassun == 1:
dougal2@231
  2991
                
dougal2@231
  2992
                
dougal2@223
  2993
                sun = None
dougal2@223
  2994
                for obj in scn.objects:
dougal2@223
  2995
                    if (obj.getType() == "Lamp") and ((obj.Layers & scn.Layers) > 0):
dougal2@223
  2996
                        if obj.getData(mesh=1).getType() == 1: # sun object # data
dougal2@223
  2997
                            sun = obj
dougal2@223
  2998
                if sun:
dougal2@232
  2999
                    str += luxFloat("gain", luxProp(scn, "env.sunsky.gain", 1.0), 0.0, 1000.0, "gain", "Sky gain", gui)
dougal2@232
  3000
                    
dougal2@223
  3001
                    invmatrix = Mathutils.Matrix(sun.getInverseMatrix())
dougal2@223
  3002
                    str += "\n   \"vector sundir\" [%f %f %f]\n" %(invmatrix[0][2], invmatrix[1][2], invmatrix[2][2])
dougal2@232
  3003
                    str += luxFloat("relsize", luxProp(scn, "env.sunsky.relsize", 1.0), 0.0, 100.0, "rel.size", "relative sun size", gui)
dougal2@223
  3004
                    str += luxFloat("turbidity", luxProp(scn, "env.sunsky.turbidity", 2.2), 2.0, 50.0, "turbidity", "Sky turbidity", gui)
dougal2@223
  3005
                    
dougal2@225
  3006
                    showGeo = luxProp(sun, 'sc.show', 'false')
dougal2@223
  3007
                    if gui:
radiance29@245
  3008
                        luxCollapse("sc.show", showGeo, "Geographic Sun", "Set sun position by world location, date and time", gui, 2.0)
dougal2@225
  3009
                    if gui and showGeo.get() == 'true':
dougal2@223
  3010
                        gui.newline("Geographic:")
dougal2@235
  3011
                        sc = sun_calculator(sun)
dougal2@223
  3012
                        
dougal2@231
  3013
                        luxInt("sc.day", luxProp(sun, "sc.day", 1), 1, 31, "day", "Local date: day", gui, 0.66)
dougal2@232
  3014
                        luxInt("sc.month", luxProp(sun, "sc.month", 1), 1, 12, "month", "Local date: month", gui, 0.67)
dougal2@231
  3015
                        luxInt("sc.year", luxProp(sun, "sc.year", 2009), 1800, 2100, "year", "Local date: year", gui, 0.66)
dougal2@223
  3016
                        
dougal2@231
  3017
                        luxInt("sc.hour", luxProp(sun, "sc.hour", 0), 0, 23, "hour", "Local time: hour", gui, 0.72)
dougal2@231
  3018
                        luxInt("sc.minute", luxProp(sun, "sc.minute", 0), 0, 59, "minute", "Local time: minute", gui, 0.72)
dougal2@231
  3019
                        luxBool("sc.dst", luxProp(sun, "sc.dst", 'false'), "DST", "DST", gui, 0.28)
dougal2@231
  3020
                        r = gui.getRect(0.28,1)
dougal2@235
  3021
                        Draw.Button("NOW", 0, r[0], r[1], r[2], r[3], "Set to current time", lambda e,v: sc.now())
dougal2@228
  3022
                        
dougal2@235
  3023
                        r = gui.getRect(0.3,1)
dougal2@235
  3024
                        Draw.Button("Preset", 0, r[0], r[1], r[2], r[3], "Choose a preset location", lambda e,v: sc.set_location(
dougal2@235
  3025
                            Draw.PupTreeMenu(sun_calculator.location_list)
dougal2@235
  3026
                        ))
dougal2@223
  3027
                        
dougal2@235
  3028
                        luxFloat("sc.lat", luxProp(sun, "sc.lat", 0.0), -90.0, 90.0, "lat", "Location: latitude", gui, 0.56)
dougal2@235
  3029
                        luxFloat("sc.long", luxProp(sun, "sc.long", 0.0), -180.0, 180.0, "long", "Location: longitude", gui, 0.56)
dougal2@235
  3030
                        luxInt("sc.tz", luxProp(sun, "sc.tz", 0), -12, 12, "timezone", "Local time: timezone offset from GMT", gui, 0.56)
dougal2@223
  3031
                        
dougal2@223
  3032
                        r = gui.getRect(2,1)
dougal2@235
  3033
                        Draw.Button("Calculate", 0, r[0], r[1], r[2], r[3], "Calculate sun's position", lambda e,v: sc.compute())
dougal2@223
  3034
                    
dougal2@223
  3035
                else:
dougal2@223
  3036
                    if gui:
dougal2@223
  3037
                        gui.newline(); r = gui.getRect(2,1); BGL.glRasterPos2i(r[0],r[1]+5) 
dougal2@223
  3038
                        Draw.Text("create a blender Sun Lamp")
dougal2@223
  3039
dougal2@223
  3040
dougal2@223
  3041
            str += "\n"
dougal2@234
  3042
        #if gui: gui.newline("GLOBAL:", 8, 0, None, [0.75,0.5,0.25])
dougal2@234
  3043
        #luxFloat("scale", luxProp(scn, "global.scale", 1.0), 0.0, 10.0, "scale", "global world scale", gui)
dougal2@223
  3044
        
dougal2@223
  3045
    return str
zuegs@21
  3046
dougal2@221
  3047
class sun_calculator:
dougal2@224
  3048
    #Based on SunLight v1.0 by Miguel Kabantsov (miguelkab@gmail.com)
dougal2@224
  3049
    #Replaces the faulty sun position calculation algorythm with a precise calculation (Source for algorythm: http://de.wikipedia.org/wiki/Sonnenstand),
dougal2@224
  3050
    #Co-Ordinates: http://www.bcca.org/misc/qiblih/latlong.html
dougal2@224
  3051
    #Author: Nils-Peter Fischer (Nils-Peter.Fischer@web.de)
dougal2@223
  3052
    
dougal2@235
  3053
    sun = None
dougal2@235
  3054
    
dougal2@223
  3055
    lat = 0
dougal2@223
  3056
    long = 0
dougal2@223
  3057
    
dougal2@223
  3058
    hour = 0
dougal2@223
  3059
    min = 0
dougal2@223
  3060
    tz = 0
dougal2@223
  3061
    dst = 'false'
dougal2@223
  3062
    
dougal2@223
  3063
    day = 0
dougal2@223
  3064
    month = 0
dougal2@223
  3065
    year = 0
dougal2@223
  3066
    
dougal2@235
  3067
    location_list = [
dougal2@235
  3068
        ("EUROPE",[
dougal2@240
  3069
            ("Antwerp, Belgium",          67),
dougal2@235
  3070
            ("Berlin, Germany",            1),
dougal2@240
  3071
            ("Bratislava, Slovak Republic", 70),
dougal2@240
  3072
            ("Brno, Czech Republic",      72),
dougal2@240
  3073
            ("Brussles, Belgium",         68),
dougal2@240
  3074
            ("Geneva, Switzerland",       65),
dougal2@235
  3075
            ("Helsinki, Finland",          7),
dougal2@240
  3076
            ("Innsbruck, Austria",        62),
dougal2@240
  3077
            ("Kyiv, Ukraine",             64),
dougal2@235
  3078
            ("London, England",           10),
dougal2@240
  3079
            ("Lyon, France",              66),
dougal2@240
  3080
            ("Nitra, Slovak Republic",    69),
dougal2@236
  3081
            ("Oslo, Norway",              58),
dougal2@235
  3082
            ("Paris, France",             15),
dougal2@240
  3083
            ("Praha, Czech Republic",     71),
dougal2@235
  3084
            ("Rome, Italy",               18),
dougal2@240
  3085
            ("Telfs, Austria",            63),
dougal2@240
  3086
            ("Warsaw, Poland",            74),
dougal2@240
  3087
            ("Wroclaw, Poland",           73),
dougal2@235
  3088
            ("Zurich, Switzerland",       21),
dougal2@235
  3089
        ]),
dougal2@223
  3090
    
dougal2@235
  3091
        ("WORLD CITIES", [
dougal2@235
  3092
            ("Beijing, China",             0),
dougal2@235
  3093
            ("Bombay, India",              2),
dougal2@235
  3094
            ("Buenos Aires, Argentina",    3),
dougal2@235
  3095
            ("Cairo, Egypt",               4),
dougal2@235
  3096
            ("Cape Town, South Africa",    5),
dougal2@235
  3097
            ("Caracas, Venezuela",         6),
dougal2@240
  3098
            ("Curitiba, Brazil",          60),
dougal2@235
  3099
            ("Hong Kong, China",           8),
dougal2@235
  3100
            ("Jerusalem, Israel",          9),
dougal2@240
  3101
            ("Joinville, Brazil",         61),
dougal2@235
  3102
            ("Mexico City, Mexico",       11),
dougal2@235
  3103
            ("Moscow, Russia",            12),
dougal2@235
  3104
            ("New Delhi, India",          13),
dougal2@235
  3105
            ("Ottawa, Canada",            14),
dougal2@235
  3106
            ("Rio de Janeiro, Brazil",    16),
dougal2@235
  3107
            ("Riyadh, Saudi Arabia",      17),
dougal2@240
  3108
            ("Sao Paulo, Brazil",         59),
dougal2@235
  3109
            ("Sydney, Australia",         19),
dougal2@235
  3110
            ("Tokyo, Japan",              20), 
dougal2@235
  3111
        ]),
dougal2@235
  3112
        
dougal2@235
  3113
        ("US CITIES", [
dougal2@235
  3114
            ("Albuquerque, NM",           22),
dougal2@235
  3115
            ("Anchorage, AK",             23),
dougal2@235
  3116
            ("Atlanta, GA",               24),
dougal2@235
  3117
            ("Austin, TX",                25),
dougal2@235
  3118
            ("Birmingham, AL",            26),
dougal2@235
  3119
            ("Bismarck, ND",              27),
dougal2@235
  3120
            ("Boston, MA",                28),
dougal2@235
  3121
            ("Boulder, CO",               29),
dougal2@235
  3122
            ("Chicago, IL",               30),
dougal2@235
  3123
            ("Dallas, TX",                31),
dougal2@235
  3124
            ("Denver, CO",                32),
dougal2@235
  3125
            ("Detroit, MI",               33),
dougal2@235
  3126
            ("Honolulu, HI",              34),
dougal2@235
  3127
            ("Houston, TX",               35),
dougal2@235
  3128
            ("Indianapolis, IN",          36),
dougal2@235
  3129
            ("Jackson, MS",               37),
dougal2@235
  3130
            ("Kansas City, MO",           38),
dougal2@235
  3131
            ("Los Angeles, CA",           39),
dougal2@235
  3132
            ("Menomonee Falls, WI",       40),
dougal2@235
  3133
            ("Miami, FL",                 41),
dougal2@235
  3134
            ("Minneapolis, MN",           42),
dougal2@235
  3135
            ("New Orleans, LA",           43),
dougal2@235
  3136
            ("New York City, NY",         44),
dougal2@235
  3137
            ("Oklahoma City, OK",         45),
dougal2@235
  3138
            ("Philadelphia, PA",          46),
dougal2@235
  3139
            ("Phoenix, AZ",               47),
dougal2@235
  3140
            ("Pittsburgh, PA",            48),
dougal2@235
  3141
            ("Portland, ME",              49),
dougal2@235
  3142
            ("Portland, OR",              50),
dougal2@235
  3143
            ("Raleigh, NC",               51),
dougal2@235
  3144
            ("Richmond, VA",              52),
dougal2@235
  3145
            ("Saint Louis, MO",           53),
dougal2@235
  3146
            ("San Diego, CA",             54),
dougal2@235
  3147
            ("San Francisco, CA",         55),
dougal2@235
  3148
            ("Seattle, WA",               56),
dougal2@235
  3149
            ("Washington DC",             57),
dougal2@235
  3150
        ])
dougal2@235
  3151
    ]
dougal2@235
  3152
dougal2@235
  3153
    location_data = {
dougal2@235
  3154
        # Europe
dougal2@240
  3155
        67:   ( 51.2167, 4.4, 1),
dougal2@237
  3156
        1:    ( 52.33, 13.30, 1),
dougal2@240
  3157
        70:   ( 48.17, 17.17, 1),
dougal2@240
  3158
        72:   ( 49.2, 16.63, 1),
dougal2@240
  3159
        68:   ( 58.8467, 4.3525, 1),
dougal2@240
  3160
        65:   ( 46.217, 6.150, 1),
dougal2@237
  3161
        7:    ( 60.1667, 24.9667,2),
dougal2@240
  3162
        62:   ( 47.2672, 11.3928, 1),
dougal2@240
  3163
        64:   ( 50.75, 30.0833, 2),
dougal2@237
  3164
        10:   ( 51.50, 0.0, 0),
dougal2@240
  3165
        66:   ( 45.767, 4.833, 1),
dougal2@240
  3166
        69:   ( 48.32, 18.07, 1),
dougal2@237
  3167
        58:   ( 59.56, 10.41, 1),
dougal2@237
  3168
        15:   ( 48.8667, 2.667, 1),
dougal2@240
  3169
        71:   ( 50.08, 14.46, 1),
dougal2@237
  3170
        18:   ( 41.90, 12.4833, 1),
dougal2@240
  3171
        63:   ( 47.3, 11.0667, 1),
dougal2@240
  3172
        74:   ( 52.232, 21.008, 1),
dougal2@240
  3173
        73:   ( 51.108, 17.038, 1),
dougal2@237
  3174
        21:   ( 47.3833, 8.5333, 1),
dougal2@235
  3175
    
dougal2@235
  3176
        # World Cities
dougal2@237
  3177
        0:    ( 39.9167, 116.4167, 8),
dougal2@237
  3178
        2:    ( 18.9333, 72.8333, 5.5),
dougal2@237
  3179
        3:    (-34.60, -58.45, -3),
dougal2@237
  3180
        4:    ( 30.10, 31.3667, 2),
dougal2@237
  3181
        5:    (-33.9167, 18.3667, 2),
dougal2@237
  3182
        6:    ( 10.50, -66.9333, -4),
dougal2@240
  3183
        60:   (-25.4278, -49.2731, -3),
dougal2@237
  3184
        8:    ( 22.25, 114.1667, 8),
dougal2@237
  3185
        9:    ( 31.7833, 35.2333, 2),
dougal2@240
  3186
        61:   (-29.3044, -48.8456, -3),
dougal2@237
  3187
        11:   ( 19.4, -99.15, -6),
dougal2@237
  3188
        12:   ( 55.75, 37.5833, 3),
dougal2@237
  3189
        13:   ( 28.6, 77.2, 5.5),
dougal2@237
  3190
        14:   ( 45.41667, -75.7, -5),
dougal2@237
  3191
        16:   (-22.90, -43.2333, -3),
dougal2@237
  3192
        17:   ( 24.633, 46.71667, 3),
dougal2@240
  3193
        59:   ( -23.5475, -46.6361, -3),
dougal2@237
  3194
        19:   (-33.8667,151.2167,10),
dougal2@237
  3195
        20:   ( 35.70, 139.7667, 9), 
dougal2@235
  3196
    
dougal2@235
  3197
        # US Cities
dougal2@237
  3198
        22:   ( 35.0833, -106.65, -7),
dougal2@237
  3199
        23:   ( 61.217, -149.90, -9),
dougal2@237
  3200
        24:   ( 33.733, -84.383, -5),
dougal2@237
  3201
        25:   ( 30.283, -97.733, -6),
dougal2@237
  3202
        26:   ( 33.521, -86.8025, -6),
dougal2@237
  3203
        27:   ( 46.817, -100.783, -6),
dougal2@237
  3204
        28:   ( 42.35, -71.05, -5),
dougal2@237
  3205
        29:   ( 40.125, -105.237, -7),
dougal2@237
  3206
        30:   ( 41.85, -87.65, -6),
dougal2@237
  3207
        31:   ( 32.46, -96.47, -6),
dougal2@237
  3208
        32:   ( 39.733, -104.983, -7),
dougal2@237
  3209
        33:   ( 42.333, -83.05, -5),
dougal2@237
  3210
        34:   ( 21.30, -157.85, -10),
dougal2@237
  3211
        35:   ( 29.75, -95.35, -6),
dougal2@237
  3212
        36:   ( 39.767, -86.15, -5),
dougal2@237
  3213
        37:   ( 32.283, -90.183, -6),
dougal2@237
  3214
        38:   ( 39.083, -94.567, -6),
dougal2@237
  3215
        39:   ( 34.05, -118.233, -8),
dougal2@237
  3216
        40:   ( 43.11, -88.10, -6),
dougal2@237
  3217
        41:   ( 25.767, -80.183, -5),
dougal2@237
  3218
        42:   ( 44.967, -93.25, -6),
dougal2@237
  3219
        43:   ( 29.95, -90.067, -6),
dougal2@237
  3220
        44:   ( 40.7167, -74.0167, -5),
dougal2@237
  3221
        45:   ( 35.483, -97.533, -6),
dougal2@237
  3222
        46:   ( 39.95, -75.15, -5),
dougal2@237
  3223
        47:   ( 33.433, -112.067,-7),
dougal2@237
  3224
        48:   ( 40.433, -79.9833, -5),
dougal2@237
  3225
        49:   ( 43.666, -70.283, -5),
dougal2@237
  3226
        50:   ( 45.517, -122.65, -8),
dougal2@237
  3227
        51:   ( 35.783, -78.65, -5),
dougal2@237
  3228
        52:   ( 37.5667, -77.450, -5),
dougal2@237
  3229
        53:   ( 38.6167, -90.1833, -6),
dougal2@237
  3230
        54:   ( 32.7667, -117.2167, -8),
dougal2@237
  3231
        55:   ( 37.7667, -122.4167, -8),
dougal2@237
  3232
        56:   ( 47.60, -122.3167, -8),
dougal2@237
  3233
        57:   ( 38.8833, -77.0333, -5),
dougal2@235
  3234
    }
dougal2@235
  3235
dougal2@235
  3236
    def __init__(self, sun):
dougal2@235
  3237
        self.sun = sun
dougal2@235
  3238
    
dougal2@235
  3239
    def now(self):
dougal2@231
  3240
        ct = time.localtime()
dougal2@231
  3241
        
dougal2@231
  3242
        if ct[8] == 0:
dougal2@231
  3243
            dst = 'false'
dougal2@231
  3244
        else:
dougal2@231
  3245
            dst = 'true'
dougal2@231
  3246
        
dougal2@235
  3247
        luxProp(self.sun, 'sc.day', 0).set(ct[2])
dougal2@235
  3248
        luxProp(self.sun, 'sc.month', 0).set(ct[1])
dougal2@235
  3249
        luxProp(self.sun, 'sc.year', 0).set(ct[0])
dougal2@235
  3250
        luxProp(self.sun, 'sc.hour', 0).set(ct[3])
dougal2@235
  3251
        luxProp(self.sun, 'sc.minute', 0).set(ct[4])
dougal2@235
  3252
        luxProp(self.sun, 'sc.dst', 0).set(dst)
dougal2@231
  3253
        
dougal2@235
  3254
        self.compute()
dougal2@231
  3255
        
dougal2@235
  3256
    def set_location(self, location):
dougal2@235
  3257
        if location < 0: return
dougal2@235
  3258
        
dougal2@235
  3259
        lat, long, tz = self.location_data[location]
dougal2@235
  3260
        luxProp(self.sun, "sc.lat", 0).set(lat)
dougal2@235
  3261
        luxProp(self.sun, "sc.long", 0).set(long)
dougal2@235
  3262
        luxProp(self.sun, "sc.tz", 0).set(tz)
dougal2@235
  3263
        
dougal2@235
  3264
        self.compute()
dougal2@231
  3265
    
dougal2@235
  3266
    def compute(self):
dougal2@223
  3267
        
dougal2@235
  3268
        self.lat  = luxProp(self.sun, "sc.lat", 0).get()
dougal2@235
  3269
        self.long = luxProp(self.sun, "sc.long", 0).get()
dougal2@235
  3270
        self.tz   = luxProp(self.sun, "sc.tz", 0).get()
dougal2@223
  3271
        
dougal2@235
  3272
        self.hour = luxProp(self.sun, "sc.hour", 0).get()
dougal2@235
  3273
        self.min  = luxProp(self.sun, "sc.minute", 0).get()
dougal2@235
  3274
        self.dst  = luxProp(self.sun, "sc.dst", 'false').get()
dougal2@224
  3275
        if self.dst == 'true':
dougal2@224
  3276
            self.dst = 1
dougal2@224
  3277
        else:
dougal2@224
  3278
            self.dst = 0
dougal2@223
  3279
        
dougal2@235
  3280
        self.day   = luxProp(self.sun, "sc.day", 0).get()
dougal2@235
  3281
        self.month = luxProp(self.sun, "sc.month", 0).get()
dougal2@235
  3282
        self.year  = luxProp(self.sun, "sc.year", 0).get()
dougal2@223
  3283
        
dougal2@223
  3284
        
dougal2@224
  3285
        az,el = self.geoSunData(
dougal2@224
  3286
            self.lat,
dougal2@224
  3287
            self.long,
dougal2@224
  3288
            self.year,
dougal2@224
  3289
            self.month,
dougal2@224
  3290
            self.day,
dougal2@224
  3291
            self.hour + self.min/60.0,
dougal2@237
  3292
            -self.tz + self.dst
dougal2@224
  3293
        )
dougal2@224
  3294
        
dougal2@235
  3295
        self.sun.rot = math.radians(90-el), 0, math.radians(-az)
dougal2@223
  3296
        
dougal2@223
  3297
        Window.Redraw()
dougal2@223
  3298
        
dougal2@223
  3299
        
dougal2@224
  3300
    # --- THE FOLLOWING METHODS ARE ADAPTED FROM LUXMAYA ---
dougal2@223
  3301
    
dougal2@224
  3302
    # mathematical helpers
dougal2@224
  3303
    def sind(self, deg):
dougal2@224
  3304
        return math.sin(math.radians(deg))
dougal2@223
  3305
    
dougal2@224
  3306
    def cosd(self, deg):
dougal2@224
  3307
        return math.cos(math.radians(deg))
dougal2@224
  3308
    
dougal2@224
  3309
    def tand(self, deg):
dougal2@224
  3310
        return math.tan(math.radians(deg))
dougal2@224
  3311
    
dougal2@224
  3312
    def asind(self, deg):
dougal2@224
  3313
        return math.degrees(math.asin(deg))
dougal2@224
  3314
    
dougal2@224
  3315
    def atand(self, deg):
dougal2@224
  3316
        return math.degrees(math.atan(deg))
dougal2@224
  3317
    
dougal2@224
  3318
    
dougal2@224
  3319
    def geo_sun_astronomicJulianDate(self, Year, Month, Day, LocalTime, Timezone):
dougal2@224
  3320
        """
dougal2@224
  3321
        See quoted source in class header for explanation
dougal2@224
  3322
        """
dougal2@224
  3323
        
dougal2@224
  3324
        if Month > 2.0:
dougal2@224
  3325
            Y = Year
dougal2@224
  3326
            M = Month
dougal2@224
  3327
        else:
dougal2@224
  3328
            Y = Year - 1.0
dougal2@224
  3329
            M = Month + 12.0
dougal2@224
  3330
            
dougal2@224
  3331
        UT = LocalTime - Timezone
dougal2@224
  3332
        hour = UT / 24.0
dougal2@224
  3333
        A = int(Y/100.0)
dougal2@224
  3334
        B = 2.0 - A+int(A/4.0)
dougal2@224
  3335
        
dougal2@224
  3336
        JD = math.floor(365.25*(Y+4716.0)) + math.floor(30.6001*(M+1.0)) + Day + hour + B - 1524.4
dougal2@224
  3337
        
dougal2@223
  3338
        return JD
dougal2@223
  3339
    
dougal2@224
  3340
    def geoSunData(self, Latitude, Longitude, Year, Month, Day, LocalTime, Timezone):
dougal2@224
  3341
        """
dougal2@224
  3342
        See quoted source in class header for explanation
dougal2@224
  3343
        """
dougal2@224
  3344
        
dougal2@224
  3345
        JD = self.geo_sun_astronomicJulianDate(Year, Month, Day, LocalTime, Timezone)
dougal2@224
  3346
        
dougal2@224
  3347
        phi = Latitude
dougal2@224
  3348
        llambda = Longitude
dougal2@224
  3349
                
dougal2@224
  3350
        n = JD - 2451545.0
dougal2@224
  3351
        LDeg = (280.460 + 0.9856474*n) - (math.floor((280.460 + 0.9856474*n)/360.0) * 360.0)
dougal2@224
  3352
        gDeg = (357.528 + 0.9856003*n) - (math.floor((357.528 + 0.9856003*n)/360.0) * 360.0)
dougal2@224
  3353
        LambdaDeg = LDeg + 1.915 * self.sind(gDeg) + 0.02 * self.sind(2.0*gDeg)
dougal2@224
  3354
        
dougal2@224
  3355
        epsilonDeg = 23.439 - 0.0000004*n
dougal2@224
  3356
        
dougal2@224
  3357
        alphaDeg = self.atand( (self.cosd(epsilonDeg) * self.sind(LambdaDeg)) / self.cosd(LambdaDeg) )
dougal2@224
  3358
        if self.cosd(LambdaDeg) < 0.0:
dougal2@224
  3359
            alphaDeg += 180.0
dougal2@224
  3360
            
dougal2@224
  3361
        deltaDeg = self.asind( self.sind(epsilonDeg) * self.sind(LambdaDeg) )
dougal2@224
  3362
        
dougal2@224
  3363
        JDNull = self.geo_sun_astronomicJulianDate(Year, Month, Day, 0.0, 0.0)
dougal2@224
  3364
        
dougal2@224
  3365
        TNull = (JDNull - 2451545.0) / 36525.0
dougal2@224
  3366
        T = LocalTime - Timezone
dougal2@224
  3367
        
dougal2@224
  3368
        thetaGh = 6.697376 + 2400.05134*TNull + 1.002738*T
dougal2@224
  3369
        thetaGh -= math.floor(thetaGh/24.0) * 24.0
dougal2@224
  3370
        
dougal2@224
  3371
        thetaG = thetaGh * 15.0
dougal2@224
  3372
        theta = thetaG + llambda
dougal2@224
  3373
        
dougal2@224
  3374
        tau = theta - alphaDeg
dougal2@224
  3375
        
dougal2@224
  3376
        a = self.atand( self.sind(tau) / ( self.cosd(tau)*self.sind(phi) - self.tand(deltaDeg)*self.cosd(phi)) )
dougal2@224
  3377
        if self.cosd(tau)*self.sind(phi) - self.tand(deltaDeg)*self.cosd(phi) < 0.0:
dougal2@224
  3378
            a += 180.0
dougal2@224
  3379
        
dougal2@224
  3380
        h = self.asind( self.cosd(deltaDeg)*self.cosd(tau)*self.cosd(phi) + self.sind(deltaDeg)*self.sind(phi) )
dougal2@224
  3381
        
dougal2@224
  3382
        R = 1.02 / (self.tand (h+(10.3/(h+5.11))))
dougal2@224
  3383
        hR = h + R/60.0
dougal2@224
  3384
        
dougal2@224
  3385
        azimuth = a
dougal2@224
  3386
        elevation = hR
dougal2@224
  3387
        
dougal2@224
  3388
        return azimuth, elevation
dougal2@221
  3389
zuegs@21
  3390
def luxAccelerator(scn, gui=None):
dougal2@223
  3391
    str = ""
dougal2@223
  3392
    if scn:
dougal2@223
  3393
        acceltype = luxProp(scn, "accelerator.type", "tabreckdtree")
radiance29@252
  3394
        str = luxIdentifier("Accelerator", acceltype, ["none", "tabreckdtree", "grid", "bvh", "qbvh"], "ACCEL", "select accelerator type", gui)
dougal2@223
  3395
        if acceltype.get() == "tabreckdtree":
dougal2@223
  3396
            if gui: gui.newline()
dougal2@223
  3397
            str += luxInt("intersectcost", luxProp(scn, "accelerator.kdtree.interscost", 80), 0, 1000, "inters.cost", "specifies how expensive ray-object intersections are", gui)
dougal2@223
  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)
dougal2@223
  3399
            if gui: gui.newline()
dougal2@223
  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)
dougal2@223
  3401
            if gui: gui.newline()
dougal2@223
  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)
dougal2@223
  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)
dougal2@223
  3404
        if acceltype.get() == "unsafekdtree":
dougal2@223
  3405
            if gui: gui.newline()
dougal2@223
  3406
            str += luxInt("intersectcost", luxProp(scn, "accelerator.kdtree.interscost", 80), 0, 1000, "inters.cost", "specifies how expensive ray-object intersections are", gui)
dougal2@223
  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)
dougal2@223
  3408
            if gui: gui.newline()
dougal2@223
  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)
dougal2@223
  3410
            if gui: gui.newline()
dougal2@223
  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)
dougal2@223
  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)
dougal2@223
  3413
        if acceltype.get() == "grid":
dougal2@223
  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)
radiance29@252
  3415
        if acceltype.get() == "qbvh":
radiance29@252
  3416
            if gui: gui.newline()
radiance29@252
  3417
            str += luxInt("maxprimsperleaf", luxProp(scn, "accelerator.qbvh.maxprimsperleaf", 4), 1, 64, "maxprimsperleaf", "Maximum number of primitives to leave in one leaf node", gui)
dougal2@223
  3418
    return str
zuegs@21
  3419
zuegs@21
  3420
def luxSystem(scn, gui=None):
dougal2@223
  3421
    if scn:
dougal2@223
  3422
        if gui: gui.newline("PATHS:", 10)
dougal2@223
  3423
        lp = luxProp(scn, "lux", "")
dougal2@223
  3424
        lp.set(Blender.sys.dirname(lp.get())+os.sep)
dougal2@223
  3425
        luxPath("LUX dir", lp, "lux binary dir", "Lux installation path", gui, 2.0)
dougal2@223
  3426
dougal2@223
  3427
#        luxFile("GUI filename", luxProp(scn, "lux", ""), "lux-file", "filename and path of the lux GUI executable", gui, 2.0)
dougal2@223
  3428
#        luxFile("Console filename", luxProp(scn, "luxconsole", ""), "lux-file-console", "filename and path of the lux console executable", gui, 2.0)
dougal2@223
  3429
        if gui: gui.newline()
dougal2@223
  3430
        luxFile("datadir", luxProp(scn, "datadir", ""), "default out dir", "default.lxs save path", gui, 2.0)
dougal2@223
  3431
zuegs@255
  3432
        if gui: gui.newline()
zuegs@255
  3433
        pm = ["absolute","relative","flat"]
zuegs@255
  3434
        luxOption("pathmode", luxProp(scn, "pathmode", "absolute"), pm, "path-mode", "select format for paths on export", gui, 2.0)
zuegs@255
  3435
dougal2@223
  3436
        if gui: gui.newline("PRIORITY:", 10)
radiance29@249
  3437
        luxnice = luxProp(scn, "luxnice", 10)
dougal2@223
  3438
        if osys.platform=="win32":
dougal2@223
  3439
            r = gui.getRect(2, 1)
dougal2@223
  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))
doug@307
  3441
        else: luxInt("nice", luxnice, -20, 19, "nice", "nice value. Range goes from -20 (highest priority) to 19 (lowest)", gui)
doug@307
  3442
doug@307
  3443
        luxBool("noopengl", luxProp(scn, "noopengl", "false"), "Disable OpenGL", "(workaround for some buggy display drivers)", gui, 1.0)
doug@307
  3444
dougal2@223
  3445
dougal2@223
  3446
        if gui: gui.newline("THREADS:", 10)
dougal2@223
  3447
        autothreads = luxProp(scn, "autothreads", "true")
dougal2@223
  3448
        luxBool("autothreads", autothreads, "Auto Detect", "Automatically use all available processors", gui, 1.0)
dougal2@223
  3449
        if autothreads.get()=="false":
dougal2@223
  3450
            luxInt("threads", luxProp(scn, "threads", 1), 1, 100, "threads", "number of threads used for rendering", gui, 1.0)
dougal2@223
  3451
dougal2@223
  3452
        if gui: gui.newline("ANIM:", 10)
dougal2@223
  3453
        useparamkeys = luxProp(scn, "useparamkeys", "false")
dougal2@223
  3454
        luxBool("useparamkeys", useparamkeys, "Enable Parameter IPO Keyframing", "Enables keyframing of luxblend parameters", gui, 2.0)
dougal2@223
  3455
dougal2@223
  3456
        if gui: gui.newline("PARAMS:", 10)
dougal2@223
  3457
        parammodeadvanced = luxProp(scn, "parammodeadvanced", "false")
dougal2@223
  3458
        luxBool("parammodeadvanced", parammodeadvanced, "Default Advanced Parameters", "Always use advanced parameters by default", gui, 2.0)
dougal2@223
  3459
dougal2@223
  3460
        if gui: gui.newline("PREVIEW:", 10)
dougal2@223
  3461
        qs = ["low","medium","high","very high"]
dougal2@223
  3462
        defprevmat = luxProp(scn, "defprevmat", "high")
dougal2@223
  3463
        luxOption("defprevmat", defprevmat, qs, "Materials", "Select default preview quality in material editor for materials", gui, 1.0)
dougal2@223
  3464
dougal2@223
  3465
        if gui: gui.newline("GAMMA:", 10)
dougal2@223
  3466
        luxBool("RGC", luxProp(scn, "RGC", "true"), "RGC", "use reverse gamma correction", gui)
dougal2@223
  3467
        luxBool("ColClamp", luxProp(scn, "colorclamp", "false"), "ColClamp", "clamp all colors to 0.0-0.9", gui)
dougal2@223
  3468
        if gui: gui.newline("MESH:", 10)
dougal2@223
  3469
        luxBool("mesh_optimizing", luxProp(scn, "mesh_optimizing", "true"), "optimize meshes", "Optimize meshes during export", gui, 2.0)
dougal2@223
  3470
        #luxInt("trianglemesh thr", luxProp(scn, "trianglemesh_thr", 0), 0, 10000000, "trianglemesh threshold", "Vertex threshold for exporting (wald) trianglemesh object(s)", gui, 2.0)
dougal2@223
  3471
        #if gui: gui.newline()
dougal2@223
  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)
dougal2@223
  3473
        if gui: gui.newline("INSTANCING:", 10)
tomb@251
  3474
        luxInt("instancing_threshold", luxProp(scn, "instancing_threshold", 2), 0, 1000000, "object instancing threshold", "Threshold to created instanced objects", gui, 2.0)
dougal2@258
  3475
        
dougal2@258
  3476
        # dougal2 packed images, enable this when implemented in Lux itself
dougal2@258
  3477
        #if gui: gui.newline('TEXTURES:',10)
dougal2@258
  3478
        #impack = luxProp(scn, 'packtextures', 'false')
dougal2@258
  3479
        #luxBool('impack', impack, 'Pack All Images', '', gui, 2.0)
dougal2@258
  3480
        
dougal2@257
  3481
        if gui: 
dougal2@259
  3482
            network=luxProp(scn,"network","false")
dougal2@259
  3483
            gui.newline("NETWORK:", 10)
dougal2@259
  3484
            luxCollapse("network",network, "network", "enable network option", gui, 2.0)
dougal2@259
  3485
            if(network.get() == "true"):
dougal2@259
  3486
                network_use_file=luxProp(scn,"network_use_file","false")
dougal2@259
  3487
                luxBool ("use file",network_use_file,"use file", "get list of servers from file; one per line",gui,2.0)
dougal2@259
  3488
                if (network_use_file.get() == "true"):
dougal2@259
  3489
                    luxFile("file", luxProp(scn, "network_file_path", ""), "file", "file where servers are defined", gui, 1.0)         
dougal2@259
  3490
                else :     
dougal2@259
  3491
                    #gui.newline("")
dougal2@259
  3492
                    luxString("Servers",luxProp(scn,"network_servers",""),"servers","coma separated list of servers",gui,1.0)
dougal2@259
  3493
                #gui.newline("")
dougal2@259
  3494
                luxInt("network_interval",luxProp(scn,"newtork_interval",180),0,300,"update interval","interval between network refresh",gui)
zuegs@21
  3495
zuegs@21
  3496
zuegs@47
  3497
def scalelist(list, factor):
dougal2@223
  3498
    for i in range(len(list)): list[i] = list[i] * factor
dougal2@223
  3499
    return list
zuegs@21
  3500
zuegs@21
  3501
zuegs@39
  3502
def luxMapping(key, mat, gui, level=0):
dougal2@223
  3503
    global icon_map2d, icon_map2dparam
dougal2@223
  3504
    if gui: gui.newline("2Dmap:", -2, level, icon_map2d)
dougal2@223
  3505
    mapping = luxProp(mat, key+".mapping", "uv")
dougal2@223
  3506
    mappings = ["uv","spherical","cylindrical","planar"]
dougal2@223
  3507
    str = luxOption("mapping", mapping, mappings, "mapping", "", gui, 0.5)
dougal2@223
  3508
    if mapping.get() == "uv":
dougal2@223
  3509
        str += luxFloat("uscale", luxProp(mat, key+".uscale", 1.0), -100.0, 100.0, "Us", "u-scale", gui, 0.375)
dougal2@223
  3510
        str += luxFloat("vscale", luxProp(mat, key+".vscale", -1.0), -100.0, 100.0, "Vs", "v-scale", gui, 0.375)
dougal2@223
  3511
        str += luxFloat("udelta", luxProp(mat, key+".udelta", 0.0), -100.0, 100.0, "Ud", "u-delta", gui, 0.375)
dougal2@223
  3512
        str += luxFloat("vdelta", luxProp(mat, key+".vdelta", 0.0), -100.0, 100.0, "Vd", "v-delta", gui, 0.375)
dougal2@223
  3513
    if mapping.get() == "planar":
dougal2@223
  3514
        str += luxFloat("udelta", luxProp(mat, key+".udelta", 0.0), -100.0, 100.0, "Ud", "u-delta", gui, 0.75)
dougal2@223
  3515
        str += luxFloat("vdelta", luxProp(mat, key+".vdelta", 0.0), -100.0, 100.0, "Vd", "v-delta", gui, 0.75)
dougal2@223
  3516
        if gui: gui.newline("v1:", -2, level+1, icon_map2dparam)
dougal2@223
  3517
        str += luxVector("v1", luxProp(mat, key+".v1", "1 0 0"), -100.0, 100.0, "v1", "v1-vector", gui, 2.0)
dougal2@223
  3518
        if gui: gui.newline("v2:", -2, level+1, icon_map2dparam)
dougal2@223
  3519
        str += luxVector("v2", luxProp(mat, key+".v2", "0 1 0"), -100.0, 100.0, "v2", "v2-vector", gui, 2.0)
dougal2@223
  3520
    return str
zuegs@39
  3521
radiance29@42
  3522
def lux3DMapping(key, mat, gui, level=0):
dougal2@223
  3523
    global icon_map3dparam
dougal2@223
  3524
    str = ""
dougal2@223
  3525
    if gui: gui.newline("scale:", -2, level, icon_map3dparam)
dougal2@223
  3526
    str += luxVectorUniform("scale", luxProp(mat, key+".3dscale", 1.0), 0.001, 1000.0, "scale", "scale-vector", gui, 2.0)
dougal2@223
  3527
    if gui: gui.newline("rot:", -2, level, icon_map3dparam)
dougal2@223
  3528
    str += luxVector("rotate", luxProp(mat, key+".3drotate", "0 0 0"), -360.0, 360.0, "rotate", "rotate-vector", gui, 2.0)
dougal2@223
  3529
    if gui: gui.newline("move:", -2, level, icon_map3dparam)
dougal2@223
  3530
    str += luxVector("translate", luxProp(mat, key+".3dtranslate", "0 0 0"), -1000.0, 1000.0, "move", "translate-vector", gui, 2.0)
dougal2@223
  3531
    return str
dougal2@223
  3532
    
dougal2@240
  3533
def getTreeNameById(tree, i): # helper function to retrive name of the selected treemenu-item
dougal2@240
  3534
    for t in tree:
dougal2@240
  3535
        if type(t)==types.TupleType:
dougal2@240
  3536
            if type(t[1])==types.ListType: 
dougal2@240
  3537
                n=getTreeNameById(t[1], i)
dougal2@240
  3538
                if n: return n
dougal2@240
  3539
            elif t[1]==i: return t[0]
dougal2@240
  3540
    return None    
zuegs@39
  3541
radiance29@155
  3542
def luxTexture(name, parentkey, type, default, min, max, caption, hint, mat, gui, matlevel, texlevel=0, lightsource=0, overrideicon=""):
dougal2@223
  3543
    global icon_tex, icon_texcol, icon_texmix, icon_texmixcol, icon_texparam, icon_spectex
dougal2@223
  3544
    def c(t1, t2):
dougal2@223
  3545
        return (t1[0]+t2[0], t1[1]+t2[1])
dougal2@223
  3546
    def alternativedefault(type, default):
dougal2@223
  3547
        if type=="float": return 0.0
dougal2@223
  3548
        else: return "0.0 0.0 0.0"
dougal2@223
  3549
    level = matlevel + texlevel
dougal2@223
  3550
    keyname = "%s:%s"%(parentkey, name)
dougal2@223
  3551
    texname = "%s:%s"%(mat.getName(), keyname)
dougal2@223
  3552
#    if gui: gui.newline(caption+":", 0, level)
dougal2@223
  3553
    if(lightsource == 0):
dougal2@223
  3554
        if texlevel == 0: texture = luxProp(mat, keyname+".texture", "imagemap")
dougal2@223
  3555
        else: texture = luxProp(mat, keyname+".texture", "constant")
dougal2@223
  3556
    else:
dougal2@223
  3557
        texture = luxProp(mat, keyname+".texture", "blackbody")
dougal2@223
  3558
dougal2@240
  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"]
dougal2@223
  3560
dougal2@223
  3561
    if gui:
dougal2@223
  3562
        if(overrideicon != ""):
dougal2@223
  3563
            icon = overrideicon
dougal2@223
  3564
        else:
dougal2@223
  3565
            icon = icon_tex
dougal2@223
  3566
            if texture.get() in ["mix", "scale", "checkerboard", "dots"]:
dougal2@223
  3567
                if type=="color": icon = icon_texmixcol
dougal2@223
  3568
                else: icon = icon_texmix
dougal2@223
  3569
            elif texture.get() in ["constant", "blackbody", "equalenergy", "frequency", "gaussian", "regulardata", "irregulardata"]:
dougal2@223
  3570
                icon = icon_spectex
dougal2@223
  3571
            else:
dougal2@223
  3572
                if type=="color": icon = icon_texcol
dougal2@223
  3573
                else: icon = icon_tex
dougal2@223
  3574
        if (texlevel > 0): gui.newline(caption+":", -2, level, icon, scalelist([0.5,0.5,0.5],2.0/(level+2)))
dougal2@223
  3575
        else: gui.newline("texture:", -2, level, icon, scalelist([0.5,0.5,0.5],2.0/(level+2)))
dougal2@223
  3576
    luxOption("texture", texture, textures, "texture", "", gui, 0.9)
dougal2@223
  3577
    str = "Texture \"%s\" \"%s\" \"%s\""%(texname, type, texture.get())
dougal2@223
  3578
dougal2@223
  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))
dougal2@223
  3580
    if gui: # Draw Texture level Material preview
dougal2@223
  3581
        luxPreview(mat, parentkey, 1, False, False, name, gui, texlevel, [0.5, 0.5, 0.5])
dougal2@223
  3582
        # Add an offset for next controls
dougal2@223
  3583
        #r = gui.getRect(1.0, 1)
dougal2@223
  3584
        #gui.x += 140
dougal2@223
  3585
dougal2@223
  3586
    if texture.get() == "constant":
dougal2@223
  3587
        value = luxProp(mat, keyname+".value", default)
dougal2@223
  3588
        if type == "float": luxFloat("value", value, min, max, "", "", gui, 1.1)
dougal2@223
  3589
        elif type == "color": luxRGB("value", value, max, "", "", gui, 1.1)
zuegs@39
  3590
# direct version
dougal2@223
  3591
        if type == "color": return ("", " \"%s %s\" [%s]"%(type, name, value.getRGC()))
dougal2@223
  3592
        return ("", " \"%s %s\" [%s]"%(type, name, value.get()))
zuegs@39
  3593
# indirect version
dougal2@223
  3594
#        if type == "color": str += " \"%s value\" [%s]"%(type, value.getRGC())
dougal2@223
  3595
#        else: str += " \"%s value\" [%s]"%(type, value.get())
dougal2@223
  3596
dougal2@223
  3597
    if texture.get() == "blackbody":
dougal2@223
  3598
        if gui:
dougal2@223
  3599
            if gui.xmax-gui.x < gui.w: gui.newline()
dougal2@223
  3600
            r = gui.getRect(1.0, 1)
dougal2@223
  3601
            gui.newline()
dougal2@223
  3602
            drawBar(bar_blackbody, gui.xmax-gui.w-7, r[1])
dougal2@223
  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)
dougal2@223
  3604
dougal2@240
  3605
    if texture.get() == "lampspectrum":
dougal2@240
  3606
        lampstring = luxProp(mat, keyname+".lampstring", "Incandescent2")
dougal2@240
  3607
        lamppreset = luxProp(mat, keyname+".lampspectrum", "PHILIPS [Argenta] 200W Incandescent Lamp")
dougal2@240
  3608
        if gui:
dougal2@240
  3609
            def setLamp(i, value, preset, tree, dict): # callback function to set ior value after selection
dougal2@240
  3610
                if i >= 0:
dougal2@240
  3611
                    value.set(dict[i])
dougal2@240
  3612
                    preset.set(getTreeNameById(tree, i))
dougal2@240
  3613
jensverwiebe@323
  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) ] ) ] 
dougal2@240
  3615
dougal2@240
  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" }
dougal2@240
  3617
dougal2@240
  3618
            r = gui.getRect(2.0, 1)
dougal2@240
  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))
dougal2@258
  3620
        str += luxString("name", lampstring, "Lamp", "Choose measured Lamp Spectrum", None, 2.0)
dougal2@240
  3621
dougal2@223
  3622
    if texture.get() == "equalenergy":
dougal2@223
  3623
        if gui:
dougal2@223
  3624
            if gui.xmax-gui.x < gui.w: gui.newline()
dougal2@223
  3625
            r = gui.getRect(1.0, 1)
dougal2@223
  3626
            gui.newline()
dougal2@223
  3627
            drawBar(bar_equalenergy, gui.xmax-gui.w-7, r[1])
dougal2@223
  3628
        str += luxFloat("energy", luxProp(mat, keyname+".energy", 1.0), 0.0, 1.0, "energy", "Energy of each spectral band", gui, 2.0, 1)
dougal2@223
  3629
dougal2@223
  3630
    if texture.get() == "frequency":
doug@312
  3631
        str += luxFloat("freq", luxProp(mat, keyname+".freq", 0.01), 0.01, 100.0, "frequency", "Frequency in nm", gui, 2.0, 1)
dougal2@223
  3632
        str += luxFloat("phase", luxProp(mat, keyname+".phase", 0.5), 0.0, 1.0, "phase", "Phase", gui, 1.1, 1)
dougal2@223
  3633
        str += luxFloat("energy", luxProp(mat, keyname+".energy", 1.0), 0.0, 1.0, "energy", "Amount of mean energy", gui, 0.9, 1)
dougal2@223
  3634
dougal2@223
  3635
    if texture.get() == "gaussian":
dougal2@223
  3636
        if gui:
dougal2@223
  3637
            if gui.xmax-gui.x < gui.w: gui.newline()
dougal2@223
  3638
            r = gui.getRect(1.0, 1)
dougal2@223
  3639
            gui.newline()
dougal2@223
  3640
            drawBar(bar_spectrum, gui.xmax-gui.w-7, r[1])
dougal2@223
  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)
dougal2@223
  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)
dougal2@223
  3643
        str += luxFloat("energy", luxProp(mat, keyname+".energy", 1.0), 0.0, 1.0, "energy", "Amount of mean energy", gui, 0.9, 1)
dougal2@223
  3644
dougal2@223
  3645
    if texture.get() == "imagemap":
dougal2@223
  3646
        str += luxOption("wrap", luxProp(mat, keyname+".wrap", "repeat"), ["repeat","black","clamp"], "repeat", "", gui, 1.1)
radiance29@245
  3647
dougal2@261
  3648
        # ZANQDO
dougal2@261
  3649
        texturefilename = luxProp(mat, keyname+".filename", "")
dougal2@261
  3650
        luxFile("filename", texturefilename, "file", "texture file path", gui, 2.0)
dougal2@261
  3651
        # dougal2 image file packing
dougal2@261
  3652
        impack = luxProp(Scene.GetCurrent(), 'packtextures', 'false')
dougal2@261
  3653
        
dougal2@261
  3654
        if impack.get() == 'false':
dougal2@261
  3655
            str += luxFile("filename", texturefilename, "file", "texture file path", None, 2.0)
dougal2@261
  3656
        else:
dougal2@261
  3657
            import zlib, base64
dougal2@261
  3658
            def get_image_data(filename):
dougal2@261
  3659
                try:
dougal2@261
  3660
                    f=open(filename,'rb')
dougal2@261
  3661
                    d=f.read()
dougal2@261
  3662
                    f.close()
dougal2@261
  3663
                except:
dougal2@261
  3664
                    print 'Error reading image data from %s' % filename
dougal2@261
  3665
                    d = ''
dougal2@261
  3666
                return base64.b64encode(zlib.compress(d))
dougal2@261
  3667
            imdata = get_image_data(texturefilename.get())
dougal2@261
  3668
            str += '\r\n   "string imagedata" ["%s"]' % imdata
dougal2@261
  3669
        
dougal2@261
  3670
        useseq = luxProp(mat, keyname+".useseq", "false")
dougal2@261
  3671
        luxCollapse("usesew", useseq, "Sequence", "", gui, 2.0)
dougal2@258
  3672
    
dougal2@261
  3673
        if useseq.get() == "true":
dougal2@261
  3674
            seqframes = luxProp(mat, keyname+".seqframes", 100)
dougal2@261
  3675
            luxInt("frames", seqframes, 1, 100000, "Frames", "", gui, 0.5)
dougal2@261
  3676
            seqoffset = luxProp(mat, keyname+".seqoffset", 0)
dougal2@261
  3677
            luxInt("offset", seqoffset, 0, 100000, "Offset", "", gui, 0.5)
dougal2@261
  3678
            seqstartframe = luxProp(mat, keyname+".seqsframe", 1)
dougal2@261
  3679
            luxInt("startframe", seqstartframe, 1, 100000, "StartFr", "", gui, 0.5)
dougal2@261
  3680
            seqcyclic = luxProp(mat, keyname+".seqcycl", "false")
dougal2@261
  3681
            luxBool("cyclic", seqcyclic, "Cyclic", "", gui, 0.5)
dougal2@258
  3682
    
dougal2@261
  3683
            
dougal2@261
  3684
            totalframes = seqframes.get()
dougal2@261
  3685
            currentframe = Blender.Get('curframe')
dougal2@261
  3686
    
dougal2@261
  3687
            if(currentframe < seqstartframe.get()):
dougal2@261
  3688
                fnumber = 1 + seqoffset.get()
dougal2@258
  3689
            else:
dougal2@261
  3690
                fnumber = (currentframe - (seqstartframe.get()-1)) + seqoffset.get()
dougal2@261
  3691
    
dougal2@261
  3692
            if(fnumber > seqframes.get()):
dougal2@261
  3693
                if(seqcyclic.get() == "false"):
dougal2@261
  3694
                    fnumber = seqframes.get()
dougal2@261
  3695
                else:
dougal2@261
  3696
                    fnumber = currentframe % seqframes.get()
dougal2@261
  3697
    
dougal2@261
  3698
            import re
dougal2@261
  3699
            def get_seq_filename(number, filename):
dougal2@261
  3700
                m = re.findall(r'(\d+)', filename)
dougal2@261
  3701
                if len(m) == 0:
dougal2@261
  3702
                    return "ERR: Can't find pattern"
dougal2@261
  3703
    
dougal2@261
  3704
                rightmost_number = m[len(m)-1]
dougal2@261
  3705
                seq_length = len(rightmost_number)
dougal2@261
  3706
    
dougal2@261
  3707
                nstr = "%i" %number
dougal2@261
  3708
                new_seq_number = nstr.zfill(seq_length)
dougal2@261
  3709
     
dougal2@261
  3710
                return filename.replace(rightmost_number, new_seq_number)
dougal2@261
  3711
     
dougal2@261
  3712
            texturefilename.set(get_seq_filename(fnumber, texturefilename.get()))
dougal2@261
  3713
            if gui: gui.newline()
dougal2@261
  3714
    
dougal2@262
  3715
        str += luxFloat("gamma", luxProp(mat, keyname+".gamma", texturegamma()), 0.0, 6.0, "gamma", "", gui, 0.75)
dougal2@262
  3716
        str += luxFloat("gain", luxProp(mat, keyname+".gain", 1.0), 0.0, 10.0, "gain", "", gui, 0.5)
dougal2@262
  3717
        filttype = luxProp(mat, keyname+".filtertype", "bilinear")
dougal2@262
  3718
        filttypes = ["mipmap_ewa","mipmap_trilinear","bilinear","nearest"]
dougal2@262
  3719
        str += luxOption("filtertype", filttype, filttypes, "filtertype", "Choose the filtering method to use for the image texture", gui, 0.75)
dougal2@262
  3720
        
dougal2@263
  3721
        if filttype.get() == "mipmap_ewa" or filttype.get() == "mipmap_trilinear":    
dougal2@262
  3722
            str += luxFloat("maxanisotropy", luxProp(mat, keyname+".maxanisotropy", 8.0), 1.0, 512.0, "maxaniso", "", gui, 1.0)
dougal2@262
  3723
            str += luxInt("discardmipmaps", luxProp(mat, keyname+".discardmipmaps", 0), 0, 1, "discardmips", "", gui, 1.0)
dougal2@261
  3724
    
dougal2@262
  3725
        str += luxMapping(keyname, mat, gui, level+1)
dougal2@223
  3726
dougal2@223
  3727
    if texture.get() == "mix":
dougal2@223
  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))
dougal2@223
  3729
        (s, l) = c((s, l), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  3730
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  3731
        str = s + str + l
dougal2@223
  3732
dougal2@223
  3733
    if texture.get() == "scale":
dougal2@223
  3734
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  3735
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  3736
        str = s + str + l
dougal2@223
  3737
dougal2@223
  3738
    if texture.get() == "bilerp":
dougal2@223
  3739
        if type == "float":
dougal2@223
  3740
            str += luxFloat("v00", luxProp(mat, keyname+".v00", 0.0), min, max, "v00", "", gui, 1.0)
dougal2@223
  3741
            str += luxFloat("v01", luxProp(mat, keyname+".v01", 1.0), min, max, "v01", "", gui, 1.0)
dougal2@223
  3742
            if gui: gui.newline("", -2)
dougal2@223
  3743
            str += luxFloat("v10", luxProp(mat, keyname+".v10", 0.0), min, max, "v10", "", gui, 1.0)
dougal2@223
  3744
            str += luxFloat("v11", luxProp(mat, keyname+".v11", 1.0), min, max, "v11", "", gui, 1.0)
dougal2@223
  3745
        elif type == "color":
dougal2@223
  3746
            if gui: gui.newline("          v00:", -2)
dougal2@223
  3747
            str += luxRGB("v00", luxProp(mat, keyname+".v00", "0.0 0.0 0.0"), max, "v00", "", gui, 2.0)
dougal2@223
  3748
            if gui: gui.newline("          v01:", -2)
dougal2@223
  3749
            str += luxRGB("v01", luxProp(mat, keyname+".v01", "1.0 1.0 1.0"), max, "v01", "", gui, 2.0)
dougal2@223
  3750
            if gui: gui.newline("          v10:", -2)
dougal2@223
  3751
            str += luxRGB("v10", luxProp(mat, keyname+".v10", "0.0 0.0 0.0"), max, "v10", "", gui, 2.0)
dougal2@223
  3752
            if gui: gui.newline("          v11:", -2)
dougal2@223
  3753
            str += luxRGB("v11", luxProp(mat, keyname+".v11", "1.0 1.0 1.0"), max, "v11", "", gui, 2.0)
dougal2@223
  3754
        str += luxMapping(keyname, mat, gui, level+1)
dougal2@223
  3755
dougal2@223
  3756
    if texture.get() == "windy":
dougal2@223
  3757
        str += lux3DMapping(keyname, mat, gui, level+1)
dougal2@223
  3758
        # this texture has no options 
dougal2@223
  3759
dougal2@223
  3760
    if texture.get() == "checkerboard":
dougal2@223
  3761
        dim = luxProp(mat, keyname+".dim", 2)
dougal2@223
  3762
        str += luxInt("dimension", dim, 2, 3, "dim", "", gui, 0.5)
dougal2@223
  3763
        if dim.get() == 2: str += luxOption("aamode", luxProp(mat, keyname+".aamode", "closedform"), ["closedform","supersample","none"], "aamode", "antialiasing mode", gui, 0.6)
dougal2@223
  3764
        if gui: gui.newline("", -2)
dougal2@223
  3765
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  3766
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  3767
        str = s + str + l
dougal2@223
  3768
        if dim.get() == 2: str += luxMapping(keyname, mat, gui, level+1) 
dougal2@223
  3769
        if dim.get() == 3: str += lux3DMapping(keyname, mat, gui, level+1)
dougal2@223
  3770
dougal2@223
  3771
    if texture.get() == "dots":
dougal2@223
  3772
        (s, l) = c(("", ""), luxTexture("inside", keyname, type, default, min, max, "inside", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  3773
        (s, l) = c((s, l), luxTexture("outside", keyname, type, alternativedefault(type, default), min, max, "outside", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  3774
        str = s + str + l
dougal2@223
  3775
        str += luxMapping(keyname, mat, gui, level+1)
dougal2@223
  3776
dougal2@223
  3777
    if texture.get() == "fbm":
dougal2@223
  3778
        str += luxInt("octaves", luxProp(mat, keyname+".octaves", 8), 1, 100, "octaves", "", gui, 1.1)
dougal2@223
  3779
        if gui: gui.newline("", -2)
dougal2@223
  3780
        str += luxFloat("roughness", luxProp(mat, keyname+".roughness", 0.5), 0.0, 1.0, "roughness", "", gui, 2.0, 1)
dougal2@223
  3781
        if gui: gui.newline("", -2)
dougal2@223
  3782
        str += lux3DMapping(keyname, mat, gui, level+1)
dougal2@223
  3783
dougal2@223
  3784
    if texture.get() == "marble":
dougal2@223
  3785
        str += luxInt("octaves", luxProp(mat, keyname+".octaves", 8), 1, 100, "octaves", "", gui, 1.1)
dougal2@223
  3786
        if gui: gui.newline("", -2)
dougal2@223
  3787
        str += luxFloat("roughness", luxProp(mat, keyname+".roughness", 0.5), 0.0, 1.0, "roughness", "", gui, 2.0, 1)
dougal2@223
  3788
        if gui: gui.newline("", -2)
dougal2@223
  3789
        str += luxFloat("nscale", luxProp(mat, keyname+".nscale", 1.0), 0.0, 100.0, "nscale", "Scaling factor for the noise input", gui, 1.0)
dougal2@223
  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)
dougal2@223
  3791
        if gui: gui.newline("", -2)
dougal2@223
  3792
        str += lux3DMapping(keyname, mat, gui, level+1)
dougal2@223
  3793
dougal2@223
  3794
    if texture.get() == "wrinkled":
dougal2@223
  3795
        str += luxInt("octaves", luxProp(mat, keyname+".octaves", 8), 1, 100, "octaves", "", gui, 1.1)
dougal2@223
  3796
        if gui: gui.newline("", -2)
dougal2@223
  3797
        str += luxFloat("roughness", luxProp(mat, keyname+".roughness", 0.5), 0.0, 1.0, "roughness", "", gui, 2.0, 1)
dougal2@223
  3798
        if gui: gui.newline("", -2)
dougal2@223
  3799
        str += lux3DMapping(keyname, mat, gui, level+1)
dougal2@223
  3800
dougal2@223
  3801
    if texture.get() == "brick":
dougal2@223
  3802
        if gui: gui.newline("brick:", -2, level+1, icon_texparam)
dougal2@223
  3803
dougal2@223
  3804
        str += luxFloat("brickwidth", luxProp(mat, keyname+".brickwidth", 0.3), 0.0, 10.0, "brickwidth (X)", "", gui, 1.0)
dougal2@223
  3805
        str += luxFloat("brickheight", luxProp(mat, keyname+".brickheight", 0.1), 0.0, 10.0, "brickheight (Z)", "", gui, 1.0)
dougal2@223
  3806
        str += luxFloat("brickdepth", luxProp(mat, keyname+".brickdepth", 0.15), 0.0, 10.0, "brickdepth (Y)", "", gui, 1.0)
dougal2@223
  3807
dougal2@223
  3808
        if gui: gui.newline("mortar:", -2, level+1, icon_texparam)
dougal2@223
  3809
dougal2@223
  3810
        str += luxFloat("mortarsize", luxProp(mat, keyname+".mortarsize", 0.01), 0.0, 1.0, "mortarsize", "", gui, 1.0)
dougal2@223
  3811
dougal2@223
  3812
        (s, l) = c(("", ""), luxTexture("bricktex", keyname, type, default, min, max, "bricktex", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  3813
        (s, l) = c((s, l), luxTexture("mortartex", keyname, type, alternativedefault(type, default), min, max, "mortartex", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  3814
        str = s + str + l
dougal2@223
  3815
dougal2@223
  3816
        str += lux3DMapping(keyname, mat, gui, level+1)
dougal2@223
  3817
dougal2@223
  3818
    if texture.get() == "blender_marble":
dougal2@223
  3819
        if gui: gui.newline("noise:", -2, level+1, icon_texparam)
dougal2@223
  3820
dougal2@223
  3821
        mtype = luxProp(mat, keyname+".mtype", "soft")
dougal2@223
  3822
        mtypes = ["soft","sharp","sharper"]
dougal2@223
  3823
        str += luxOption("type", mtype, mtypes, "type", "", gui, 0.5)
dougal2@223
  3824
dougal2@223
  3825
        noisetype = luxProp(mat, keyname+".noisetype", "hard_noise")
dougal2@223
  3826
        noisetypes = ["soft_noise","hard_noise"]
dougal2@223
  3827
        str += luxOption("noisetype", noisetype, noisetypes, "noisetypes", "", gui, 0.75)
dougal2@223
  3828
dougal2@223
  3829
        str += luxInt("noisedepth", luxProp(mat, keyname+".noisedepth", 2), 0, 6, "noisedepth", "", gui, 0.75)
dougal2@223
  3830
dougal2@223
  3831
        str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 2.0, "noisesize", "", gui, 1.0)
dougal2@223
  3832
        str += luxFloat("turbulance", luxProp(mat, keyname+".turbulance", 5.0), 0.0, 200.0, "turbulance", "", gui, 1.0)
dougal2@223
  3833
dougal2@223
  3834
        if gui: gui.newline("basis:", -2, level+1, icon_texparam)
dougal2@223
  3835
        noisebasis2 = luxProp(mat, keyname+".noisebasis2", "sin")
dougal2@223
  3836
        noisebasises2 = ["sin","saw","tri"]
dougal2@223
  3837
        str += luxOption("noisebasis2", noisebasis2, noisebasises2, "noisebasis2", "", gui, 0.7)
dougal2@223
  3838
dougal2@223
  3839
        noisebasis = luxProp(mat, keyname+".noisebasis", "blender_original")
dougal2@223
  3840
        noisebasises = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
dougal2@223
  3841
        str += luxOption("noisebasis", noisebasis, noisebasises, "noisebasis", "", gui, 1.3)
dougal2@223
  3842
dougal2@223
  3843
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
dougal2@223
  3844
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
dougal2@223
  3845
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
dougal2@223
  3846
dougal2@223
  3847
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  3848
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  3849
        str = s + str + l
dougal2@223
  3850
dougal2@223
  3851
        str += lux3DMapping(keyname, mat, gui, level+1)
dougal2@223
  3852
dougal2@223
  3853
    if texture.get() == "blender_musgrave":
dougal2@223
  3854
        if gui: gui.newline("type:", -2, level+1, icon_texparam)
dougal2@223
  3855
        mtype = luxProp(mat, keyname+".mtype", "multifractal")
dougal2@223
  3856
        mtypes = ["multifractal","ridged_multifractal", "hybrid_multifractal", "hetero_terrain", "fbm"]
dougal2@223
  3857
        str += luxOption("type", mtype, mtypes, "type", "", gui, 2.0)
dougal2@223
  3858
dougal2@223
  3859
        str += luxFloat("h", luxProp(mat, keyname+".h", 1.0), 0.0, 2.0, "h", "", gui, 0.5)
dougal2@223
  3860
        str += luxFloat("lacu", luxProp(mat, keyname+".lacu", 2.0), 0.0, 6.0, "lacu", "", gui, 0.75)
dougal2@223
  3861
        str += luxFloat("octs", luxProp(mat, keyname+".octs", 2.0), 0.0, 8.0, "octs", "", gui, 0.75)
dougal2@223
  3862
dougal2@223
  3863
        if mtype.get() == "hetero_terrain":
dougal2@223
  3864
            str += luxFloat("offset", luxProp(mat, keyname+".offset", 2.0), 0.0, 6.0, "offset", "", gui, 2.0)
dougal2@223
  3865
        if mtype.get() == "ridged_multifractal":
dougal2@223
  3866
            str += luxFloat("offset", luxProp(mat, keyname+".offset", 2.0), 0.0, 6.0, "offset", "", gui, 1.25)
dougal2@223
  3867
            str += luxFloat("gain", luxProp(mat, keyname+".gain", 2.0), 0.0, 6.0, "gain", "", gui, 0.75)
dougal2@223
  3868
        if mtype.get() == "hybrid_multifractal":
dougal2@223
  3869
            str += luxFloat("offset", luxProp(mat, keyname+".offset", 2.0), 0.0, 6.0, "offset", "", gui, 1.25)
dougal2@223
  3870
            str += luxFloat("gain", luxProp(mat, keyname+".gain", 2.0), 0.0, 6.0, "gain", "", gui, 0.75)
dougal2@223
  3871
dougal2@223
  3872
        str += luxFloat("outscale", luxProp(mat, keyname+".outscale", 1.0), 0.0, 10.0, "iscale", "", gui, 1.0)
dougal2@223
  3873
        str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 2.0, "noisesize", "", gui, 1.0)
dougal2@223
  3874
dougal2@223
  3875
        if gui: gui.newline("basis:", -2, level+1, icon_texparam)
dougal2@223
  3876
        noisebasis = luxProp(mat, keyname+".noisebasis", "blender_original")
dougal2@223
  3877
        noisebasises = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
dougal2@223
  3878
        str += luxOption("noisebasis", noisebasis, noisebasises, "noisebasis", "", gui, 2.0)
dougal2@223
  3879
dougal2@223
  3880
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
dougal2@223
  3881
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
dougal2@223
  3882
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
dougal2@223
  3883
dougal2@223
  3884
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  3885
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  3886
        str = s + str + l
dougal2@223
  3887
dougal2@223
  3888
        str += lux3DMapping(keyname, mat, gui, level+1)
dougal2@223
  3889
dougal2@223
  3890
    if texture.get() == "blender_wood":
dougal2@223
  3891
        if gui: gui.newline("noise:", -2, level+1, icon_texparam)
dougal2@223
  3892
dougal2@223
  3893
        mtype = luxProp(mat, keyname+".mtype", "bands")
dougal2@223
  3894
        mtypes = ["bands","rings","bandnoise", "ringnoise"]
dougal2@223
  3895
        str += luxOption("type", mtype, mtypes, "type", "", gui, 0.5)
dougal2@223
  3896
dougal2@223
  3897
        noisetype = luxProp(mat, keyname+".noisetype", "hard_noise")
dougal2@223
  3898
        noisetypes = ["soft_noise","hard_noise"]
dougal2@223
  3899
        str += luxOption("noisetype", noisetype, noisetypes, "noisetypes", "", gui, 0.75)
dougal2@223
  3900
dougal2@223
  3901
        str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 2.0, "noisesize", "", gui, 1.0)
dougal2@223
  3902
        str += luxFloat("turbulance", luxProp(mat, keyname+".turbulance", 5.0), 0.0, 200.0, "turbulance", "", gui, 1.0)
dougal2@223
  3903
dougal2@223
  3904
        if gui: gui.newline("basis:", -2, level+1, icon_texparam)
dougal2@223
  3905
        noisebasis2 = luxProp(mat, keyname+".noisebasis2", "sin")
dougal2@223
  3906
        noisebasises2 = ["sin","saw","tri"]
dougal2@223
  3907
        str += luxOption("noisebasis2", noisebasis2, noisebasises2, "noisebasis2", "", gui, 0.7)
dougal2@223
  3908
dougal2@223
  3909
        noisebasis = luxProp(mat, keyname+".noisebasis", "blender_original")
dougal2@223
  3910
        noisebasises = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
dougal2@223
  3911
        str += luxOption("noisebasis", noisebasis, noisebasises, "noisebasis", "", gui, 1.3)
dougal2@223
  3912
dougal2@223
  3913
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
dougal2@223
  3914
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
dougal2@223
  3915
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
dougal2@223
  3916
dougal2@223
  3917
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  3918
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  3919
        str = s + str + l
dougal2@223
  3920
    
dougal2@223
  3921
        str += lux3DMapping(keyname, mat, gui, level+1)
dougal2@223
  3922
dougal2@223
  3923
    if texture.get() == "blender_clouds":
dougal2@223
  3924
        if gui: gui.newline("noise:", -2, level+1, icon_texparam)
dougal2@223
  3925
dougal2@223
  3926
        mtype = luxProp(mat, keyname+".mtype", "default")
dougal2@223
  3927
        mtypes = ["default","color"]
dougal2@223
  3928
        str += luxOption("type", mtype, mtypes, "type", "", gui, 0.5)
dougal2@223
  3929
dougal2@223
  3930
        noisetype = luxProp(mat, keyname+".noisetype", "hard_noise")
dougal2@223
  3931
        noisetypes = ["soft_noise","hard_noise"]
dougal2@223
  3932
        str += luxOption("noisetype", noisetype, noisetypes, "noisetypes", "", gui, 0.75)
dougal2@223
  3933
dougal2@223
  3934
        str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 2.0, "noisesize", "", gui, 1.0)
dougal2@223
  3935
        str += luxInt("noisedepth", luxProp(mat, keyname+".noisedepth", 2), 0, 6, "noisedepth", "", gui, 1.0)
dougal2@223
  3936
dougal2@223
  3937
        if gui: gui.newline("basis:", -2, level+1, icon_texparam)
dougal2@223
  3938
        noisebasis = luxProp(mat, keyname+".noisebasis", "blender_original")
dougal2@223
  3939
        noisebasises = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
dougal2@223
  3940
        str += luxOption("noisebasis", noisebasis, noisebasises, "noisebasis", "", gui, 1.3)
dougal2@223
  3941
dougal2@223
  3942
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
dougal2@223
  3943
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
dougal2@223
  3944
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
dougal2@223
  3945
dougal2@223
  3946
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  3947
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  3948
        str = s + str + l
dougal2@223
  3949
    
dougal2@223
  3950
        str += lux3DMapping(keyname, mat, gui, level+1)
dougal2@223
  3951
dougal2@223
  3952
    if texture.get() == "blender_blend":
dougal2@223
  3953
        if gui: gui.newline("type:", -2, level+1, icon_texparam)
dougal2@223
  3954
dougal2@223
  3955
        mtype = luxProp(mat, keyname+".mtype", "lin")
dougal2@223
  3956
        mtypes = ["lin","quad","ease","diag","sphere","halo","radial"]
dougal2@223
  3957
        str += luxOption("type", mtype, mtypes, "type", "", gui, 0.5)
dougal2@223
  3958
        
dougal2@223
  3959
        mflag = luxProp(mat, keyname+".flag", "false")
dougal2@223
  3960
        str += luxBool("flipxy", mflag, "flipXY", "", gui, 0.5)
dougal2@223
  3961
dougal2@223
  3962
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
dougal2@223
  3963
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
dougal2@223
  3964
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
dougal2@223
  3965
dougal2@223
  3966
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  3967
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  3968
        str = s + str + l
dougal2@223
  3969
        
dougal2@223
  3970
        str += lux3DMapping(keyname, mat, gui, level+1)
dougal2@223
  3971
dougal2@223
  3972
    if texture.get() == "blender_distortednoise":
dougal2@223
  3973
        if gui: gui.newline("noise:", -2, level+1, icon_texparam)
dougal2@223
  3974
        
dougal2@223
  3975
        str += luxFloat("distamount", luxProp(mat, keyname+".distamount", 1.0), 0.0, 10.0, "distamount", "", gui, 1.0)
dougal2@223
  3976
        str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 2.0, "noisesize", "", gui, 1.0)
dougal2@223
  3977
        str += luxFloat("nabla", luxProp(mat, keyname+".nabla", 0.025), 0.000, 2.0, "nabla", "", gui, 1.0)
dougal2@223
  3978
        
dougal2@223
  3979
        if gui: gui.newline("distortion:", -2, level+1, icon_texparam)
dougal2@223
  3980
        ntype = luxProp(mat, keyname+".type", "blender_original")
dougal2@223
  3981
        ntypes = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
dougal2@223
  3982
        str += luxOption("type", ntype, ntypes, "type", "", gui, 1.3)
dougal2@223
  3983
        
dougal2@223
  3984
        if gui: gui.newline("basis:", -2, level+1, icon_texparam)
dougal2@223
  3985
        noisebasis = luxProp(mat, keyname+".noisebasis", "blender_original")
dougal2@223
  3986
        noisebasises = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
dougal2@223
  3987
        str += luxOption("noisebasis", noisebasis, noisebasises, "noisebasis", "", gui, 1.3)
dougal2@223
  3988
dougal2@223
  3989
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
dougal2@223
  3990
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
dougal2@223
  3991
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
dougal2@223
  3992
dougal2@223
  3993
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  3994
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  3995
        str = s + str + l
dougal2@223
  3996
        
dougal2@223
  3997
        str += lux3DMapping(keyname, mat, gui, level+1)
dougal2@223
  3998
dougal2@223
  3999
    if texture.get() == "blender_noise":        
dougal2@223
  4000
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
dougal2@223
  4001
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
dougal2@223
  4002
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
dougal2@223
  4003
dougal2@223
  4004
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  4005
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  4006
        str = s + str + l
dougal2@223
  4007
        
dougal2@223
  4008
        str += lux3DMapping(keyname, mat, gui, level+1)
dougal2@223
  4009
        
dougal2@223
  4010
    if texture.get() == "blender_magic":
dougal2@223
  4011
        if gui: gui.newline("noise:", -2, level+1, icon_texparam)
dougal2@223
  4012
        
dougal2@223
  4013
        str += luxInt("noisedepth", luxProp(mat, keyname+".noisedepth", 2), 0.0, 10.0, "noisedepth", "", gui, 1.0)
dougal2@223
  4014
        str += luxFloat("turbulance", luxProp(mat, keyname+".turbulance", 5.0), 0.0, 2.0, "turbulance", "", gui, 1.0)
dougal2@223
  4015
dougal2@223
  4016
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
dougal2@223
  4017
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
dougal2@223
  4018
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
dougal2@223
  4019
dougal2@223
  4020
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  4021
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  4022
        str = s + str + l
dougal2@223
  4023
        
dougal2@223
  4024
        str += lux3DMapping(keyname, mat, gui, level+1)
dougal2@223
  4025
        
dougal2@223
  4026
    if texture.get() == "blender_stucci":
dougal2@223
  4027
        if gui: gui.newline("noise:", -2, level+1, icon_texparam)
dougal2@223
  4028
        mtype = luxProp(mat, keyname+".mtype", "Plastic")
dougal2@223
  4029
        mtypes = ["Plastic","Wall In","Wall Out"]
dougal2@223
  4030
        str += luxOption("type", mtype, mtypes, "type", "", gui, 0.5)
dougal2@223
  4031
dougal2@223
  4032
        noisetype = luxProp(mat, keyname+".noisetype", "soft_noise")
dougal2@223
  4033
        noisetypes = ["soft_noise","hard_noise"]
dougal2@223
  4034
        str += luxOption("noisetype", noisetype, noisetypes, "noisetypes", "", gui, 0.75)
dougal2@223
  4035
        
dougal2@223
  4036
        str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 10.0, "noisesize", "", gui, 1.0)
dougal2@223
  4037
        str += luxFloat("turbulance", luxProp(mat, keyname+".turbulance", 5.0), 0.0, 200.0, "turbulance", "", gui, 1.0)
dougal2@223
  4038
dougal2@223
  4039
        noisebasis = luxProp(mat, keyname+".noisebasis", "blender_original")
dougal2@223
  4040
        noisebasises = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
dougal2@223
  4041
        str += luxOption("noisebasis", noisebasis, noisebasises, "noisebasis", "", gui, 1.3)
dougal2@223
  4042
dougal2@223
  4043
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
dougal2@223
  4044
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
dougal2@223
  4045
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
dougal2@223
  4046
dougal2@223
  4047
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  4048
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  4049
        str = s + str + l
dougal2@223
  4050
dougal2@223
  4051
        str += lux3DMapping(keyname, mat, gui, level+1)
dougal2@223
  4052
dougal2@223
  4053
    if texture.get() == "blender_voronoi":
dougal2@223
  4054
        #if gui: gui.newline("distmetric:", -2, level+1, icon_texparam)
dougal2@223
  4055
        mtype = luxProp(mat, keyname+".distmetric", "actual_distance")
dougal2@223
  4056
        mtypes = ["actual_distance","distance_squared","manhattan", "chebychev", "minkovsky_half", "minkovsky_four", "minkovsky"]
dougal2@223
  4057
        str += luxOption("distmetric", mtype, mtypes, "distmetric", "", gui, 1.1)
dougal2@223
  4058
dougal2@223
  4059
        if gui: gui.newline("param:", -2, level+1, icon_texparam)
dougal2@223
  4060
        str += luxFloat("minkovsky_exp", luxProp(mat, keyname+".minkovsky_exp", 2.5), 0.001, 10.0, "minkovsky_exp", "", gui, 1.0)
dougal2@223
  4061
        str += luxFloat("outscale", luxProp(mat, keyname+".outscale", 1.0), 0.01, 10.0, "outscale", "", gui, 1.0)
dougal2@223
  4062
        str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 2.0, "noisesize", "", gui, 1.0)
dougal2@223
  4063
        str += luxFloat("nabla", luxProp(mat, keyname+".nabla", 0.025), 0.001, 0.1, "nabla", "", gui, 1.0)
dougal2@223
  4064
        if gui: gui.newline("wparam:", -2, level+1, icon_texparam)
dougal2@223
  4065
        str += luxFloat("w1", luxProp(mat, keyname+".w1", 1.0), -2.0, 2.0, "w1", "", gui, 1.0)
dougal2@223
  4066
        str += luxFloat("w2", luxProp(mat, keyname+".w2", 0.0), -2.0, 2.0, "w2", "", gui, 1.0)
dougal2@223
  4067
        str += luxFloat("w3", luxProp(mat, keyname+".w3", 0.0), -2.0, 2.0, "w3", "", gui, 1.0)
dougal2@223
  4068
        str += luxFloat("w4", luxProp(mat, keyname+".w4", 0.0), -2.0, 2.0, "w4", "", gui, 1.0)
dougal2@223
  4069
dougal2@223
  4070
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
dougal2@223
  4071
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
dougal2@223
  4072
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
dougal2@223
  4073
dougal2@223
  4074
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  4075
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
dougal2@223
  4076
        str = s + str + l
dougal2@223
  4077
dougal2@223
  4078
        str += lux3DMapping(keyname, mat, gui, level+1)
dougal2@223
  4079
dougal2@223
  4080
dougal2@223
  4081
dougal2@223
  4082
    return (str+"\n", " \"texture %s\" [\"%s\"]"%(name, texname))
zuegs@39
  4083
zuegs@39
  4084
zuegs@47
  4085
def luxSpectrumTexture(name, key, default, max, caption, hint, mat, gui, level=0):
dougal2@223
  4086
    global icon_col
dougal2@223
  4087
    if gui: gui.newline(caption, 4, level, icon_col, scalelist([0.5,0.6,0.5],2.0/(level+2)))
dougal2@223
  4088
    str = ""
dougal2@223
  4089
    keyname = "%s:%s"%(key, name)
dougal2@223
  4090
    texname = "%s:%s"%(mat.getName(), keyname)
dougal2@223
  4091
    value = luxProp(mat, keyname, default)
dougal2@223
  4092
    link = luxRGB(name, value, max, "", hint, gui, 2.0)
dougal2@223
  4093
    tex = luxProp(mat, keyname+".textured", False)
dougal2@223
  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)]))
dougal2@223
  4095
    if tex.get()=="true":
dougal2@223
  4096
        if gui: gui.newline("", -2)
dougal2@223
  4097
        (str, link) = luxTexture(name, key, "color", default, 0, max, caption, hint, mat, gui, level+1)
dougal2@223
  4098
        if value.getRGB() != (1.0, 1.0, 1.0):
dougal2@223
  4099
            if str == "": # handle special case if texture is a just a constant
dougal2@223
  4100
                str += "Texture \"%s\" \"color\" \"scale\" \"color tex1\" [%s] \"color tex2\" [%s]\n"%(texname+".scale", (link.rpartition("[")[2])[0:-1], value.get())
dougal2@223
  4101
            else: str += "Texture \"%s\" \"color\" \"scale\" \"texture tex1\" [\"%s\"] \"color tex2\" [%s]\n"%(texname+".scale", texname, value.get())
dougal2@223
  4102
            link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
dougal2@223
  4103
    return (str, link)
zuegs@21
  4104
radiance29@136
  4105
def luxLightSpectrumTexture(name, key, default, max, caption, hint, mat, gui, level=0):
dougal2@223
  4106
    #if gui: gui.newline(caption, 4, level, icon_emission, scalelist([0.6,0.5,0.5],2.0/(level+2)))
dougal2@223
  4107
    str = ""
dougal2@223
  4108
    keyname = "%s:%s"%(key, name)
dougal2@223
  4109
    texname = "%s:%s"%(mat.getName(), keyname)
dougal2@223
  4110
    (str, link) = luxTexture(name, key, "color", default, 0, max, caption, hint, mat, gui, level+1, 0, 1)
dougal2@223
  4111
    return (str, link)
radiance29@136
  4112
zuegs@47
  4113
def luxFloatTexture(name, key, default, min, max, caption, hint, mat, gui, level=0):
dougal2@223
  4114
    global icon_float
dougal2@223
  4115
    if gui: gui.newline(caption, 4, level, icon_float, scalelist([0.5,0.5,0.6],2.0/(level+2)))
dougal2@223
  4116
    str = ""
dougal2@223
  4117
    keyname = "%s:%s"%(key, name)
dougal2@223
  4118
    texname = "%s:%s"%(mat.getName(), keyname)
dougal2@223
  4119
    value = luxProp(mat, keyname, default)
dougal2@223
  4120
    link = luxFloat(name, value, min, max, "", hint, gui, 2.0)
dougal2@223
  4121
    tex = luxProp(mat, keyname+".textured", False)
dougal2@223
  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)]))
dougal2@223
  4123
    if tex.get()=="true":
dougal2@223
  4124
        if gui: gui.newline("", -2)
dougal2@223
  4125
        (str, link) = luxTexture(name, key, "float", default, min, max, caption, hint, mat, gui, level+1)
dougal2@223
  4126
        if value.get() != 1.0:
dougal2@223
  4127
            if str == "": # handle special case if texture is a just a constant
dougal2@223
  4128
                str += "Texture \"%s\" \"float\" \"scale\" \"float tex1\" [%s] \"float tex2\" [%s]\n"%(texname+".scale", (link.rpartition("[")[2])[0:-1], value.get())
dougal2@223
  4129
            else: str += "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" [\"%s\"] \"float tex2\" [%s]\n"%(texname+".scale", texname, value.get())
dougal2@223
  4130
            link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
dougal2@223
  4131
    return (str, link)
zuegs@21
  4132
radiance29@121
  4133
def luxFloatSliderTexture(name, key, default, min, max, caption, hint, mat, gui, level=0):
dougal2@223
  4134
        global icon_float
dougal2@223
  4135
        if gui: gui.newline(caption, 4, level, icon_float, scalelist([0.5,0.5,0.6],2.0/(level+2)))
dougal2@223
  4136
        str = ""
dougal2@223
  4137
        keyname = "%s:%s"%(key, name)
dougal2@223
  4138
        texname = "%s:%s"%(mat.getName(), keyname)
dougal2@223
  4139
        value = luxProp(mat, keyname, default)
dougal2@223
  4140
        link = luxFloat(name, value, min, max, caption, hint, gui, 2.0, 1)
dougal2@223
  4141
        tex = luxProp(mat, keyname+".textured", False)
dougal2@223
  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)]))
dougal2@223
  4143
        if tex.get()=="true":
dougal2@223
  4144
                if gui: gui.newline("", -2)
dougal2@223
  4145
                (str, link) = luxTexture(name, key, "float", default, min, max, caption, hint, mat, gui, level+1)
dougal2@223
  4146
                if value.get() != 1.0:
dougal2@223
  4147
                        if str == "": # handle special case if texture is a just a constant
dougal2@223
  4148
                                str += "Texture \"%s\" \"float\" \"scale\" \"float tex1\" [%s] \"float tex2\" [%s]\n"%(texname+".scale", (link.rpartition("[")[2])[0:-1], value.get())
dougal2@223
  4149
                        else: str += "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" [\"%s\"] \"float tex2\" [%s]\n"%(texname+".scale", texname, value.get())
dougal2@223
  4150
                        link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
dougal2@223
  4151
        return (str, link)
radiance29@121
  4152
radiance29@121
  4153
zuegs@91
  4154
def luxExponentTexture(name, key, default, min, max, caption, hint, mat, gui, level=0):
dougal2@223
  4155
    global icon_float
dougal2@223
  4156
    if gui: gui.newline(caption, 4, level, icon_float, scalelist([0.5,0.5,0.6],2.0/(level+2)))
dougal2@223
  4157
    str = ""
dougal2@223
  4158
    keyname = "%s:%s"%(key, name)
dougal2@223
  4159
    texname = "%s:%s"%(mat.getName(), keyname)
dougal2@223
  4160
    value = luxProp(mat, keyname, default)
dougal2@223
  4161
dougal2@223
  4162
    if(value.get() == None): value.set(0.002)
dougal2@223
  4163
dougal2@223
  4164
#    link = luxFloat(name, value, min, max, "", hint, gui, 2.0)
dougal2@223
  4165
    if gui:
dougal2@223
  4166
        r = gui.getRect(2.0, 1)
dougal2@223
  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))
dougal2@223
  4168
    link = " \"float %s\" [%f]"%(name, value.getFloat())
dougal2@223
  4169
dougal2@223
  4170
    tex = luxProp(mat, keyname+".textured", False)
dougal2@223
  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)]))
dougal2@223
  4172
    if tex.get()=="true":
dougal2@223
  4173
        if gui: gui.newline("", -2)
dougal2@223
  4174
        (str, link) = luxTexture(name, key, "float", default, min, max, caption, hint, mat, gui, level+1)
dougal2@223
  4175
        if value.get() != 1.0:
dougal2@223
  4176
            if str == "": # handle special case if texture is a just a constant
dougal2@223
  4177
                str += "Texture \"%s\" \"float\" \"scale\" \"float tex1\" [%s] \"float tex2\" [%s]\n"%(texname+".scale", (link.rpartition("[")[2])[0:-1], value.get())
dougal2@223
  4178
            else: str += "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" [\"%s\"] \"float tex2\" [%s]\n"%(texname+".scale", texname, value.get())
dougal2@223
  4179
            link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
dougal2@223
  4180
    return (str, link)
zuegs@91
  4181
zuegs@91
  4182
radiance29@81
  4183
def luxDispFloatTexture(name, key, default, min, max, caption, hint, mat, gui, level=0):
dougal2@223
  4184
    global icon_float
dougal2@223
  4185
    if gui: gui.newline(caption, 4, level, icon_float, scalelist([0.5,0.5,0.6],2.0/(level+2)))
dougal2@223
  4186
    str = ""
dougal2@223
  4187
    keyname = "%s:%s"%(key, name)
dougal2@223
  4188
    texname = "%s:%s"%(mat.getName(), keyname)
dougal2@223
  4189
    value = luxProp(mat, keyname, default)
dougal2@223
  4190
    link = luxFloat(name, value, min, max, "", hint, gui, 2.0)
dougal2@223
  4191
    tex = luxProp(mat, keyname+".textured", False)
dougal2@223
  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)]))
dougal2@223
  4193
    if tex.get()=="true":
dougal2@223
  4194
        if gui: gui.newline("", -2)
dougal2@223
  4195
        (str, link) = luxTexture(name, key, "float", default, min, max, caption, hint, mat, gui, level+1)
dougal2@223
  4196
        str += "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" [\"%s\"] \"float tex2\" [%s]\n"%(texname+".scale", texname, value.get())
dougal2@223
  4197
        link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
dougal2@223
  4198
    return (str, link)
radiance29@81
  4199
radiance29@72
  4200
def luxIORFloatTexture(name, key, default, min, max, caption, hint, mat, gui, level=0):
dougal2@223
  4201
    # IOR preset data
dougal2@223
  4202
    iornames = ["0Z *** Gases @ 0 C ***", "01 - Vacuum", "02 - Air @ STP", "03 - Air", "04 - Helium", "05 - Hydrogen", "06 - Carbon dioxide",
dougal2@223
  4203
    "1Z *** LIQUIDS @ 20 C ***", "11 - Benzene", "12 - Water", "13 - Ethyl alcohol", "14 - Carbon tetrachloride", "15 - Carbon disulfide", 
dougal2@223
  4204
    "2Z *** SOLIDS at room temperature ***", "21 - Diamond", "22 - Strontium titanate", "23 - Amber", "24 - Fused silica glass", "25 - sodium chloride", 
dougal2@223
  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"]
dougal2@223
  4206
    iorvals = [1.0, 1.0, 1.0002926, 1.000293, 1.000036, 1.000132, 1.00045,
dougal2@223
  4207
    1.501, 1.501, 1.333, 1.361, 1.461, 1.628,
dougal2@223
  4208
    2.419, 2.419, 2.41, 1.55, 1.458, 1.50,
dougal2@223
  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]
dougal2@223
  4210
dougal2@223
  4211
    global icon_float
dougal2@223
  4212
    if gui: gui.newline(caption, 4, level, icon_float, scalelist([0.5,0.5,0.6],2.0/(level+2)))
dougal2@223
  4213
    str = ""
dougal2@223
  4214
    keyname = "%s:%s"%(key, name)
dougal2@223
  4215
    texname = "%s:%s"%(mat.getName(), keyname)
dougal2@223
  4216
    value = luxProp(mat, keyname, default)
dougal2@223
  4217
dougal2@223
  4218
    iorusepreset = luxProp(mat, keyname+".iorusepreset", "true")
dougal2@223
  4219
    luxBool("iorusepreset", iorusepreset, "Preset", "Select from a list of predefined presets", gui, 0.4)
dougal2@223
  4220
dougal2@223
  4221
    if(iorusepreset.get() == "true"):
dougal2@223
  4222
        iorpreset = luxProp(mat, keyname+".iorpreset", "24 - Fused silica glass")
dougal2@223
  4223
        if gui:
dougal2@240
  4224
            def setIor(i, value, preset, tree, dict): # callback function to set ior value after selection                
dougal2@223
  4225
                if i >= 0:
dougal2@223
  4226
                    value.set(dict[i])
dougal2@240
  4227
                    preset.set(getTreeNameById(tree, i))
dougal2@223
  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) ] ) ]
dougal2@223
  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}
dougal2@223
  4230
            r = gui.getRect(1.6, 1)
dougal2@223
  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))
dougal2@223
  4232
        link = luxFloat(name, value, min, max, "IOR", hint, None, 1.6)
dougal2@223
  4233
    else:
dougal2@223
  4234
        link = luxFloat(name, value, min, max, "IOR", hint, gui, 1.6, 1)
dougal2@223
  4235
dougal2@223
  4236
    tex = luxProp(mat, keyname+".textured", False)
dougal2@223
  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)]))
dougal2@223
  4238
    if tex.get()=="true":
dougal2@223
  4239
        if gui: gui.newline("", -2)
dougal2@223
  4240
        (str, link) = luxTexture(name, key, "float", default, min, max, caption, hint, mat, gui, level+1)
dougal2@223
  4241
        if value.get() != 1.0:
dougal2@223
  4242
            str += "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" [\"%s\"] \"float tex2\" [%s]\n"%(texname+".scale", texname, value.get())
dougal2@223
  4243
            link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
dougal2@223
  4244
    return (str, link)
radiance29@72
  4245
radiance29@72
  4246
def luxCauchyBFloatTexture(name, key, default, min, max, caption, hint, mat, gui, level=0):
dougal2@223
  4247
    # IOR preset data
dougal2@223
  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" ]
dougal2@223
  4249
    cauchybvals = [ 0.00354, 0.00420, 0.00459, 0.00531, 0.00743, 0.01342 ]
dougal2@223
  4250
dougal2@223
  4251
    global icon_float
dougal2@223
  4252
    if gui: gui.newline(caption, 4, level, icon_float, scalelist([0.5,0.5,0.6],2.0/(level+2)))
dougal2@223
  4253
    str = ""
dougal2@223
  4254
    keyname = "%s:%s"%(key, name)
dougal2@223
  4255
    texname = "%s:%s"%(mat.getName(), keyname)
dougal2@223
  4256
    value = luxProp(mat, keyname, default)
dougal2@223
  4257
dougal2@223
  4258
    cauchybusepreset = luxProp(mat, keyname+".cauchybusepreset", "true")
dougal2@223
  4259
    luxBool("cauchybusepreset", cauchybusepreset, "Preset", "Select from a list of predefined presets", gui, 0.4)
dougal2@223
  4260
dougal2@223
  4261
    if(cauchybusepreset.get() == "true"):
dougal2@223
  4262
        cauchybpreset = luxProp(mat, keyname+".cauchybpreset", "01 - Fused silica glass")
dougal2@223
  4263
        luxOption("cauchybpreset", cauchybpreset, cauchybnames, "  PRESET", "select CauchyB preset", gui, 1.6)
dougal2@223
  4264
        idx = cauchybnames.index(cauchybpreset.get())
dougal2@223
  4265
        value.set(cauchybvals[idx])
dougal2@223
  4266
        link = luxFloat(name, value, min, max, "cauchyb", hint, None, 1.6)
dougal2@223
  4267
    else:
dougal2@223
  4268
        link = luxFloat(name, value, min, max, "cauchyb", hint, gui, 1.6, 1)
dougal2@223
  4269
dougal2@223
  4270
    tex = luxProp(mat, keyname+".textured", False)
dougal2@223
  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)]))
dougal2@223
  4272
    if tex.get()=="true":
dougal2@223
  4273
        if gui: gui.newline("", -2)
dougal2@223
  4274
        (str, link) = luxTexture(name, key, "float", default, min, max, caption, hint, mat, gui, level+1)
dougal2@223
  4275
        if value.get() != 1.0:
dougal2@223
  4276
            str += "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" [\"%s\"] \"float tex2\" [%s]\n"%(texname+".scale", texname, value.get())
dougal2@223
  4277
            link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
dougal2@223
  4278
    return (str, link)
radiance29@72
  4279
zuegs@143
  4280
def luxLight(name, kn, mat, gui, level):
dougal2@223
  4281
    if gui:
dougal2@223
  4282
        if name != "": gui.newline(name+":", 10, level)
dougal2@223
  4283
        else: gui.newline("color:", 0, level+1)
dougal2@223
  4284
    (str,link) = luxLightSpectrumTexture("L", kn+"light", "1.0 1.0 1.0", 1.0, "Spectrum", "", mat, gui, level+1)
dougal2@223
  4285
    if gui: gui.newline("")
dougal2@223
  4286
    link += luxFloat("power", luxProp(mat, kn+"light.power", 100.0), 0.0, 10000.0, "Power(W)", "AreaLight Power in Watts", gui)
dougal2@223
  4287
    link += luxFloat("efficacy", luxProp(mat, kn+"light.efficacy", 17.0), 0.0, 100.0, "Efficacy(lm/W)", "Efficacy Luminous flux/watt", gui)
dougal2@223
  4288
    if gui: gui.newline("")
dougal2@223
  4289
    link += luxFloat("gain", luxProp(mat, kn+"light.gain", 1.0), 0.0, 100.0, "gain", "Gain/scale multiplier", gui)
dougal2@223
  4290
    lightgroup = luxProp(mat, kn+"light.lightgroup", "default")
dougal2@223
  4291
    luxString("lightgroup", lightgroup, "group", "assign light to a named light-group", gui, 1.0)
dougal2@223
  4292
dougal2@223
  4293
    if gui: gui.newline("Photometric")
dougal2@223
  4294
    pm = luxProp(mat, kn+"light.usepm", "false")
radiance29@245
  4295
    luxCollapse("photometric", pm, "Photometric Diagram", "Enable Photometric Diagram options", gui, 2.0)
dougal2@223
  4296
dougal2@223
  4297
    if(pm.get()=="true"):
dougal2@223
  4298
        pmtype = luxProp(mat, kn+"light.pmtype", "IESna")
dougal2@223
  4299
        pmtypes = ["IESna", "imagemap"]
dougal2@223
  4300
        luxOption("type", pmtype, pmtypes, "type", "Choose Photometric data type to use", gui, 0.6)
dougal2@223
  4301
        if(pmtype.get() == "imagemap"):
dougal2@223
  4302
            map = luxProp(mat, kn+"light.pmmapname", "")
zuegs@255
  4303
            link += luxFile("mapname", map, "map-file", "filename of the photometric map", gui, 1.4)
dougal2@223
  4304
        if(pmtype.get() == "IESna"):
dougal2@223
  4305
            map = luxProp(mat, kn+"light.pmiesname", "")
zuegs@255
  4306
            link += luxFile("iesname", map, "ies-file", "filename of the IES photometric data file", gui, 1.4)
dougal2@223
  4307
dougal2@223
  4308
    has_bump_options = 0
dougal2@223
  4309
    has_object_options = 1
dougal2@223
  4310
    return (str, link)
zuegs@143
  4311
radiance29@154
  4312
def luxLamp(name, kn, mat, gui, level):
dougal2@223
  4313
    if gui:
dougal2@223
  4314
        if name != "": gui.newline(name+":", 10, level)
dougal2@223
  4315
        else: gui.newline("color:", 0, level+1)
dougal2@223
  4316
#    if gui: gui.newline("", 10, level)
dougal2@223
  4317
    (str,link) = luxLightSpectrumTexture("L", kn+"light", "1.0 1.0 1.0", 1.0, "Spectrum", "", mat, gui, level+1)
dougal2@223
  4318
    if gui: gui.newline("")
dougal2@223
  4319
    link += luxFloat("gain", luxProp(mat, kn+"light.gain", 1.0), 0.0, 100.0, "gain", "Gain/scale multiplier", gui)
dougal2@223
  4320
    lightgroup = luxProp(mat, kn+"light.lightgroup", "default")
dougal2@223
  4321
    luxString("lightgroup", lightgroup, "group", "assign light to a named light-group", gui, 1.0)
dougal2@223
  4322
dougal2@223
  4323
    if gui: gui.newline("Photometric")
dougal2@223
  4324
    pm = luxProp(mat, kn+"light.usepm", "false")
dougal2@223
  4325
    luxBool("photometric", pm, "Photometric Diagram", "Enable Photometric Diagram options", gui, 2.0)
dougal2@223
  4326
dougal2@223
  4327
    if(pm.get()=="true"):
dougal2@223
  4328
        pmtype = luxProp(mat, kn+"light.pmtype", "IESna")
dougal2@223
  4329
        pmtypes = ["IESna", "imagemap"]
dougal2@223
  4330
        luxOption("type", pmtype, pmtypes, "type", "Choose Photometric data type to use", gui, 0.6)
dougal2@223
  4331
        if(pmtype.get() == "imagemap"):
dougal2@223
  4332
            map = luxProp(mat, kn+"light.pmmapname", "")
zuegs@255
  4333
            link += luxFile("mapname", map, "map-file", "filename of the photometric map", gui, 1.4)
dougal2@223
  4334
        if(pmtype.get() == "IESna"):
dougal2@223
  4335
            map = luxProp(mat, kn+"light.pmiesname", "")
zuegs@255
  4336
            link += luxFile("iesname", map, "ies-file", "filename of the IES photometric data file", gui, 1.4)
dougal2@223
  4337
dougal2@223
  4338
        link += luxBool("flipz", luxProp(mat, kn+"light.flipZ", "true"), "Flip Z", "Flip Z direction in mapping", gui, 2.0)
dougal2@223
  4339
dougal2@223
  4340
    return (str, link)
radiance29@154
  4341
radiance29@154
  4342
def luxSpot(name, kn, mat, gui, level):
dougal2@223
  4343
    if gui:
dougal2@223
  4344
        if name != "": gui.newline(name+":", 10, level)
dougal2@223
  4345
        else: gui.newline("color:", 0, level+1)
dougal2@223
  4346
#    if gui: gui.newline("", 10, level)
dougal2@223
  4347
    (str,link) = luxLightSpectrumTexture("L", kn+"light", "1.0 1.0 1.0", 1.0, "Spectrum", "", mat, gui, level+1)
dougal2@223
  4348
    if gui: gui.newline("")
dougal2@223
  4349
    link += luxFloat("gain", luxProp(mat, kn+"light.gain", 1.0), 0.0, 100.0, "gain", "Gain/scale multiplier", gui)
dougal2@223
  4350
    lightgroup = luxProp(mat, kn+"light.lightgroup", "default")
dougal2@223
  4351
    luxString("lightgroup", lightgroup, "group", "assign light to a named light-group", gui, 1.0)
dougal2@223
  4352
dougal2@223
  4353
    if gui: gui.newline("Projection")
dougal2@223
  4354
    proj = luxProp(mat, kn+"light.usetexproj", "false")
dougal2@223
  4355
    luxBool("projection", proj, "Texture Projection", "Enable imagemap texture projection", gui, 2.0)
dougal2@223
  4356
dougal2@223
  4357
    if(proj.get() == "true"):
dougal2@223
  4358
        map = luxProp(mat, kn+"light.pmmapname", "")
zuegs@255
  4359
        link += luxFile("mapname", map, "map-file", "filename of the photometric map", gui, 2.0)
dougal2@223
  4360
dougal2@223
  4361
    return (str, link)
radiance29@154
  4362
dougal2@196
  4363
dougal2@199
  4364
def Preview_Sphereset(mat, kn, state):
dougal2@223
  4365
    if state=="true":
dougal2@223
  4366
        luxProp(mat, kn+"prev_sphere", "true").set("true")
dougal2@223
  4367
        luxProp(mat, kn+"prev_plane", "false").set("false")
dougal2@223
  4368
        luxProp(mat, kn+"prev_torus", "false").set("false")
dougal2@199
  4369
def Preview_Planeset(mat, kn, state):
dougal2@223
  4370
    if state=="true":
dougal2@223
  4371
        luxProp(mat, kn+"prev_sphere", "true").set("false")
dougal2@223
  4372
        luxProp(mat, kn+"prev_plane", "false").set("true")
dougal2@223
  4373
        luxProp(mat, kn+"prev_torus", "false").set("false")
dougal2@199
  4374
def Preview_Torusset(mat, kn, state):
dougal2@223
  4375
    if state=="true":
dougal2@223
  4376
        luxProp(mat, kn+"prev_sphere", "true").set("false")
dougal2@223
  4377
        luxProp(mat, kn+"prev_plane", "false").set("false")
dougal2@223
  4378
        luxProp(mat, kn+"prev_torus", "false").set("true")
dougal2@199
  4379
dougal2@196
  4380
def Preview_Update(mat, kn, defLarge, defType, texName, name, level):
dougal2@223
  4381
    #print "%s %s %s %s %s %s %s" % (mat, kn, defLarge, defType, texName, name, level)
zuegs@255
  4382
zuegs@255
  4383
    global previewing
zuegs@255
  4384
    previewing = True
dougal2@223
  4385
    
dougal2@223
  4386
    Blender.Window.WaitCursor(True)
dougal2@223
  4387
    scn = Scene.GetCurrent()
dougal2@223
  4388
dougal2@223
  4389
    # Size of preview thumbnail
dougal2@223
  4390
    thumbres = 110 # default 110x110
dougal2@223
  4391
    if(defLarge):
dougal2@223
  4392
        large = luxProp(mat, kn+"prev_large", "true")
dougal2@223
  4393
    else:
dougal2@223
  4394
        large = luxProp(mat, kn+"prev_large", "false")
dougal2@223
  4395
    if(large.get() == "true"):
dougal2@223
  4396
        thumbres = 140 # small 140x140
dougal2@223
  4397
dougal2@223
  4398
    thumbbuf = thumbres*thumbres*3
dougal2@223
  4399
dougal2@223
  4400
#        consolebin = luxProp(scn, "luxconsole", "").get()
dougal2@223
  4401
    consolebin = Blender.sys.dirname(luxProp(scn, "lux", "").get()) + os.sep + "luxconsole"
dougal2@223
  4402
    if osys.platform == "win32": consolebin = consolebin + ".exe"
dougal2@223
  4403
dougal2@223
  4404
    PIPE = subprocess.PIPE
dougal2@223
  4405
    p = subprocess.Popen((consolebin, '-b', '-'), bufsize=thumbbuf, stdin=PIPE, stdout=PIPE, stderr=PIPE)
dougal2@223
  4406
dougal2@223
  4407
    # Unremark to write debugging output to file
dougal2@223
  4408
    # p.stdin = open('c:\preview.lxs', 'w')
dougal2@223
  4409
dougal2@223
  4410
    if defType == 0:    
dougal2@223
  4411
        prev_sphere = luxProp(mat, kn+"prev_sphere", "true")
dougal2@223
  4412
        prev_plane = luxProp(mat, kn+"prev_plane", "false")
dougal2@223
  4413
        prev_torus = luxProp(mat, kn+"prev_torus", "false")
dougal2@223
  4414
    elif defType == 1:
dougal2@223
  4415
        prev_sphere = luxProp(mat, kn+"prev_sphere", "false")
dougal2@223
  4416
        prev_plane = luxProp(mat, kn+"prev_plane", "true")
dougal2@223
  4417
        prev_torus = luxProp(mat, kn+"prev_torus", "false")
dougal2@223
  4418
    else:
dougal2@223
  4419
        prev_sphere = luxProp(mat, kn+"prev_sphere", "false")
dougal2@223
  4420
        prev_plane = luxProp(mat, kn+"prev_plane", "false")
dougal2@223
  4421
        prev_torus = luxProp(mat, kn+"prev_torus", "true")
dougal2@223
  4422
dougal2@223
  4423
    # Zoom
dougal2@223
  4424
    if luxProp(mat, kn+"prev_zoom", "false").get() == "true":
dougal2@223
  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')
dougal2@223
  4426
    else:
dougal2@223
  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')
dougal2@223
  4428
    # Fleximage
doug@336
  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))
dougal2@223
  4430
    p.stdin.write('PixelFilter "sinc"\n')
dougal2@223
  4431
    # Quality
dougal2@223
  4432
    scn = Scene.GetCurrent()
dougal2@223
  4433
    defprevmat = luxProp(scn, "defprevmat", "high")
dougal2@223
  4434
    quality = luxProp(mat, kn+"prev_quality", defprevmat.get())
dougal2@223
  4435
    if quality.get()=="low":
dougal2@223
  4436
        p.stdin.write('Sampler "lowdiscrepancy" "string pixelsampler" ["hilbert"] "integer pixelsamples" [2]\n')
dougal2@223
  4437
    elif quality.get()=="medium":
dougal2@223
  4438
        p.stdin.write('Sampler "lowdiscrepancy" "string pixelsampler" ["hilbert"] "integer pixelsamples" [4]\n')
dougal2@223
  4439
    elif quality.get()=="high":
dougal2@223
  4440
        p.stdin.write('Sampler "lowdiscrepancy" "string pixelsampler" ["hilbert"] "integer pixelsamples" [8]\n')
dougal2@223
  4441
    else: 
dougal2@223
  4442
        p.stdin.write('Sampler "lowdiscrepancy" "string pixelsampler" ["hilbert"] "integer pixelsamples" [32]\n')
dougal2@223
  4443
    # SurfaceIntegrator
dougal2@223
  4444
    if(prev_plane.get()=="false"):
dougal2@223
  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')
dougal2@223
  4446
    else:
dougal2@223
  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')
dougal2@223
  4448
    # World
dougal2@223
  4449
    p.stdin.write('WorldBegin\n')
dougal2@223
  4450
    if(prev_sphere.get()=="true"):
dougal2@223
  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')
dougal2@223
  4452
    elif (prev_plane.get()=="true"):
dougal2@223
  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')
dougal2@223
  4454
    else:
dougal2@223
  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')
dougal2@223
  4456
    obwidth = luxProp(mat, kn+"prev_obwidth", 1.0)
dougal2@223
  4457
    obw = obwidth.get()
dougal2@223
  4458
    p.stdin.write('TransformBegin\n')
dougal2@223
  4459
    p.stdin.write('Scale %f %f %f\n'%(obw,obw,obw))
dougal2@223
  4460
    if texName:
dougal2@223
  4461
        print "texture "+texName+"  "+name
dougal2@223
  4462
        (str, link) = luxTexture(texName, name, "color", "1.0 1.0 1.0", None, None, "", "", mat, None, 0, level)
dougal2@223
  4463
        link = link.replace(" "+texName+"\"", " Kd\"") # swap texture name to "Kd"
dougal2@223
  4464
        p.stdin.write(str+"\n")
dougal2@223
  4465
        p.stdin.write("Material \"matte\" "+link+"\n") 
dougal2@223
  4466
    else:
dougal2@223
  4467
        # Material
dougal2@223
  4468
        p.stdin.write(luxMaterial(mat))
dougal2@223
  4469
        link = luxProp(mat,"link","").get()
dougal2@223
  4470
        if kn!="": link = link.rstrip("\"")+":"+kn.strip(".:")+"\""
dougal2@223
  4471
        p.stdin.write(link+'\n')
dougal2@223
  4472
    p.stdin.write('TransformEnd\n')
dougal2@223
  4473
    # Shape
dougal2@223
  4474
    if(prev_sphere.get()=="true"):
dougal2@223
  4475
        p.stdin.write('Shape "sphere" "float radius" [1.0]\n')
dougal2@223
  4476
    elif (prev_plane.get()=="true"):
jensverwiebe@327
  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')
dougal2@223
  4478
    elif (prev_torus.get()=="true"):
dougal2@223
  4479
        p.stdin.write('Shape "torus" "float radius" [1.0]\n')
dougal2@223
  4480
    p.stdin.write('AttributeEnd\n')
dougal2@223
  4481
    # Checkerboard floor
dougal2@223
  4482
    if(prev_plane.get()=="false"):
dougal2@223
  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')
dougal2@223
  4484
        p.stdin.write('Texture "checks" "color" "checkerboard"')
dougal2@223
  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]')
dougal2@223
  4486
        p.stdin.write('"string mapping" ["uv"] "float uscale" [36.8] "float vscale" [36.0]\n')
dougal2@223
  4487
        p.stdin.write('Material "matte" "texture Kd" ["checks"]\n')
radiance29@229
  4488
        p.stdin.write('Shape "loopsubdiv" "integer nlevels" [3] "bool dmnormalsmooth" ["true"] "bool dmsharpboundary" ["false"] ')
dougal2@223
  4489
        p.stdin.write('"integer indices" [ 0 1 2 0 2 3 1 0 4 1 4 5 5 4 6 5 6 7 ]')
dougal2@223
  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')
dougal2@223
  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')
dougal2@223
  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')
dougal2@223
  4493
        p.stdin.write('AttributeEnd\n')
dougal2@223
  4494
    # Lightsource
dougal2@223
  4495
    if(prev_plane.get()=="false"):
dougal2@223
  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')
dougal2@223
  4497
    else:
dougal2@223
  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')
dougal2@223
  4499
    area = luxProp(mat, kn+"prev_arealight", "false")
dougal2@223
  4500
    if(area.get() == "false"):
dougal2@223
  4501
        p.stdin.write('Texture "pL" "color" "blackbody" "float temperature" [6500.0]\n')
dougal2@223
  4502
        p.stdin.write('LightSource "point" "texture L" ["pL"]')
dougal2@223
  4503
    else:
dougal2@223
  4504
        p.stdin.write('ReverseOrientation\n')
dougal2@223
  4505
        p.stdin.write('AreaLightSource "area" "color L" [1.0 1.0 1.0]\n')
dougal2@223
  4506
        p.stdin.write('Shape "disk" "float radius" [1.0]\nAttributeEnd\n')
dougal2@223
  4507
    p.stdin.write('WorldEnd\n')
zuegs@255
  4508
    previewing = False
dougal2@223
  4509
dougal2@223
  4510
    data = p.communicate()[0]
dougal2@223
  4511
    p.stdin.close()
dougal2@223
  4512
    if(len(data) < thumbbuf): 
dougal2@223
  4513
        print "error on preview"
dougal2@223
  4514
        return
dougal2@223
  4515
    global previewCache
dougal2@223
  4516
    image = luxImage()
dougal2@223
  4517
    image.decodeLuxConsole(thumbres, thumbres, data)
dougal2@223
  4518
    previewCache[(mat.name+":"+kn).__hash__()] = image
dougal2@223
  4519
    Draw.Redraw()
dougal2@223
  4520
    Blender.Window.WaitCursor(False)
dougal2@196
  4521
dougal2@196
  4522
def luxPreview(mat, name, defType=0, defEnabled=False, defLarge=False, texName=None, gui=None, level=0, color=None):
dougal2@223
  4523
    
dougal2@223
  4524
dougal2@223
  4525
    if gui:
dougal2@223
  4526
        kn = name
dougal2@223
  4527
        if texName: kn += ":"+texName
dougal2@223
  4528
        if kn != "": kn += "."
dougal2@223
  4529
        if(defEnabled == True):
dougal2@223
  4530
            showpreview = luxProp(mat, kn+"prev_show", "true")
dougal2@223
  4531
        else:
dougal2@223
  4532
            showpreview = luxProp(mat, kn+"prev_show", "false")
dougal2@223
  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)]))
dougal2@223
  4534
        if showpreview.get()=="true": 
dougal2@223
  4535
            if(defLarge):
dougal2@223
  4536
                large = luxProp(mat, kn+"prev_large", "true")
dougal2@223
  4537
            else:
dougal2@223
  4538
                large = luxProp(mat, kn+"prev_large", "false")
dougal2@223
  4539
            voffset = -8
dougal2@223
  4540
            rr = 5.65 
dougal2@223
  4541
            if(large.get() == "true"):
dougal2@223
  4542
                rr = 7
dougal2@223
  4543
                voffset = 22
dougal2@223
  4544
            gui.newline()
dougal2@223
  4545
            r = gui.getRect(1.1, rr)
dougal2@223
  4546
            if(color != None):
dougal2@223
  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)
dougal2@223
  4548
            try: previewCache[(mat.name+":"+kn).__hash__()].draw(r[0]-82, r[1]+4)
dougal2@223
  4549
            except: pass
dougal2@223
  4550
dougal2@223
  4551
            prev_sphere = luxProp(mat, kn+"prev_sphere", "true")
dougal2@223
  4552
            prev_plane = luxProp(mat, kn+"prev_plane", "false")
dougal2@223
  4553
            prev_torus = luxProp(mat, kn+"prev_torus", "false")
dougal2@223
  4554
            if defType == 1:
dougal2@223
  4555
                prev_sphere = luxProp(mat, kn+"prev_sphere", "false")
dougal2@223
  4556
                prev_plane = luxProp(mat, kn+"prev_plane", "true")
dougal2@223
  4557
                prev_torus = luxProp(mat, kn+"prev_torus", "false")
dougal2@223
  4558
            elif defType == 2:
dougal2@223
  4559
                prev_sphere = luxProp(mat, kn+"prev_sphere", "false")
dougal2@223
  4560
                prev_plane = luxProp(mat, kn+"prev_plane", "false")
dougal2@223
  4561
                prev_torus = luxProp(mat, kn+"prev_torus", "true")
dougal2@223
  4562
dougal2@223
  4563
            # preview mode toggle buttons
dougal2@223
  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)]))
dougal2@223
  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)]))
dougal2@223
  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)]))
dougal2@223
  4567
dougal2@223
  4568
            # Zoom toggle
dougal2@223
  4569
            zoom = luxProp(mat, kn+"prev_zoom", "false")
dougal2@223
  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)]))
dougal2@223
  4571
dougal2@223
  4572
            area = luxProp(mat, kn+"prev_arealight", "false")
dougal2@223
  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)]))
dougal2@223
  4574
dougal2@223
  4575
            # Object width
dougal2@223
  4576
            obwidth = luxProp(mat, kn+"prev_obwidth", 1.0)
dougal2@223
  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))
dougal2@223
  4578
dougal2@223
  4579
            # large/small size
dougal2@223
  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)]))
dougal2@223
  4581
dougal2@223
  4582
            # Preview Quality
dougal2@223
  4583
            qs = ["low","medium","high","very high"]
dougal2@223
  4584
            scn = Scene.GetCurrent()
dougal2@223
  4585
            defprevmat = luxProp(scn, "defprevmat", "high")
dougal2@223
  4586
            quality = luxProp(mat, kn+"prev_quality", defprevmat.get())
dougal2@223
  4587
            luxOptionRect("quality", quality, qs, "  Quality", "select preview quality", gui, r[0]+200, r[1]+100+voffset, 88, 18)
dougal2@223
  4588
dougal2@223
  4589
            # Update preview
dougal2@223
  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))
dougal2@223
  4591
dougal2@223
  4592
            # Reset depths after getRect()
dougal2@223
  4593
            gui.y -= 92+voffset
dougal2@223
  4594
            gui.y -= gui.h
dougal2@223
  4595
            gui.hmax = 18 + 4
radiance29@115
  4596
radiance29@72
  4597
def luxMaterialBlock(name, luxname, key, mat, gui=None, level=0, str_opt=""):
dougal2@223
  4598
    global icon_mat, icon_matmix, icon_map3dparam
dougal2@223
  4599
    def c(t1, t2):
dougal2@223
  4600
        return (t1[0]+t2[0], t1[1]+t2[1])
dougal2@223
  4601
    str = ""
dougal2@223
  4602
    if key == "": keyname = kn = name
dougal2@223
  4603
    else: keyname = kn = "%s:%s"%(key, name)
dougal2@223
  4604
    if kn != "": kn += "."
dougal2@223
  4605
    if keyname == "": matname = mat.getName()
dougal2@223
  4606
    else: matname = "%s:%s"%(mat.getName(), keyname)
dougal2@223
  4607
dougal2@223
  4608
    if mat:
dougal2@223
  4609
        mattype = luxProp(mat, kn+"type", "matte")
dougal2@223
  4610
        # Set backwards compatibility of glossy material from plastic and substrate
dougal2@223
  4611
        if(mattype.get() == "substrate" or mattype.get() == "plastic"):
dougal2@223
  4612
            mattype.set("glossy")
dougal2@223
  4613
doug@331
  4614
        # this is reverse order than in shown in the dropdown list
doug@331
  4615
        materials = ["null","mix","mirror","shinymetal","metal","mattetranslucent","matte","glossy","roughglass","glass","carpaint"]
doug@331
  4616
        
doug@331
  4617
        if level == 0: materials = ["portal","light","boundvolume"]+materials
dougal2@223
  4618
        if gui:
dougal2@223
  4619
            icon = icon_mat
dougal2@223
  4620
            if mattype.get() == "mix": icon = icon_matmix
dougal2@223
  4621
            if level == 0: gui.newline("Material type:", 12, level, icon, [0.75,0.5,0.25])
dougal2@223
  4622
            else: gui.newline(name+":", 12, level, icon, scalelist([0.75,0.6,0.25],2.0/(level+2)))
dougal2@223
  4623
dougal2@223
  4624
dougal2@223
  4625
        link = luxOption("type", mattype, materials, "  TYPE", "select material type", gui)
dougal2@223
  4626
        showadvanced = luxProp(mat, kn+"showadvanced", "false")
dougal2@223
  4627
        luxBool("advanced", showadvanced, "Advanced", "Show advanced options", gui, 0.6)
dougal2@223
  4628
        showhelp = luxProp(mat, kn+"showhelp", "false")
dougal2@223
  4629
        luxHelp("help", showhelp, "Help", "Show Help Information", gui, 0.4)
dougal2@223
  4630
dougal2@223
  4631
        # show copy/paste menu button
dougal2@223
  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))
dougal2@223
  4633
dougal2@223
  4634
        # Draw Material preview option
dougal2@223
  4635
        showmatprev = False
dougal2@223
  4636
        if level == 0:
dougal2@223
  4637
            showmatprev = True
dougal2@223
  4638
        if gui: luxPreview(mat, keyname, 0, showmatprev, True, None, gui, level, [0.746, 0.625, 0.5])
dougal2@223
  4639
dougal2@223
  4640
dougal2@223
  4641
        if gui: gui.newline()
dougal2@223
  4642
        has_object_options   = 0 # disable object options by default
dougal2@223
  4643
        has_bump_options     = 0 # disable bump mapping options by default
dougal2@223
  4644
        has_emission_options = 0 # disable emission options by default
dougal2@258
  4645
        has_compositing_options = 0 # disable compositing options by default
radiance29@245
  4646
dougal2@223
  4647
        if mattype.get() == "mix":
dougal2@223
  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))
dougal2@223
  4649
            (str,link) = c((str,link), luxMaterialBlock("mat1", "namedmaterial1", keyname, mat, gui, level+1))
dougal2@223
  4650
            (str,link) = c((str,link), luxMaterialBlock("mat2", "namedmaterial2", keyname, mat, gui, level+1))
dougal2@223
  4651
            has_bump_options = 0
dougal2@223
  4652
            has_object_options = 1
dougal2@223
  4653
            has_emission_options = 1
dougal2@258
  4654
            has_compositing_options = 0
dougal2@223
  4655
dougal2@223
  4656
        if mattype.get() == "light":
dougal2@223
  4657
            lightgroup = luxProp(mat, kn+"light.lightgroup", "default")
doughammond@325
  4658
            if luxProp(Scene.GetCurrent(), "nolg", "false").get()!="true":
doughammond@325
  4659
                link = "LightGroup \"%s\"\n"%lightgroup.get()
dougal2@223
  4660
            link += "AreaLightSource \"area\""
dougal2@223
  4661
            (str,link) = c((str,link), luxLight("", kn, mat, gui, level))
dougal2@223
  4662
            has_bump_options = 0
dougal2@223
  4663
            has_object_options = 1
dougal2@223
  4664
            has_emission_options = 0
dougal2@258
  4665
            has_compositing_options = 1
dougal2@223
  4666
dougal2@223
  4667
        if mattype.get() == "boundvolume":
dougal2@223
  4668
            link = ""
dougal2@223
  4669
            voltype = luxProp(mat, kn+"vol.type", "homogeneous")
radiance29@252
  4670
            vols = ["homogeneous", "exponential", "cloud"]
dougal2@223
  4671
            vollink = luxOption("type", voltype, vols, "type", "", gui)
dougal2@223
  4672
            if voltype.get() == "homogeneous":
dougal2@223
  4673
                link = "Volume \"homogeneous\""
dougal2@223
  4674
            if voltype.get() == "exponential":
dougal2@223
  4675
                link = "Volume \"exponential\""
radiance29@252
  4676
            if voltype.get() == "cloud":
radiance29@252
  4677
                link = "Volume \"cloud\""
dougal2@223
  4678
dougal2@223
  4679
            if gui: gui.newline("absorption:", 0, level+1)
dougal2@223
  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)
dougal2@223
  4681
            if gui: gui.newline("scattering:", 0, level+1)
dougal2@223
  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)
dougal2@223
  4683
            if gui: gui.newline("emission:", 0, level+1)
dougal2@223
  4684
            link += luxRGB("Le", luxProp(mat, kn+"vol.le", "0.0 0.0 0.0"), 1.0, "Le", "The volume's emission spectrum", gui)
dougal2@223
  4685
            if gui: gui.newline("assymetry:", 0, level+1)
dougal2@223
  4686
            link += luxFloat("g", luxProp(mat, kn+"vol.g", 0.0), 0.0, 100.0, "g", "The phase function asymmetry parameter", gui)
dougal2@223
  4687
dougal2@223
  4688
            if voltype.get() == "exponential":
dougal2@223
  4689
                if gui: gui.newline("form:", 0, level+1)
dougal2@223
  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)
dougal2@223
  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)
dougal2@223
  4692
                if gui: gui.newline("updir:", 0, level+1)
dougal2@223
  4693
                link += luxVector("updir", luxProp(mat, kn+"vol.updir", "0 0 1"), -1.0, 1.0, "updir", "Up direction vector", gui, 2.0)
dougal2@223
  4694
radiance29@252
  4695
            if voltype.get() == "cloud":
radiance29@252
  4696
                if gui: gui.newline("cloud:", 0, level+1)
radiance29@252
  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)
radiance29@252
  4698
                link += luxFloat("noisescale", luxProp(mat, kn+"vol.noisescale", 0.3), 0.1, 2.0, "noisesize", "Size of cloud noise", gui)
radiance29@252
  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)
radiance29@252
  4700
                link += luxFloat("noiseoffset", luxProp(mat, kn+"vol.noiseoffset", 0.0), 0.0, 1000.0, "noiseoffset", "Useful for creating unique clouds", gui )
radiance29@252
  4701
                link += luxInt("octaves", luxProp(mat, kn+"vol.octaves", 3), 1, 8, "octaves", "Sets the amount of detail for the noise", gui )
radiance29@252
  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 )
radiance29@252
  4703
                link += luxFloat("sharpness", luxProp(mat, kn+"vol.sharpness", 6.0), 0.2, 10.0, "sharpness", "Sets the sharpness of the noise", gui)
radiance29@252
  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)
radiance29@252
  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)
radiance29@252
  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 )
radiance29@252
  4707
                link += luxFloat("spheresize", luxProp(mat, kn+"vol.spheresize", 0.15), 0.05, 0.55, "spheresize", "Size of cumulus spheres", gui)
radiance29@252
  4708
 
dougal2@223
  4709
            link += str_opt
dougal2@223
  4710
dougal2@223
  4711
            has_bump_options = 0
dougal2@223
  4712
            has_object_options = 0
dougal2@223
  4713
            has_emission_options = 0
dougal2@223
  4714
dougal2@223
  4715
            return (str, link)
dougal2@223
  4716
dougal2@223
  4717
        if mattype.get() == "carpaint":
doug@333
  4718
            if gui: gui.newline("Preset:", 0, level+1)
doug@333
  4719
            carname = luxProp(mat, kn+"carpaint.name", "Custom")
doug@333
  4720
            cars = ["Custom","ford f8","polaris silber","opel titan","bmw339","2k acrylack","white","blue","blue matte"]
dougal2@223
  4721
            carlink = luxOption("name", carname, cars, "name", "", gui)
doug@333
  4722
            if carname.get() == "Custom":
dougal2@223
  4723
                (str,link) = c((str,link), luxSpectrumTexture("Kd", keyname, "1.0 1.0 1.0", 1.0, "diffuse", "", mat, gui, level+1))
dougal2@223
  4724
                (str,link) = c((str,link), luxSpectrumTexture("Ks1", keyname, "1.0 1.0 1.0", 1.0, "specular1", "", mat, gui, level+1))
dougal2@223
  4725
                (str,link) = c((str,link), luxSpectrumTexture("Ks2", keyname, "1.0 1.0 1.0", 1.0, "specular2", "", mat, gui, level+1))
dougal2@223
  4726
                (str,link) = c((str,link), luxSpectrumTexture("Ks3", keyname, "1.0 1.0 1.0", 1.0, "specular3", "", mat, gui, level+1))
dougal2@223
  4727
                (str,link) = c((str,link), luxFloatTexture("R1", keyname, 1.0, 0.0, 1.0, "R1", "", mat, gui, level+1))
dougal2@223
  4728
                (str,link) = c((str,link), luxFloatTexture("R2", keyname, 1.0, 0.0, 1.0, "R2", "", mat, gui, level+1))
dougal2@223
  4729
                (str,link) = c((str,link), luxFloatTexture("R3", keyname, 1.0, 0.0, 1.0, "R3", "", mat, gui, level+1))
dougal2@223
  4730
                (str,link) = c((str,link), luxFloatTexture("M1", keyname, 1.0, 0.0, 1.0, "M1", "", mat, gui, level+1))
dougal2@223
  4731
                (str,link) = c((str,link), luxFloatTexture("M2", keyname, 1.0, 0.0, 1.0, "M2", "", mat, gui, level+1))
dougal2@223
  4732
                (str,link) = c((str,link), luxFloatTexture("M3", keyname, 1.0, 0.0, 1.0, "M3", "", mat, gui, level+1))
dougal2@223
  4733
            else: link += carlink
tomb@250
  4734
            absorption = luxProp(mat, keyname+".useabsorption", "false")
tomb@250
  4735
            luxCollapse("absorption", absorption, "Absorption", "Enable Coating Absorption", gui, 2.0)
tomb@250
  4736
            if absorption.get() == "true":
tomb@250
  4737
                (str,link) = c((str,link), luxSpectrumTexture("Ka", keyname, "0.2 0.2 0.2", 1.0, "absorption", "", mat, gui, level+1))
tomb@250
  4738
                (str,link) = c((str,link), luxFloatTexture("d", keyname, 5.0, 0.0, 15.0, "depth", "", mat, gui, level+1))
dougal2@223
  4739
            has_bump_options = 1
dougal2@223
  4740
            has_object_options = 1
dougal2@223
  4741
            has_emission_options = 1
dougal2@260
  4742
            has_compositing_options = 1
dougal2@258
  4743
        
dougal2@223
  4744
        if mattype.get() == "glass":
dougal2@223
  4745
            (str,link) = c((str,link), luxSpectrumTexture("Kr", keyname, "1.0 1.0 1.0", 1.0, "reflection", "", mat, gui, level+1))
dougal2@223
  4746
            (str,link) = c((str,link), luxSpectrumTexture("Kt", keyname, "1.0 1.0 1.0", 1.0, "transmission", "", mat, gui, level+1))
dougal2@223
  4747
            (str,link) = c((str,link), luxIORFloatTexture("index", keyname, 1.5, 1.0, 6.0, "IOR", "", mat, gui, level+1))
dougal2@223
  4748
            architectural = luxProp(mat, keyname+".architectural", "false")
dougal2@223
  4749
            link += luxBool("architectural", architectural, "architectural", "Enable architectural glass", gui, 2.0)
dougal2@223
  4750
            if architectural.get() == "false":
dougal2@223
  4751
                chromadisp = luxProp(mat, keyname+".chromadisp", "false")
radiance29@245
  4752
                luxCollapse("chromadisp", chromadisp, "Dispersive Refraction", "Enable Chromatic Dispersion", gui, 2.0)
dougal2@223
  4753
                if chromadisp.get() == "true":
dougal2@223
  4754
                    (str,link) = c((str,link), luxCauchyBFloatTexture("cauchyb", keyname, 0.0, 0.0, 1.0, "cauchyb", "", mat, gui, level+1))
dougal2@223
  4755
                thinfilm = luxProp(mat, keyname+".thinfilm", "false")
radiance29@245
  4756
                luxCollapse("thinfilm", thinfilm, "Thin Film Coating", "Enable Thin Film Coating", gui, 2.0)
dougal2@223
  4757
                if thinfilm.get() == "true":
dougal2@223
  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))
dougal2@223
  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))
dougal2@223
  4760
            has_bump_options = 1
dougal2@223
  4761
            has_object_options = 1
dougal2@223
  4762
            has_emission_options = 1
dougal2@258
  4763
            has_compositing_options = 1
dougal2@258
  4764
            
dougal2@223
  4765
        if mattype.get() == "matte":
dougal2@223
  4766
            orennayar = luxProp(mat, keyname+".orennayar", "false")
dougal2@223
  4767
            (str,link) = c((str,link), luxSpectrumTexture("Kd", keyname, "1.0 1.0 1.0", 1.0, "diffuse", "", mat, gui, level+1))
radiance29@245
  4768
            luxCollapse("orennayar", orennayar, "Oren-Nayar", "Enable Oren-Nayar BRDF", gui, 2.0)
dougal2@223
  4769
            if orennayar.get() == "true":
dougal2@223
  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))
dougal2@223
  4771
            has_bump_options = 1
dougal2@223
  4772
            has_object_options = 1
dougal2@223
  4773
            has_emission_options = 1
dougal2@258
  4774
            has_compositing_options = 1
dougal2@258
  4775
        
dougal2@223
  4776
        if mattype.get() == "mattetranslucent":
dougal2@223
  4777
            orennayar = luxProp(mat, keyname+".orennayar", "false")
dougal2@223
  4778
            (str,link) = c((str,link), luxSpectrumTexture("Kr", keyname, "1.0 1.0 1.0", 1.0, "reflection", "", mat, gui, level+1))
dougal2@223
  4779
            (str,link) = c((str,link), luxSpectrumTexture("Kt", keyname, "1.0 1.0 1.0", 1.0, "transmission", "", mat, gui, level+1))
radiance29@245
  4780
            luxCollapse("orennayar", orennayar, "Oren-Nayar", "Enable Oren-Nayar BRDF", gui, 2.0)
dougal2@223
  4781
            if orennayar.get() == "true":
dougal2@223
  4782
                (str,link) = c((str,link), luxFloatTexture("sigma", keyname, 0.0, 0.0, 100.0, "sigma", "", mat, gui, level+1))
dougal2@223
  4783
            has_bump_options = 1
dougal2@223
  4784
            has_object_options = 1
dougal2@223
  4785
            has_emission_options = 1
dougal2@258
  4786
            has_compositing_options = 1
dougal2@258
  4787
        
dougal2@223
  4788
        if mattype.get() == "metal":
dougal2@223
  4789
            if gui: gui.newline("name:", 0, level+1)
dougal2@223
  4790
            metalname = luxProp(mat, kn+"metal.name", "")
dougal2@223
  4791
            metals = ["aluminium","amorphous carbon","silver","gold","copper"]
dougal2@223
  4792
dougal2@223
  4793
            if not(metalname.get() in metals):
dougal2@223
  4794
                metals.append(metalname.get())
dougal2@223
  4795
            metallink = luxOption("name", metalname, metals, "name", "", gui, 1.88)
dougal2@223
  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"))
dougal2@223
  4797
            link += luxstr(metallink)
dougal2@223
  4798
            anisotropic = luxProp(mat, kn+"metal.anisotropic", "false")
dougal2@223
  4799
            if gui:
dougal2@223
  4800
                gui.newline("")
dougal2@223
  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)]))
dougal2@223
  4802
            if anisotropic.get()=="true":
dougal2@223
  4803
                (str,link) = c((str,link), luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "u-exponent", "", mat, gui, level+1))
dougal2@223
  4804
                (str,link) = c((str,link), luxExponentTexture("vroughness", keyname, 0.002, 0.0, 1.0, "v-exponent", "", mat, gui, level+1))
dougal2@223
  4805
            else:
dougal2@223
  4806
                (s, l) = luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "exponent", "", mat, gui, level+1)
dougal2@223
  4807
                (str,link) = c((str,link), (s, l))
dougal2@223
  4808
                link += l.replace("uroughness", "vroughness", 1)
dougal2@223
  4809
                
dougal2@223
  4810
            has_bump_options = 1
dougal2@223
  4811
            has_object_options = 1
dougal2@223
  4812
            has_emission_options = 1
dougal2@258
  4813
            has_compositing_options = 1
dougal2@258
  4814
            
dougal2@223
  4815
        if mattype.get() == "mirror":
dougal2@223
  4816
            (str,link) = c((str,link), luxSpectrumTexture("Kr", keyname, "1.0 1.0 1.0", 1.0, "reflection", "", mat, gui, level+1))
dougal2@223
  4817
            thinfilm = luxProp(mat, keyname+".thinfilm", "false")
radiance29@245
  4818
            luxCollapse("thinfilm", thinfilm, "Thin Film Coating", "Enable Thin Film Coating", gui, 2.0)
dougal2@223
  4819
            if thinfilm.get() == "true":
dougal2@223
  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))
dougal2@223
  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))
dougal2@223
  4822
dougal2@223
  4823
            has_bump_options = 1
dougal2@223
  4824
            has_object_options = 1
dougal2@223
  4825
            has_emission_options = 1
dougal2@258
  4826
            has_compositing_options = 1
dougal2@258
  4827
            
dougal2@223
  4828
        if mattype.get() == "roughglass":
dougal2@223
  4829
            (str,link) = c((str,link), luxSpectrumTexture("Kr", keyname, "1.0 1.0 1.0", 1.0, "reflection", "", mat, gui, level+1))
dougal2@223
  4830
            (str,link) = c((str,link), luxSpectrumTexture("Kt", keyname, "1.0 1.0 1.0", 1.0, "transmission", "", mat, gui, level+1))
dougal2@223
  4831
            anisotropic = luxProp(mat, kn+"roughglass.anisotropic", "false")
dougal2@223
  4832
            if gui:
dougal2@223
  4833
                gui.newline("")
dougal2@223
  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)]))
dougal2@223
  4835
            if anisotropic.get()=="true":
dougal2@223
  4836
                (str,link) = c((str,link), luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "u-exponent", "", mat, gui, level+1))
dougal2@223
  4837
                (str,link) = c((str,link), luxExponentTexture("vroughness", keyname, 0.002, 0.0, 1.0, "v-exponent", "", mat, gui, level+1))
dougal2@223
  4838
            else:
dougal2@223
  4839
                (s, l) = luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "exponent", "", mat, gui, level+1)
dougal2@223
  4840
                (str,link) = c((str,link), (s, l))
dougal2@223
  4841
                link += l.replace("uroughness", "vroughness", 1)
dougal2@223
  4842
            (str,link) = c((str,link), luxIORFloatTexture("index", keyname, 1.5, 1.0, 6.0, "IOR", "", mat, gui, level+1))
dougal2@223
  4843
            chromadisp = luxProp(mat, keyname+".chromadisp", "false")
radiance29@245
  4844
            luxCollapse("chromadisp", chromadisp, "Dispersive Refraction", "Enable Chromatic Dispersion", gui, 2.0)
dougal2@223
  4845
            if chromadisp.get() == "true":
dougal2@223
  4846
                (str,link) = c((str,link), luxCauchyBFloatTexture("cauchyb", keyname, 0.0, 0.0, 1.0, "cauchyb", "", mat, gui, level+1))
dougal2@223
  4847
            has_bump_options = 1
dougal2@223
  4848
            has_object_options = 1
dougal2@223
  4849
            has_emission_options = 1
dougal2@258
  4850
            has_compositing_options = 1
dougal2@258
  4851
            
dougal2@223
  4852
        if mattype.get() == "shinymetal":
dougal2@223
  4853
            (str,link) = c((str,link), luxSpectrumTexture("Kr", keyname, "1.0 1.0 1.0", 1.0, "reflection", "", mat, gui, level+1))
dougal2@223
  4854
            (str,link) = c((str,link), luxSpectrumTexture("Ks", keyname, "1.0 1.0 1.0", 1.0, "specular", "", mat, gui, level+1))
dougal2@223
  4855
            anisotropic = luxProp(mat, kn+"shinymetal.anisotropic", "false")
dougal2@223
  4856
            if gui:
dougal2@223
  4857
                gui.newline("")
dougal2@223
  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)]))
dougal2@223
  4859
            if anisotropic.get()=="true":
dougal2@223
  4860
                (str,link) = c((str,link), luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "u-exponent", "", mat, gui, level+1))
dougal2@223
  4861
                (str,link) = c((str,link), luxExponentTexture("vroughness", keyname, 0.002, 0.0, 1.0, "v-exponent", "", mat, gui, level+1))
dougal2@223
  4862
            else:
dougal2@223
  4863
                (s, l) = luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "exponent", "", mat, gui, level+1)
dougal2@223
  4864
                (str,link) = c((str,link), (s, l))
dougal2@223
  4865
                link += l.replace("uroughness", "vroughness", 1)
dougal2@223
  4866
dougal2@223
  4867
            thinfilm = luxProp(mat, keyname+".thinfilm", "false")
radiance29@245
  4868
            luxCollapse("thinfilm", thinfilm, "Thin Film Coating", "Enable Thin Film Coating", gui, 2.0)
dougal2@223
  4869
            if thinfilm.get() == "true":
dougal2@223
  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))
dougal2@223
  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))
dougal2@223
  4872
dougal2@223
  4873
            has_bump_options = 1
dougal2@223
  4874
            has_object_options = 1
dougal2@223
  4875
            has_emission_options = 1
dougal2@258
  4876
            has_compositing_options = 1
dougal2@258
  4877
            
dougal2@223
  4878
        if mattype.get() == "glossy":
dougal2@223
  4879
            (str,link) = c((str,link), luxSpectrumTexture("Kd", keyname, "1.0 1.0 1.0", 1.0, "diffuse", "", mat, gui, level+1))
dougal2@223
  4880
            useior = luxProp(mat, keyname+".useior", "false")
dougal2@223
  4881
            if gui:
dougal2@223
  4882
                gui.newline("")
dougal2@223
  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)]))
dougal2@223
  4884
            if useior.get() == "true":
dougal2@223
  4885
                (str,link) = c((str,link), luxIORFloatTexture("index", keyname, 1.5, 1.0, 50.0, "IOR", "", mat, gui, level+1))
dougal2@223
  4886
                link += " \"color Ks\" [1.0 1.0 1.0]"    
dougal2@223
  4887
            else:
dougal2@223
  4888
                (str,link) = c((str,link), luxSpectrumTexture("Ks", keyname, "1.0 1.0 1.0", 1.0, "specular", "", mat, gui, level+1))
dougal2@223
  4889
                link += " \"float index\" [0.0]"    
dougal2@223
  4890
            anisotropic = luxProp(mat, kn+"glossy.anisotropic", "false")
dougal2@223
  4891
            if gui:
dougal2@223
  4892
                gui.newline("")
dougal2@223
  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)]))
dougal2@223
  4894
            if anisotropic.get()=="true":
dougal2@223
  4895
                (str,link) = c((str,link), luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "u-exponent", "", mat, gui, level+1))
dougal2@223
  4896
                (str,link) = c((str,link), luxExponentTexture("vroughness", keyname, 0.002, 0.0, 1.0, "v-exponent", "", mat, gui, level+1))
dougal2@223
  4897
            else:
dougal2@223
  4898
                (s, l) = luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "exponent", "", mat, gui, level+1)
dougal2@223
  4899
                (str,link) = c((str,link), (s, l))
dougal2@223
  4900
                link += l.replace("uroughness", "vroughness", 1)
dougal2@223
  4901
dougal2@223
  4902
            absorption = luxProp(mat, keyname+".useabsorption", "false")
radiance29@245
  4903
            luxCollapse("absorption", absorption, "Absorption", "Enable Coating Absorption", gui, 2.0)
dougal2@223
  4904
            if absorption.get() == "true":
tomb@251
  4905
                (str,link) = c((str,link), luxSpectrumTexture("Ka", keyname, "0.2 0.2 0.2", 1.0, "absorption", "", mat, gui, level+1))
tomb@251
  4906
                (str,link) = c((str,link), luxFloatTexture("d", keyname, 0.15, 0.0, 15.0, "depth", "", mat, gui, level+1))
dougal2@223
  4907
            has_bump_options = 1
dougal2@223
  4908
            has_object_options = 1
dougal2@223
  4909
            has_emission_options = 1
dougal2@258
  4910
            has_compositing_options = 1
doug@334
  4911
            
doug@334
  4912
        if mattype.get() == 'null':
doug@334
  4913
        	has_emission_options = 1
dougal2@223
  4914
dougal2@223
  4915
        # Bump mapping options (common)
dougal2@223
  4916
        if (has_bump_options == 1):
dougal2@223
  4917
            usebump = luxProp(mat, keyname+".usebump", "false")
radiance29@245
  4918
            luxCollapse("usebump", usebump, "Bump Map", "Enable Bump Mapping options", gui, 2.0)
dougal2@223
  4919
            if usebump.get() == "true":
doug@335
  4920
                (str,link) = c((str,link), luxFloatTexture("bumpmap", keyname, 0.0, -1.0, 1.0, "bumpmap", "", mat, gui, level+1))
dougal2@223
  4921
dougal2@223
  4922
        # emission options (common)
dougal2@223
  4923
        if (level == 0):
dougal2@223
  4924
            if (has_emission_options == 1):
dougal2@223
  4925
                if gui: gui.newline("", 2, level, None, [0.6,0.6,0.4])
dougal2@223
  4926
                useemission = luxProp(mat, "emission", "false")
radiance29@245
  4927
                luxCollapse("useemission", useemission, "Emission", "Enable emission options", gui, 2.0)
dougal2@223
  4928
                if useemission.get() == "true":
dougal2@223
  4929
                    # emission GUI is here but lux export will be done later 
dougal2@223
  4930
                    luxLight("", "", mat, gui, level)
dougal2@223
  4931
            else: luxProp(mat, "emission", "false").set("false") # prevent from exporting later
dougal2@223
  4932
radiance29@245
  4933
dougal2@260
  4934
        # Compositing options (common)
dougal2@260
  4935
        # Note - currently only display options when using distributedpath integrator
dougal2@260
  4936
        integratortype = luxProp(Scene.GetCurrent(), "sintegrator.type", "bidirectional")
dougal2@260
  4937
        if (integratortype.get() == "distributedpath" and level == 0):
dougal2@260
  4938
            if (has_compositing_options == 1):
dougal2@260
  4939
                if gui: gui.newline("", 2, level, None, [0.4,0.4,0.6])
dougal2@260
  4940
                usecompo = luxProp(mat, "compo", "false")
dougal2@260
  4941
                luxCollapse("compo", usecompo, "Compositing", "Enable Compositing options", gui, 2.0)
dougal2@260
  4942
                if usecompo.get() == "true":
dougal2@260
  4943
                    if gui: gui.newline("", 2, level, None, [0.35,0.35,0.55])
dougal2@260
  4944
                    usecompoviz = luxProp(mat, "compo_viz", "false")
dougal2@260
  4945
                    luxCollapse("compo_viz", usecompoviz, "Visibility", "Enable Visibility Compositing options", gui, 2.0)
dougal2@260
  4946
                    if usecompoviz.get() == "true":
dougal2@260
  4947
                        if gui: gui.newline("View", 2, level, None, [0.35,0.35,0.55])
dougal2@260
  4948
                        compovizmat = luxProp(mat, "compo_viz_mat", "true")
dougal2@260
  4949
                        link += luxBool("compo_visible_material", compovizmat, "Material", "Enable View Visibility of Material", gui, 1.0)
dougal2@260
  4950
                        compovizemi = luxProp(mat, "compo_viz_emi", "true")
dougal2@260
  4951
                        link += luxBool("compo_visible_emission", compovizemi, "Emission", "Enable View Visibility of Emission", gui, 1.0)
dougal2@260
  4952
                        
dougal2@260
  4953
                        if gui: gui.newline("Indirect", 2, level, None, [0.35,0.35,0.55])
dougal2@260
  4954
                        compovizmati = luxProp(mat, "compo_viz_mati", "true")
dougal2@260
  4955
                        link += luxBool("compo_visible_indirect_material", compovizmati, "Material", "Enable InDirect Visibility of Material", gui, 1.0)
dougal2@260
  4956
                        compovizemii = luxProp(mat, "compo_viz_emii", "true")
dougal2@260
  4957
                        link += luxBool("compo_visible_indirect_emission", compovizemii, "Emission", "Enable InDirect Visibility of Emission", gui, 1.0)
dougal2@259
  4958
                    
dougal2@260
  4959
                    if gui: gui.newline("", 2, level, None, [0.4,0.4,0.6])
dougal2@260
  4960
                    overridealpha = luxProp(mat, "compo_o_alpha", "false")
dougal2@260
  4961
                    link += luxCollapse("compo_override_alpha", overridealpha, "Override Alpha", "Enable Manual control of alpha value", gui, 2.0)
dougal2@260
  4962
                    if overridealpha.get() == "true":
dougal2@260
  4963
                        if gui: gui.newline("Alpha", 2, level, None, [0.4,0.4,0.6])
dougal2@260
  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)
dougal2@260
  4965
                    usecolorkey = luxProp(mat, "compo_usekey", "false")
dougal2@260
  4966
                    if gui: gui.newline("", 2, level, None, [0.35,0.35,0.55])
dougal2@260
  4967
                    link += luxCollapse("compo_use_key", usecolorkey, "Chroma Key", "Enable Chroma Object key", gui, 2.0)
dougal2@260
  4968
                    if usecolorkey.get() == "true":
dougal2@260
  4969
                        if gui: gui.newline("Key", 2, level, None, [0.35,0.35,0.55])
dougal2@260
  4970
                        link += luxRGB("compo_key_color", luxProp(mat, "compo_key_color", "0.0 0.0 1.0"), 1.0, "key", "", gui, 2.0)
radiance29@245
  4971
dougal2@223
  4972
        # transformation options (common)
doug@332
  4973
        if (level == 0) and mattype.get() not in ['portal', 'null']:
dougal2@223
  4974
            if gui: gui.newline("", 2, level, None, [0.6,0.6,0.4])
dougal2@223
  4975
            usetransformation = luxProp(mat, "transformation", "false")
radiance29@245
  4976
            luxCollapse("usetransformation", usetransformation, "Texture Transformation", "Enable transformation option", gui, 2.0)
dougal2@223
  4977
            if usetransformation.get() == "true":
dougal2@223
  4978
                scale = luxProp(mat, "3dscale", 1.0)
dougal2@223
  4979
                rotate = luxProp(mat, "3drotate", "0 0 0")
dougal2@223
  4980
                translate = luxProp(mat, "3dtranslate", "0 0 0")
dougal2@223
  4981
                if gui:
dougal2@223
  4982
                    gui.newline("scale:", -2, level, icon_map3dparam)
dougal2@223
  4983
                    luxVectorUniform("scale", scale, 0.001, 1000.0, "scale", "scale-vector", gui, 2.0)
dougal2@223
  4984
                    gui.newline("rot:", -2, level, icon_map3dparam)
dougal2@223
  4985
                    luxVector("rotate", rotate, -360.0, 360.0, "rotate", "rotate-vector", gui, 2.0)
dougal2@223
  4986
                    gui.newline("move:", -2, level, icon_map3dparam)
dougal2@223
  4987
                    luxVector("translate", translate, -1000.0, 1000.0, "move", "translate-vector", gui, 2.0)
dougal2@223
  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"
dougal2@223
  4989
dougal2@223
  4990
        # Object options (common)
dougal2@223
  4991
        if (level == 0) and (has_object_options == 1):
dougal2@223
  4992
            if gui: gui.newline("Mesh:", 2, level, icon, [0.6,0.6,0.4])
dougal2@223
  4993
            usesubdiv = luxProp(mat, "subdiv", "false")
dougal2@223
  4994
            luxBool("usesubdiv", usesubdiv, "Subdivision", "Enable Loop Subdivision options", gui, 1.0)
dougal2@223
  4995
            usedisp = luxProp(mat, "dispmap", "false")
dougal2@223
  4996
            luxBool("usedisp", usedisp, "Displacement Map", "Enable Displacement mapping options", gui, 1.0)
dougal2@223
  4997
            if usesubdiv.get() == "true" or usedisp.get() == "true":
dougal2@223
  4998
                luxInt("sublevels", luxProp(mat, "sublevels", 2), 0, 12, "sublevels", "The number of levels of object subdivision", gui, 2.0)
dougal2@223
  4999
                sharpbound = luxProp(mat, "sharpbound", "false")
dougal2@223
  5000
                luxBool("sharpbound", sharpbound, "Sharpen Bounds", "Sharpen boundaries during subdivision", gui, 1.0)
dougal2@223
  5001
                nsmooth = luxProp(mat, "nsmooth", "true")
dougal2@223
  5002
                luxBool("nsmooth", nsmooth, "Smooth", "Smooth faces during subdivision", gui, 1.0)
dougal2@223
  5003
            if usedisp.get() == "true":
dougal2@223
  5004
                (str,ll) = c((str,link), luxDispFloatTexture("dispmap", keyname, 0.1, -10, 10.0, "dispmap", "Displacement Mapping amount", mat, gui, level+1))
dougal2@223
  5005
                luxFloat("sdoffset",  luxProp(mat, "sdoffset", 0.0), 0.0, 1.0, "Offset", "Offset for displacement map", gui, 2.0)
dougal2@223
  5006
                usesubdiv.set("true");
dougal2@223
  5007
dougal2@223
  5008
        if mattype.get() == "light":
dougal2@223
  5009
            return (str, link)
dougal2@223
  5010
dougal2@223
  5011
        str += "MakeNamedMaterial \"%s\"%s\n"%(matname, link)
dougal2@223
  5012
    return (str, " \"string %s\" [\"%s\"]"%(luxname, matname))
zuegs@47
  5013
zuegs@47
  5014
zuegs@47
  5015
def luxMaterial(mat, gui=None):
dougal2@223
  5016
    str = ""
dougal2@223
  5017
    if mat:
dougal2@223
  5018
        if luxProp(mat, "type", "").get()=="": # lux material not defined yet
dougal2@223
  5019
            print "Blender material \"%s\" has no lux material definition, converting..."%(mat.getName())
dougal2@223
  5020
            try:
dougal2@223
  5021
                convertMaterial(mat) # try converting the blender material to a lux material
dougal2@223
  5022
            except: pass
dougal2@223
  5023
        (str, link) = luxMaterialBlock("", "", "", mat, gui, 0)
dougal2@223
  5024
        if luxProp(mat, "type", "matte").get() != "light":
dougal2@223
  5025
            link = "NamedMaterial \"%s\""%(mat.getName())
dougal2@223
  5026
        # export emission options (no gui)
dougal2@223
  5027
        useemission = luxProp(mat, "emission", "false")
dougal2@223
  5028
        if useemission.get() == "true":
dougal2@227
  5029
            lightgroup = luxProp(mat, "light.lightgroup", "default")
doughammond@325
  5030
            if luxProp(Scene.GetCurrent(), "nolg", "false").get()!="true":
doughammond@325
  5031
                link += "\n\tLightGroup \"%s\"\n"%lightgroup.get()
dougal2@227
  5032
            
dougal2@223
  5033
            (estr, elink) = luxLight("", "", mat, None, 0)
dougal2@223
  5034
            str += estr
dougal2@223
  5035
            link += "\n\tAreaLightSource \"area\" "+elink 
dougal2@223
  5036
            
dougal2@223
  5037
        luxProp(mat, "link", "").set("".join(link))
dougal2@260
  5038
        
dougal2@223
  5039
    return str
dougal2@223
  5040
        
zuegs@21
  5041
radiance29@64
  5042
def luxVolume(mat, gui=None):
dougal2@223
  5043
    str = ""
dougal2@223
  5044
    if mat:
dougal2@223
  5045
        (str, link) = luxMaterialBlock("", "", "", mat, gui, 0)
dougal2@223
  5046
        luxProp(mat, "link", "").set("".join(link))
dougal2@223
  5047
    return str
zuegs@21
  5048
dougal2@196
  5049
runRenderAfterExport = None
zuegs@21
  5050
def CBluxExport(default, run):
dougal2@223
  5051
    global runRenderAfterExport
dougal2@223
  5052
    runRenderAfterExport = run
dougal2@223
  5053
    if default:
dougal2@223
  5054
        datadir = luxProp(Scene.GetCurrent(), "datadir", "").get()
dougal2@223
  5055
        if datadir=="": datadir = Blender.Get("datadir")
dougal2@223
  5056
        filename = datadir + os.sep + "default.lxs"
dougal2@223
  5057
        save_still(filename)
dougal2@223
  5058
    else:
dougal2@223
  5059
        Window.FileSelector(save_still, "Export", sys.makename(Blender.Get("filename"), ".lxs"))
zuegs@21
  5060
zuegs@21
  5061
zuegs@171
  5062
def CBluxAnimExport(default, run, fileselect=True):
dougal2@223
  5063
    if default:
dougal2@223
  5064
        datadir = luxProp(Scene.GetCurrent(), "datadir", "").get()
dougal2@223
  5065
        if datadir=="": datadir = Blender.Get("datadir")
dougal2@223
  5066
        filename = datadir + os.sep + "default.lxs"
dougal2@223
  5067
        save_anim(filename)
dougal2@223
  5068
    else:
dougal2@223
  5069
        if fileselect:
dougal2@223
  5070
            Window.FileSelector(save_anim, "Export", sys.makename(Blender.Get("filename"), ".lxs"))
dougal2@223
  5071
        else:
dougal2@223
  5072
            datadir = luxProp(Scene.GetCurrent(), "datadir", "").get()
dougal2@223
  5073
            if datadir=="": datadir = Blender.Get("datadir")
dougal2@223
  5074
            filename = sys.makename(Blender.Get("filename") , ".lxs")
dougal2@223
  5075
            save_anim(filename)
dade916@57
  5076
zuegs@116
  5077
zuegs@83
  5078
# convert a Blender material to lux material
zuegs@83
  5079
def convertMaterial(mat):
dougal2@223
  5080
    def dot(str):
dougal2@223
  5081
        if str != "": return str+"."
dougal2@223
  5082
        return str
dougal2@223
  5083
    def ddot(str):
dougal2@223
  5084
        if str != "": return str+":"
dougal2@223
  5085
        return str
dougal2@223
  5086
    def mapConstDict(value, constant_dict, lux_dict, default=None):
dougal2@223
  5087
        for k,v in constant_dict.items():
dougal2@223
  5088
            if (v == value) and (lux_dict.has_key(k)):
dougal2@223
  5089
                return lux_dict[k]
dougal2@223
  5090
        return default
dougal2@223
  5091
dougal2@223
  5092
    def convertMapping(name, tex):
dougal2@223
  5093
        if tex.texco == Texture.TexCo["UV"]:
dougal2@223
  5094
            luxProp(mat, dot(name)+"mapping","").set("uv")
dougal2@223
  5095
            luxProp(mat, dot(name)+"uscale", 1.0).set(tex.size[0])
dougal2@223
  5096
            luxProp(mat, dot(name)+"vscale", 1.0).set(-tex.size[1])
dougal2@223
  5097
            luxProp(mat, dot(name)+"udelta", 0.0).set(tex.ofs[0]+0.5*(1.0-tex.size[0]))
dougal2@223
  5098
            luxProp(mat, dot(name)+"vdelta", 0.0).set(-tex.ofs[1]-0.5*(1.0-tex.size[1]))
dougal2@223
  5099
            if tex.mapping != Texture.Mappings["FLAT"]:
dougal2@223
  5100
                print "Material Conversion Warning: for UV-texture-input only FLAT mapping is supported\n" 
dougal2@223
  5101
        else:
dougal2@223
  5102
            if tex.mapping == Texture.Mappings["FLAT"]:
dougal2@223
  5103
                luxProp(mat, dot(name)+"mapping","").set("planar")
dougal2@223
  5104
            elif tex.mapping == Texture.Mappings["TUBE"]:
dougal2@223
  5105
                luxProp(mat, dot(name)+"mapping","").set("cylindrical")
dougal2@223
  5106
            elif tex.mapping == Texture.Mappings["SPHERE"]:
dougal2@223
  5107
                luxProp(mat, dot(name)+"mapping","").set("spherical")
dougal2@223
  5108
            else: luxProp(mat, dot(name)+"mapping","").set("planar")
dougal2@223
  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]))
dougal2@223
  5110
        luxProp(mat, dot(name)+"3dtranslate", "0.0 0.0 0.0").setVector((-tex.ofs[0], -tex.ofs[1], -tex.ofs[2]))
dougal2@223
  5111
dougal2@223
  5112
    def convertColorband(colorband):
dougal2@223
  5113
        # colorbands are not supported in lux - so lets extract a average low-side and high-side color
dougal2@223
  5114
        cb = [colorband[0]] + colorband[:] + [colorband[-1]]
dougal2@223
  5115
        cb[0][4], cb[-1][4] = 0.0, 1.0
dougal2@223
  5116
        low, high = [0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0]
dougal2@223
  5117
        for i in range(1, len(cb)):
dougal2@223
  5118
            for c in range(4):
dougal2@223
  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])
dougal2@223
  5120
                high[c] += (cb[i-1][c]*cb[i-1][4] + cb[i][c]*cb[i][4]) * (cb[i][4]-cb[i-1][4])
dougal2@223
  5121
        return low, high
dougal2@223
  5122
dougal2@223
  5123
    def createLuxTexture(name, tex):
dougal2@223
  5124
        texture = tex.tex
dougal2@223
  5125
        convertMapping(name, tex)
dougal2@223
  5126
        if (texture.type == Texture.Types["IMAGE"]) and (texture.image) and (texture.image.filename!=""):
dougal2@223
  5127
            luxProp(mat, dot(name)+"texture", "").set("imagemap")
dougal2@223
  5128
            luxProp(mat, dot(name)+"filename", "").set(texture.image.filename)
dougal2@223
  5129
            luxProp(mat, dot(name)+"wrap", "").set(mapConstDict(texture.extend, Texture.ExtendModes, {"REPEAT":"repeat", "EXTEND":"clamp", "CLIP":"black"}, ""))
dougal2@223
  5130
        else:
dougal2@223
  5131
            if tex.texco != Texture.TexCo["GLOB"]:
dougal2@223
  5132
                print "Material Conversion Warning: procedural textures supports global mapping only\n"
dougal2@223
  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"}
dougal2@223
  5134
            luxProp(mat, dot(name)+"bright", 1.0).set(texture.brightness)
dougal2@223
  5135
            luxProp(mat, dot(name)+"contrast", 1.0).set(texture.contrast)
dougal2@223
  5136
            if texture.type == Texture.Types["CLOUDS"]:
dougal2@223
  5137
                luxProp(mat, dot(name)+"texture", "").set("blender_clouds")
dougal2@223
  5138
                luxProp(mat, dot(name)+"mtype", "").set(mapConstDict(texture.stype, Texture.STypes, {"CLD_DEFAULT":"default", "CLD_COLOR":"color"}, ""))
dougal2@223
  5139
                luxProp(mat, dot(name)+"noisetype", "").set({"soft":"soft_noise", "hard":"hard_noise"}[texture.noiseType])
dougal2@223
  5140
                luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
dougal2@223
  5141
                luxProp(mat, dot(name)+"noisedepth", 2).set(texture.noiseDepth)
dougal2@223
  5142
                luxProp(mat, dot(name)+"noisebasis", "").set(mapConstDict(texture.noiseBasis, Texture.Noise, noiseDict, ""))
dougal2@223
  5143
            elif texture.type == Texture.Types["WOOD"]:
dougal2@223
  5144
                luxProp(mat, dot(name)+"texture", "").set("blender_wood")
dougal2@223
  5145
                luxProp(mat, dot(name)+"mtype", "").set(mapConstDict(texture.stype, Texture.STypes, {"WOD_BANDS":"bands", "WOD_RINGS":"rings", "WOD_BANDNOISE":"bandnoise", "WOD_RINGNOISE":"ringnoise"}, ""))
dougal2@223
  5146
                luxProp(mat, dot(name)+"noisebasis2", "").set(mapConstDict(texture.noiseBasis2, Texture.Noise, {"SINE":"sin", "SAW":"saw", "TRI":"tri"}, ""))
dougal2@223
  5147
                luxProp(mat, dot(name)+"noisebasis", "").set(mapConstDict(texture.noiseBasis, Texture.Noise, noiseDict, ""))
dougal2@223
  5148
                luxProp(mat, dot(name)+"noisetype", "").set({"soft":"soft_noise", "hard":"hard_noise"}[texture.noiseType])
dougal2@223
  5149
                luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
dougal2@223
  5150
                luxProp(mat, dot(name)+"turbulance", 0.25).set(texture.turbulence)
dougal2@223
  5151
            elif texture.type == Texture.Types["MUSGRAVE"]:
dougal2@223
  5152
                luxProp(mat, dot(name)+"texture", "").set("blender_musgrave")
dougal2@223
  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"}, ""))
dougal2@223
  5154
                luxProp(mat, dot(name)+"noisebasis", "").set(mapConstDict(texture.noiseBasis, Texture.Noise, noiseDict, ""))
dougal2@223
  5155
                luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
dougal2@223
  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)
dougal2@223
  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
dougal2@223
  5158
                else: luxProp(mat, dot(name)+"h", 1.0).set(0.5) # use a default value
dougal2@223
  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)
dougal2@223
  5160
                try:
dougal2@223
  5161
                    luxProp(mat, dot(name)+"offset", 1.0).set(texture.offset)
dougal2@223
  5162
                    luxProp(mat, dot(name)+"gain", 1.0).set(texture.gain)
dougal2@223
  5163
                except AttributeError: pass
dougal2@223
  5164
                luxProp(mat, dot(name)+"lacu", 2.0).set(texture.lacunarity)
dougal2@223
  5165
                luxProp(mat, dot(name)+"octs", 2.0).set(texture.octs)
dougal2@223
  5166
                luxProp(mat, dot(name)+"outscale", 1.0).set(texture.iScale)
dougal2@223
  5167
            elif texture.type == Texture.Types["MARBLE"]:
dougal2@223
  5168
                luxProp(mat, dot(name)+"texture", "").set("blender_marble")
dougal2@223
  5169
                luxProp(mat, dot(name)+"mtype", "").set(mapConstDict(texture.stype, Texture.STypes, {"MBL_SOFT":"soft", "MBL_SHARP":"sharp", "MBL_SHARPER":"sharper"}, ""))
dougal2@223
  5170
                luxProp(mat, dot(name)+"noisetype", "").set({"soft":"soft_noise", "hard":"hard_noise"}[texture.noiseType])
dougal2@223
  5171
                luxProp(mat, dot(name)+"turbulance", 0.25).set(texture.turbulence)
dougal2@223
  5172
                luxProp(mat, dot(name)+"noisedepth", 2).set(texture.noiseDepth)
dougal2@223
  5173
                luxProp(mat, dot(name)+"noisebasis", "").set(mapConstDict(texture.noiseBasis, Texture.Noise, noiseDict, ""))
dougal2@223
  5174
                luxProp(mat, dot(name)+"noisebasis2", "").set(mapConstDict(texture.noiseBasis2, Texture.Noise, {"SINE":"sin", "SAW":"saw", "TRI":"tri"}, ""))
dougal2@223
  5175
                luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
dougal2@223
  5176
            elif texture.type == Texture.Types["VORONOI"]:
dougal2@223
  5177
                luxProp(mat, dot(name)+"texture", "").set("blender_voronoi")
dougal2@223
  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])
dougal2@223
  5179
                luxProp(mat, dot(name)+"outscale", 1.0).set(texture.iScale)
dougal2@223
  5180
                luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
dougal2@223
  5181
                luxProp(mat, dot(name)+"minkosky_exp", 2.5).set(texture.exp)
dougal2@223
  5182
                luxProp(mat, dot(name)+"w1", 1.0).set(texture.weight1)
dougal2@223
  5183
                luxProp(mat, dot(name)+"w2", 0.0).set(texture.weight2)
dougal2@223
  5184
                luxProp(mat, dot(name)+"w3", 0.0).set(texture.weight3)
dougal2@223
  5185
                luxProp(mat, dot(name)+"w4", 0.0).set(texture.weight4)
dougal2@223
  5186
            elif texture.type == Texture.Types["NOISE"]:
dougal2@223
  5187
                luxProp(mat, dot(name)+"texture", "").set("blender_noise")
dougal2@223
  5188
            elif texture.type == Texture.Types["DISTNOISE"]:
dougal2@223
  5189
                luxProp(mat, dot(name)+"texture", "").set("blender_distortednoise")
dougal2@223
  5190
                luxProp(mat, dot(name)+"distamount", 1.0).set(texture.distAmnt)
dougal2@223
  5191
                luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
dougal2@223
  5192
                luxProp(mat, dot(name)+"noisebasis", "").set(mapConstDict(texture.noiseBasis, Texture.Noise, noiseDict, ""))
dougal2@223
  5193
                luxProp(mat, dot(name)+"noisebasis2", "").set(mapConstDict(texture.noiseBasis2, Texture.Noise, noiseDict, ""))
dougal2@223
  5194
            elif texture.type == Texture.Types["MAGIC"]:
dougal2@223
  5195
                luxProp(mat, dot(name)+"texture", "").set("blender_magic")
dougal2@223
  5196
                luxProp(mat, dot(name)+"turbulance", 0.25).set(texture.turbulence)
dougal2@223
  5197
                luxProp(mat, dot(name)+"noisedepth", 2).set(texture.noiseDepth)
dougal2@223
  5198
            elif texture.type == Texture.Types["STUCCI"]:
dougal2@223
  5199
                luxProp(mat, dot(name)+"texture", "").set("blender_stucci")
dougal2@223
  5200
                luxProp(mat, dot(name)+"mtype", "").set(mapConstDict(texture.stype, Texture.STypes, {"STC_PLASTIC":"Plastic", "MSTC_WALLIN":"Wall In", "STC_WALLOUT":"Wall Out"}, ""))
dougal2@223
  5201
                luxProp(mat, dot(name)+"noisetype", "").set({"soft":"soft_noise", "hard":"hard_noise"}[texture.noiseType])
dougal2@223
  5202
                luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
dougal2@223
  5203
                luxProp(mat, dot(name)+"turbulance", 0.25).set(texture.turbulence)
dougal2@223
  5204
                luxProp(mat, dot(name)+"noisebasis", "").set(mapConstDict(texture.noiseBasis, Texture.Noise, noiseDict, ""))
dougal2@223
  5205
            elif texture.type == Texture.Types["BLEND"]:
dougal2@223
  5206
                luxProp(mat, dot(name)+"texture", "").set("blender_blend")
dougal2@223
  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"}, ""))
dougal2@223
  5208
                luxProp(mat, dot(name)+"flipXY", "false").set({0:"false", 1:"true"}[texture.rot90])
dougal2@223
  5209
            else:
dougal2@223
  5210
                print "Material Conversion Warning: SORRY, this procedural texture isn\'t implemented in conversion\n"
dougal2@223
  5211
dougal2@223
  5212
    def convertTextures(basename, texs, type="float", channel="col", val=1.0):
dougal2@223
  5213
        tex = texs.pop()
dougal2@223
  5214
        texture = tex.tex
dougal2@223
  5215
        isImagemap = (texture.type == Texture.Types["IMAGE"]) and (texture.image) and (texture.image.filename!="")
dougal2@223
  5216
        if channel == "col":
dougal2@223
  5217
            if texture.flags & Texture.Flags["COLORBAND"] > 0:
dougal2@223
  5218
                cbLow, cbHigh = convertColorband(texture.colorband)
dougal2@223
  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
dougal2@223
  5220
                if tex.noRGB:
dougal2@223
  5221
                    lum1, lum2 = (val1[0]+val1[1]+val1[2])/3.0, (val2[0]+val2[1]+val2[2])/3.0
dougal2@223
  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)
dougal2@223
  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
dougal2@223
  5224
            else: val1, alpha1, val2, alpha2 = tex.col, 0.0, tex.col, tex.colfac
dougal2@223
  5225
        elif channel == "nor": val1, alpha1, val2, alpha2 = tex.norfac * 0.01, 0.0, tex.norfac * 0.01, 1.0
dougal2@223
  5226
        else: val1, alpha1, val2, alpha2 = 1.0, 0.0, 1.0, tex.varfac
dougal2@223
  5227
        if (tex.neg)^((channel=="nor") and (tex.mtNor<0)): val1, alpha1, val2, alpha2 = val2, alpha2, val1, alpha1
dougal2@223
  5228
        luxProp(mat, dot(basename)+"textured", "").set("true")
dougal2@223
  5229
dougal2@223
  5230
        name = basename
dougal2@223
  5231
        if (alpha1 < 1.0) or (alpha2 < 1.0): # texture with transparency
dougal2@223
  5232
            luxProp(mat, dot(basename)+"texture", "").set("mix")
dougal2@223
  5233
            if alpha1 == alpha2: # constant alpha
dougal2@223
  5234
                luxProp(mat, ddot(basename)+"amount.value", 1.0).set(alpha1)
dougal2@223
  5235
            else:
dougal2@223
  5236
                createLuxTexture(ddot(basename)+"amount", tex)
dougal2@223
  5237
                luxProp(mat, ddot(basename)+"amount:tex1.value", 1.0).set(alpha1)
dougal2@223
  5238
                luxProp(mat, ddot(basename)+"amount:tex2.value", 1.0).set(alpha2)
dougal2@223
  5239
            # transparent to next texture
dougal2@223
  5240
            name = ddot(basename)+"tex1"
dougal2@223
  5241
            if len(texs) > 0:
dougal2@223
  5242
                convertTextures(ddot(basename)+"tex1", texs, type, channel, val)
dougal2@223
  5243
            else:
dougal2@223
  5244
                if type=="float": luxProp(mat, ddot(basename)+"tex1.value", 1.0).set(val);
dougal2@223
  5245
                else: luxProp(mat, ddot(basename)+"tex1.value", "1.0 1.0 1.0").setRGB((val[0], val[1], val[2]))
dougal2@223
  5246
            name = ddot(basename)+"tex2"
dougal2@223
  5247
        if val1 == val2: # texture with different colors / value
dougal2@223
  5248
            if type == "col": luxProp(mat, dot(name)+"value", "1.0 1.0 1.0").setRGB(val1)
dougal2@223
  5249
            else: luxProp(mat, dot(name)+"value", 1.0).set(val1)
dougal2@223
  5250
        else:
dougal2@223
  5251
            createLuxTexture(name, tex)
dougal2@223
  5252
            if type == "col": luxProp(mat, ddot(name)+"tex1.value", "1.0 1.0 1.0").setRGB(val1)
dougal2@223
  5253
            else: luxProp(mat, ddot(name)+"tex1.value", 1.0).set(val1)
dougal2@223
  5254
            if type == "col": luxProp(mat, ddot(name)+"tex2.value", "1.0 1.0 1.0").setRGB(val2)
dougal2@223
  5255
            else: luxProp(mat, ddot(name)+"tex2.value", 1.0).set(val2)
dougal2@223
  5256
dougal2@223
  5257
dougal2@223
  5258
    def convertDiffuseTexture(name):
dougal2@223
  5259
        texs = []
dougal2@223
  5260
        for tex in mat.getTextures():
dougal2@223
  5261
            if tex and (tex.mapto & Texture.MapTo["COL"] > 0) and (tex.tex) and (tex.tex.type != Texture.Types["NONE"]): texs.append(tex)
dougal2@223
  5262
        if len(texs) > 0:
dougal2@223
  5263
            luxProp(mat, name, "").setRGB((mat.ref, mat.ref, mat.ref))
dougal2@223
  5264
            convertTextures(name, texs, "col", "col", (mat.R, mat.G, mat.B))
dougal2@223
  5265
    def convertSpecularTexture(name):
dougal2@223
  5266
        texs = []
dougal2@223
  5267
        for tex in mat.getTextures():
dougal2@223
  5268
            if tex and (tex.mapto & Texture.MapTo["CSP"] > 0) and (tex.tex) and (tex.tex.type != Texture.Types["NONE"]): texs.append(tex)
dougal2@223
  5269
        if len(texs) > 0:
dougal2@223
  5270
            luxProp(mat, name, "").setRGB((mat.ref*mat.spec, mat.ref*mat.spec, mat.ref*mat.spec))
dougal2@223
  5271
            convertTextures(name, texs, "col", "col", (mat.specR, mat.specG, mat.specB))
dougal2@223
  5272
    def convertMirrorTexture(name):
dougal2@223
  5273
        texs = []
dougal2@223
  5274
        for tex in mat.getTextures():
dougal2@223
  5275
            if tex and (tex.mapto & Texture.MapTo["CMIR"] > 0) and (tex.tex) and (tex.tex.type != Texture.Types["NONE"]): texs.append(tex)
dougal2@223
  5276
        if len(texs) > 0:
dougal2@223
  5277
            luxProp(mat, name, "").setRGB((mat.ref, mat.ref, mat.ref))
dougal2@223
  5278
            convertTextures(name, texs, "col", "col", (mat.mirR, mat.mirG, mat.mirB))
dougal2@223
  5279
    def convertBumpTexture(basename):
dougal2@223
  5280
        texs = []
dougal2@223
  5281
        for tex in mat.getTextures():
dougal2@223
  5282
            if tex and (tex.mapto & Texture.MapTo["NOR"] > 0) and (tex.tex) and (tex.tex.type != Texture.Types["NONE"]): texs.append(tex)
dougal2@223
  5283
        if len(texs) > 0:
dougal2@223
  5284
            name = basename+":bumpmap"
dougal2@223
  5285
            luxProp(mat, basename+".usebump", "").set("true")
dougal2@223
  5286
            luxProp(mat, dot(name)+"textured", "").set("true")
dougal2@223
  5287
            luxProp(mat, name, "").set(1.0)
dougal2@223
  5288
            convertTextures(name, texs, "float", "nor", 0.0)
dougal2@223
  5289
dougal2@223
  5290
    def makeMatte(name):
dougal2@223
  5291
        luxProp(mat, dot(name)+"type", "").set("matte")
dougal2@223
  5292
        luxProp(mat, name+":Kd", "").setRGB((mat.R*mat.ref, mat.G*mat.ref, mat.B*mat.ref))
dougal2@223
  5293
        convertDiffuseTexture(name+":Kd")
dougal2@223
  5294
        convertBumpTexture(name)
dougal2@223
  5295
    def makeGlossy(name, roughness):
dougal2@223
  5296
        luxProp(mat, dot(name)+"type", "").set("glossy")
dougal2@223
  5297
        luxProp(mat, name+":Kd", "").setRGB((mat.R*mat.ref, mat.G*mat.ref, mat.B*mat.ref))
dougal2@223
  5298
        luxProp(mat, name+":Ks", "").setRGB((mat.specR*mat.spec*0.5, mat.specG*mat.spec*0.5, mat.specB*mat.spec*0.5))
dougal2@223
  5299
        luxProp(mat, name+":uroughness", 0.0).set(roughness)
dougal2@223
  5300
        luxProp(mat, name+":vroughness", 0.0).set(roughness)
dougal2@223
  5301
        convertDiffuseTexture(name+":Kd")
dougal2@223
  5302
        convertSpecularTexture(name+":Ks")
dougal2@223
  5303
        convertBumpTexture(name)
dougal2@223
  5304
    def makeMirror(name):
dougal2@223
  5305
        luxProp(mat, dot(name)+"type", "").set("mirror")
dougal2@223
  5306
        luxProp(mat, name+":Kr", "").setRGB((mat.mirR, mat.mirG, mat.mirB))
dougal2@223
  5307
        convertMirrorTexture(name+":Kr")
dougal2@223
  5308
        convertBumpTexture(name)
dougal2@223
  5309
    def makeGlass(name):
dougal2@223
  5310
        luxProp(mat, dot(name)+"type", "").set("glass")
dougal2@223
  5311
        luxProp(mat, name+":Kr", "").setRGB((0.0, 0.0, 0.0))
dougal2@223
  5312
        luxProp(mat, name+":Kt", "").setRGB((mat.R, mat.G, mat.B))
dougal2@223
  5313
        luxProp(mat, name+":index.iorusepreset", "").set("false")
dougal2@223
  5314
        luxProp(mat, name+":index", 0.0).set(mat.getIOR())
dougal2@223
  5315
        convertMirrorTexture(name+":Kr")
dougal2@223
  5316
        convertDiffuseTexture(name+":Kt")
dougal2@223
  5317
        convertBumpTexture(name)
dougal2@223
  5318
    def makeRoughglass(name, roughness):
dougal2@223
  5319
        luxProp(mat, dot(name)+"type", "").set("roughglass")
dougal2@223
  5320
        luxProp(mat, name+":Kr", "").setRGB((0.0, 0.0, 0.0))
dougal2@223
  5321
        luxProp(mat, name+":Kt", "").setRGB((mat.R, mat.G, mat.B))
dougal2@223
  5322
        luxProp(mat, name+":index.iorusepreset", "").set("false")
dougal2@223
  5323
        luxProp(mat, name+":index", 0.0).set(mat.getIOR())
dougal2@223
  5324
        luxProp(mat, name+":uroughness", 0.0).set(roughness)
dougal2@223
  5325
        luxProp(mat, name+":vroughness", 0.0).set(roughness)
dougal2@223
  5326
        convertMirrorTexture(name+":Kr")
dougal2@223
  5327
        convertDiffuseTexture(name+":Kt")
dougal2@223
  5328
        convertBumpTexture(name)
dougal2@223
  5329
    print "convert Blender material \"%s\" to lux material"%(mat.name)
dougal2@223
  5330
    mat.properties['luxblend'] = {}
dougal2@223
  5331
    if mat.emit > 0.0001:
dougal2@223
  5332
        luxProp(mat, "type", "").set("light")
dougal2@223
  5333
        luxProp(mat, "light.l", "").setRGB((mat.R, mat.G, mat.B))
dougal2@223
  5334
        luxProp(mat, "light.gain", 1.0).set(mat.emit)
dougal2@223
  5335
        return
dougal2@223
  5336
    alpha = mat.alpha
dougal2@223
  5337
    if not(mat.mode & Material.Modes.RAYTRANSP): alpha = 1.0
dougal2@223
  5338
    alpha0name, alpha1name = "", ""
dougal2@223
  5339
    if (alpha > 0.0) and (alpha < 1.0):
dougal2@223
  5340
        luxProp(mat, "type", "").set("mix")
dougal2@223
  5341
        luxProp(mat, ":amount", 0.0).set(alpha)
dougal2@223
  5342
        alpha0name, alpha1name = "mat2", "mat1"
dougal2@223
  5343
    if alpha > 0.0:
dougal2@223
  5344
        mirror = mat.rayMirr
dougal2@223
  5345
        if not(mat.mode & Material.Modes.RAYMIRROR): mirror = 0.0
dougal2@223
  5346
        mirror0name, mirror1name = alpha1name, alpha1name
dougal2@223
  5347
        if (mirror > 0.0) and (mirror < 1.0):
dougal2@223
  5348
            luxProp(mat, dot(alpha1name)+"type", "").set("mix")
dougal2@223
  5349
            luxProp(mat, alpha1name+":amount", 0.0).set(1.0 - mirror)
dougal2@223
  5350
            mirror0name, mirror1name = ddot(alpha1name)+"mat1", ddot(alpha1name)+"mat2"
dougal2@223
  5351
        if mirror > 0.0:
dougal2@223
  5352
            if mat.glossMir < 1.0: makeGlossy(mirror1name, 1.0-mat.glossMir**2)
dougal2@223
  5353
            else: makeMirror(mirror1name)
dougal2@223
  5354
        if mirror < 1.0:
dougal2@223
  5355
            if mat.spec > 0.0: makeGlossy(mirror0name, 1.0/mat.hard)
dougal2@223
  5356
            else: makeMatte(mirror0name)
dougal2@223
  5357
    if alpha < 1.0:
dougal2@223
  5358
        if mat.glossTra < 1.0: makeRoughnessGlass(alpha0name, 1.0-mat.glossTra**2)
dougal2@223
  5359
        else: makeGlass(alpha0name)
zuegs@116
  5360
zuegs@116
  5361
def convertAllMaterials():
dougal2@223
  5362
    for mat in Material.Get(): convertMaterial(mat)
zuegs@83
  5363
zuegs@83
  5364
zuegs@83
  5365
zuegs@181
  5366
dougal2@189
  5367
### Connect LRMDB ###
dougal2@189
  5368
ConnectLrmdb = False
zuegs@178
  5369
try:
dougal2@223
  5370
    import socket  # try import of socket library
dougal2@223
  5371
    ConnectLrmdb = True
dougal2@223
  5372
    def downloadLRMDB(mat, id):
dougal2@223
  5373
        if id.isalnum():
dougal2@231
  5374
            DrawProgressBar(0.0,'Getting Material #'+id)
dougal2@223
  5375
            try:
dougal2@223
  5376
                HOST = 'www.luxrender.net'
dougal2@223
  5377
                GET = '/lrmdb/en/material/download/'+id
dougal2@223
  5378
                PORT = 80
dougal2@223
  5379
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
dougal2@223
  5380
                sock.connect((HOST, PORT))
dougal2@223
  5381
                sock.send("GET %s HTTP/1.0\r\nHost: %s\r\n\r\n" % (GET, HOST))
dougal2@223
  5382
                data = sock.recv(1024)
dougal2@223
  5383
                str = ""
dougal2@223
  5384
                while len(data):
dougal2@223
  5385
                    str += data
dougal2@223
  5386
                    data = sock.recv(1024)
dougal2@223
  5387
                sock.close()
dougal2@223
  5388
                if str.split("\n", 1)[0].find("200") < 0:
dougal2@223
  5389
                    print "ERROR: server error: %s"%(str.split("\n",1)[0])
dougal2@223
  5390
                    return None
dougal2@223
  5391
                str = (str.split("\r\n\r\n")[1]).strip()
dougal2@223
  5392
                if (str[0]=="{") and (str[-1]=="}"):
dougal2@223
  5393
                    return str2MatTex(str)
dougal2@223
  5394
                print "ERROR: downloaded data is not a material or texture"
dougal2@223
  5395
            except:
dougal2@223
  5396
                print "ERROR: download failed"
dougal2@231
  5397
                
dougal2@231
  5398
            DrawProgressBar(1.0,'')
dougal2@223
  5399
        else:
dougal2@223
  5400
            print "ERROR: material id is not valid"
dougal2@223
  5401
        return None
dougal2@223
  5402
    
dougal2@223
  5403
        
dougal2@223
  5404
    #===========================================================================
dougal2@223
  5405
    # COOKIETRANSPORT
dougal2@223
  5406
    #===========================================================================
dougal2@223
  5407
    
dougal2@223
  5408
    #--------------------------------------------------------------------------- 
dougal2@223
  5409
    # IMPORTS
dougal2@223
  5410
    import cookielib, urllib2, xmlrpclib
dougal2@223
  5411
    
dougal2@223
  5412
    #---------------------------------------------------------------------------
dougal2@223
  5413
    # pilfered from
dougal2@223
  5414
    # https://fedorahosted.org/python-bugzilla/browser/bugzilla.py?rev=e6f699f06e92b1e49b1b8d2c8fbe89d9425a4a9a
dougal2@223
  5415
    class CookieTransport(xmlrpclib.Transport):
dougal2@223
  5416
        '''
dougal2@223
  5417
        A subclass of xmlrpclib.Transport that supports cookies.
dougal2@223
  5418
        '''
dougal2@223
  5419
        
dougal2@223
  5420
        cookiejar = None
dougal2@223
  5421
        scheme = 'http'
dougal2@223
  5422
        verbose = None
dougal2@223
  5423
    
dougal2@223
  5424
        # Cribbed from xmlrpclib.Transport.send_user_agent 
dougal2@223
  5425
        def send_cookies(self, connection, cookie_request):
dougal2@223
  5426
            '''
dougal2@223
  5427
            Send all the cookie data that we have received
dougal2@223
  5428
            '''
dougal2@223
  5429
            
dougal2@223
  5430
            if self.cookiejar is None:
dougal2@223
  5431
                self.cookiejar = cookielib.CookieJar()
dougal2@223
  5432
            elif self.cookiejar:
dougal2@223
  5433
                # Let the cookiejar figure out what cookies are appropriate
dougal2@223
  5434
                self.cookiejar.add_cookie_header(cookie_request)
dougal2@223
  5435
                # Pull the cookie headers out of the request object...
dougal2@223
  5436
                cookielist = list()
dougal2@223
  5437
                for header, value in cookie_request.header_items():
dougal2@223
  5438
                    if header.startswith('Cookie'):
dougal2@223
  5439
                        cookielist.append([header, value])
dougal2@223
  5440
                # ...and put them over the connection
dougal2@223
  5441
                for header, value in cookielist:
dougal2@223
  5442
                    connection.putheader(header, value)
dougal2@223
  5443
    
dougal2@223
  5444
        # This is the same request() method from xmlrpclib.Transport,
dougal2@223
  5445
        # with a couple additions noted below
dougal2@223
  5446
        def request(self, host, handler, request_body, verbose=0):
dougal2@223
  5447
            '''
dougal2@223
  5448
            Handle the request
dougal2@223
  5449
            '''
dougal2@223
  5450
            
dougal2@223
  5451
            host_connection = self.make_connection(host)
dougal2@223
  5452
            if verbose:
dougal2@223
  5453
                host_connection.set_debuglevel(1)
dougal2@223
  5454
    
dougal2@223
  5455
            # ADDED: construct the URL and Request object for proper cookie handling
dougal2@223
  5456
            request_url = "%s://%s/" % (self.scheme, host)
dougal2@223
  5457
            cookie_request  = urllib2.Request(request_url) 
dougal2@223
  5458
    
dougal2@223
  5459
            self.send_request(host_connection, handler, request_body)
dougal2@223
  5460
            self.send_host(host_connection, host) 
dougal2@223
  5461
            
dougal2@223
  5462
            # ADDED. creates cookiejar if None.
dougal2@223
  5463
            self.send_cookies(host_connection, cookie_request)
dougal2@223
  5464
            self.send_user_agent(host_connection)
dougal2@223
  5465
            self.send_content(host_connection, request_body)
dougal2@223
  5466
    
dougal2@223
  5467
            errcode, errmsg, headers = host_connection.getreply()
dougal2@223
  5468
    
dougal2@223
  5469
            # ADDED: parse headers and get cookies here
dougal2@223
  5470
            class CookieResponse:
dougal2@223
  5471
                '''
dougal2@223
  5472
                fake a response object that we can fill with the headers above
dougal2@223
  5473
                '''
dougal2@223
  5474
                
dougal2@223
  5475
                def __init__(self, headers):
dougal2@223
  5476
                    self.headers = headers
dougal2@223
  5477
                    
dougal2@223
  5478
                def info(self):
dougal2@223
  5479
                    return self.headers
dougal2@223
  5480
                
dougal2@223
  5481
            cookie_response = CookieResponse(headers)
dougal2@223
  5482
            
dougal2@223
  5483
            # Okay, extract the cookies from the headers
dougal2@223
  5484
            self.cookiejar.extract_cookies(cookie_response, cookie_request)
dougal2@223
  5485
            
dougal2@223
  5486
            # And write back any changes
dougal2@223
  5487
            # DH THIS DOESN'T WORK
dougal2@223
  5488
            # self.cookiejar.save(self.cookiejar.filename)
dougal2@223
  5489
    
dougal2@223
  5490
            if errcode != 200:
dougal2@223
  5491
                raise xmlrpclib.ProtocolError(
dougal2@223
  5492
                    host + handler,
dougal2@223
  5493
                    errcode, errmsg,
dougal2@223
  5494
                    headers
dougal2@223
  5495
                )
dougal2@223
  5496
    
dougal2@223
  5497
            self.verbose = verbose
dougal2@223
  5498
    
dougal2@223
  5499
            try:
dougal2@223
  5500
                sock = host_connection._conn.sock
dougal2@223
  5501
            except AttributeError:
dougal2@223
  5502
                sock = None
dougal2@223
  5503
    
dougal2@223
  5504
            return self._parse_response(host_connection.getfile(), sock)
dougal2@223
  5505
    
dougal2@223
  5506
dougal2@223
  5507
    #===========================================================================
dougal2@223
  5508
    # LRMDB Integration
dougal2@223
  5509
    #===========================================================================
dougal2@223
  5510
    class lrmdb:
dougal2@223
  5511
        host              = 'http://www.luxrender.net/lrmdb/ixr'
dougal2@223
  5512
        
dougal2@223
  5513
        username          = ""
dougal2@223
  5514
        password          = ""
dougal2@223
  5515
        logged_in         = False
dougal2@223
  5516
        
dougal2@223
  5517
        SERVER            = None
dougal2@223
  5518
        
dougal2@223
  5519
        last_error_str    = None
dougal2@223
  5520
        
dougal2@223
  5521
        def last_error(self):
dougal2@223
  5522
            return self.last_error_str #'LRMDB Connector: %s' %
dougal2@223
  5523
        
dougal2@223
  5524
        def login(self):
dougal2@223
  5525
            try:
dougal2@223
  5526
                result = self.SERVER.user.login(
dougal2@223
  5527
                    self.username,
dougal2@223
  5528
                    self.password
dougal2@223
  5529
                )
dougal2@223
  5530
                if not result:
dougal2@223
  5531
                    raise
dougal2@223
  5532
                else:
dougal2@223
  5533
                    self.logged_in = True
dougal2@223
  5534
                    return True
dougal2@223
  5535
            except:
dougal2@223
  5536
                self.last_error_str = 'Login Failed'
dougal2@223
  5537
                self.logged_in = False
dougal2@223
  5538
                return False
dougal2@223
  5539
            
dougal2@223
  5540
        def submit_object(self, mat, basekey, tex):
dougal2@223
  5541
            if not self.check_creds(): return False
dougal2@223
  5542
            
dougal2@223
  5543
            try:
dougal2@223
  5544
                result = 'Unknown Error'
dougal2@223
  5545
                
dougal2@223
  5546
                if tex:
dougal2@223
  5547
                    name = Draw.PupStrInput('Name: ', '', 32)
dougal2@223
  5548
                else:
dougal2@223
  5549
                    name = mat.name
dougal2@223
  5550
                
dougal2@223
  5551
                result = self.SERVER.object.submit(
dougal2@223
  5552
                    name,
dougal2@223
  5553
                    MatTex2dict( getMatTex(mat, basekey, tex), tex )
dougal2@223
  5554
                )
dougal2@223
  5555
                if result is not True:
dougal2@223
  5556
                    raise
dougal2@223
  5557
                else:
dougal2@223
  5558
                    return True
dougal2@223
  5559
            except:
dougal2@223
  5560
                self.last_error_str = 'Submit failed: %s' % result
dougal2@223
  5561
                return False
dougal2@223
  5562
        
dougal2@223
  5563
        def check_creds(self):
dougal2@223
  5564
            if self.SERVER is None:
dougal2@223
  5565
                try:
dougal2@223
  5566
                    self.SERVER = xmlrpclib.ServerProxy(self.host, transport=CookieTransport())
dougal2@223
  5567
                except:
dougal2@223
  5568
                    self.last_error_str = 'ServerProxy init failed'
dougal2@223
  5569
                    return False
dougal2@223
  5570
            
dougal2@223
  5571
            
dougal2@223
  5572
            if not self.logged_in:
dougal2@223
  5573
                #if self.username is "":
dougal2@223
  5574
                self.request_username()
dougal2@223
  5575
                
dougal2@223
  5576
                #if self.password is "":
dougal2@223
  5577
                self.request_password()
dougal2@223
  5578
                    
dougal2@223
  5579
                return self.login()
dougal2@223
  5580
            else:
dougal2@223
  5581
                return True
dougal2@223
  5582
                
dougal2@223
  5583
        def request_username(self):
dougal2@223
  5584
            self.username = Draw.PupStrInput("Username:", self.username, 32)
dougal2@223
  5585
            
dougal2@223
  5586
        def request_password(self):
dougal2@223
  5587
            self.password = Draw.PupStrInput("Password:", self.password, 32)
dougal2@223
  5588
dougal2@223
  5589
    lrmdb_connector = lrmdb()
dougal2@223
  5590
        
dougal2@223
  5591
    
dougal2@189
  5592
except: print "WARNING: LRMDB support not available"
zuegs@178
  5593
zuegs@178
  5594
zuegs@83
  5595
zuegs@167
  5596
### MatTex functions ###
zuegs@167
  5597
### MatTex : is a dictionary of material or texture properties
zuegs@167
  5598
zuegs@198
  5599
def getMatTex(mat, basekey='', tex=False):
dougal2@223
  5600
    global usedproperties, usedpropertiesfilterobj
dougal2@223
  5601
    usedproperties = {}
dougal2@223
  5602
    usedpropertiesfilterobj = mat
dougal2@223
  5603
    luxMaterial(mat)
dougal2@223
  5604
    dict = {}
dougal2@223
  5605
    for k,v in usedproperties.items():
dougal2@223
  5606
        if k[:len(basekey)]==basekey:
dougal2@223
  5607
            if k[-9:] != '.textured':
dougal2@223
  5608
                name = k[len(basekey):]
dougal2@223
  5609
                if name == ".type": name = "type"
dougal2@223
  5610
                dict[name] = v
dougal2@223
  5611
    dict["__type__"] = ["material","texture"][bool(tex)]
dougal2@223
  5612
    return dict
zuegs@167
  5613
zuegs@198
  5614
def putMatTex(mat, dict, basekey='', tex=None):
dougal2@223
  5615
    if dict and (tex!=None) and (tex ^ (dict.has_key("__type__") and (dict["__type__"]=="texture"))):
dougal2@223
  5616
        print "ERROR: Can't apply %s as %s"%(["texture","material"][bool(tex)],["material","texture"][bool(tex)])
dougal2@223
  5617
        return
dougal2@223
  5618
    if dict:
dougal2@223
  5619
        # remove all current properties in mat that starts with basekey
dougal2@223
  5620
        try:
dougal2@223
  5621
            d = mat.properties['luxblend']
dougal2@223
  5622
            for k,v in d.convert_to_pyobject().items():
dougal2@223
  5623
                kn = k
zuegs@244
  5624
                if k[:7]=="__hash:":    # decode if entry is hashed (cause of 32chars limit)
dougal2@223
  5625
                    l = v.split(" = ")
dougal2@223
  5626
                    kn = l[0]
dougal2@223
  5627
                if kn[:len(basekey)]==basekey:
dougal2@223
  5628
                    del mat.properties['luxblend'][k]
zuegs@244
  5629
        except: print "error" # pass
dougal2@223
  5630
        # assign loaded properties
dougal2@223
  5631
        for k,v in dict.items():
dougal2@223
  5632
            try:
dougal2@223
  5633
                if (basekey!="") and (k=="type"): k = ".type"
zuegs@244
  5634
                # zuegs: following two lines should fix issue http://www.luxrender.net/forum/viewtopic.php?f=16&t=1618&p=14512#p14512
zuegs@244
  5635
                if (basekey!="") and ((k[0]!=".") and (k[0]!=":")): k = ":"+k
zuegs@244
  5636
                if (basekey=="") and (k[0:4]==":mat"): k = k[1:]
dougal2@223
  5637
                luxProp(mat, basekey+k, None).set(v)
dougal2@223
  5638
                if k[-8:] == '.texture':
dougal2@223
  5639
                    luxProp(mat, basekey+k[:-8]+'.textured', 'false').set('true')
dougal2@223
  5640
            except: pass
zuegs@167
  5641
dougal2@208
  5642
dougal2@208
  5643
LBX_VERSION = '0.7'
dougal2@208
  5644
dougal2@212
  5645
def MatTex2dict(d, tex = None):
dougal2@223
  5646
    global LBX_VERSION
dougal2@223
  5647
    
dougal2@223
  5648
    if LBX_VERSION == '0.6':
dougal2@223
  5649
    
dougal2@223
  5650
        if tex is not None and tex == True:
dougal2@223
  5651
            d['LUX_DATA'] = 'TEXTURE'
dougal2@223
  5652
        else:
dougal2@223
  5653
            d['LUX_DATA'] = 'MATERIAL'
dougal2@223
  5654
        
dougal2@223
  5655
        d['LUX_VERSION'] = '0.6'
dougal2@223
  5656
        
dougal2@223
  5657
        return d
dougal2@223
  5658
    
dougal2@223
  5659
    elif LBX_VERSION == '0.7':
dougal2@223
  5660
        definition = []
dougal2@223
  5661
        for k in d.keys():
dougal2@223
  5662
            if type(d[k]) == types.IntType:
dougal2@223
  5663
                t = 'integer'
dougal2@223
  5664
            if type(d[k]) == types.FloatType:
dougal2@223
  5665
                t = 'float'
dougal2@223
  5666
            if type(d[k]) == types.BooleanType:
dougal2@223
  5667
                t = 'bool'
dougal2@223
  5668
            if type(d[k]) == types.StringType:
dougal2@223
  5669
                l=None
dougal2@223
  5670
                try:
dougal2@223
  5671
                    l = d[k].split(" ")
dougal2@223
  5672
                except: pass
dougal2@223
  5673
                if l==None or len(l)!=3:
dougal2@223
  5674
                    t = 'string'
dougal2@223
  5675
                else:
dougal2@223
  5676
                    t = 'vector'
dougal2@223
  5677
                
dougal2@223
  5678
            definition.append([ t, k, d[k] ])
dougal2@223
  5679
        
dougal2@223
  5680
        
dougal2@223
  5681
        lbx = {
dougal2@223
  5682
            'type': d['__type__'],
dougal2@223
  5683
            'version': '0.7',
dougal2@223
  5684
            'definition': definition,
dougal2@223
  5685
            'metadata': [
dougal2@223
  5686
                ['string', 'generator', 'luxblend'],
dougal2@223
  5687
            ]
dougal2@223
  5688
        }
dougal2@223
  5689
        
dougal2@223
  5690
        return lbx
dougal2@216
  5691
dougal2@216
  5692
def format_dictStr(dictStr):
dougal2@216
  5693
    result = ''
dougal2@216
  5694
    pos = 0
dougal2@216
  5695
    indentStr = '  '
dougal2@230
  5696
    newLine = '\n'
dougal2@216
  5697
    
dougal2@216
  5698
    for char in dictStr:
dougal2@216
  5699
        if char in ['}', ']']:
dougal2@216
  5700
            result += newLine
dougal2@216
  5701
            pos -= 1
dougal2@216
  5702
            for j in range(0,pos):
dougal2@216
  5703
                result += indentStr
dougal2@216
  5704
                
dougal2@216
  5705
        result += char
dougal2@216
  5706
        
dougal2@216
  5707
        if char in [',', '{', '[']:
dougal2@216
  5708
            result += newLine
dougal2@216
  5709
            if char in ['{', '[']:
dougal2@216
  5710
                pos += 1
dougal2@216
  5711
            for j in range(0,pos):
dougal2@216
  5712
                result += indentStr
dougal2@216
  5713
            
dougal2@216
  5714
    return result
dougal2@216
  5715
dougal2@216
  5716
dougal2@212
  5717
def MatTex2str(d, tex = None):
dougal2@223
  5718
    global LBX_VERSION
dougal2@223
  5719
    
dougal2@223
  5720
    if LBX_VERSION == '0.6':
dougal2@223
  5721
        return format_dictStr(str( MatTex2dict(d, tex) )) #.replace(", \'", ",\n\'")
dougal2@223
  5722
    
dougal2@223
  5723
    elif LBX_VERSION == '0.7':
dougal2@223
  5724
        return format_dictStr(str( MatTex2dict(d, tex) )) #.replace("], \'", "],\r\n\'").replace("[","\r\n\t[")
dougal2@216
  5725
        
zuegs@167
  5726
dougal2@223
  5727
def str2MatTex(s, tex = None):    # todo: this is not absolutely save from attacks!!!
dougal2@223
  5728
    global LBX_VERSION
dougal2@223
  5729
    
dougal2@223
  5730
    s = s.strip()
dougal2@223
  5731
    if (s[0]=='{') and (s[-1]=='}'):
dougal2@223
  5732
        d = eval(s, dict(__builtins__=None,True=True,False=False))
dougal2@223
  5733
        if type(d)==types.DictType:
dougal2@223
  5734
            
dougal2@223
  5735
            
dougal2@223
  5736
            if LBX_VERSION == '0.6':
dougal2@223
  5737
            
dougal2@223
  5738
                if tex is not None and tex == True:
dougal2@223
  5739
                    test_str = 'TEXTURE'
dougal2@223
  5740
                else:
dougal2@223
  5741
                    test_str = 'MATERIAL'
dougal2@223
  5742
                    
dougal2@223
  5743
                if   ('LUX_DATA' in d.keys() and d['LUX_DATA'] == test_str) \
dougal2@223
  5744
                and  ('LUX_VERSION' in d.keys() and (d['LUX_VERSION'] == '0.6' or d['LUX_VERSION'] == 0.6)):
dougal2@223
  5745
                    return d
dougal2@223
  5746
                else:
dougal2@223
  5747
                    reason = 'Missing/incorrect metadata'
dougal2@223
  5748
                    
dougal2@223
  5749
            elif LBX_VERSION == '0.7':
dougal2@223
  5750
                
dougal2@223
  5751
                def lb_list_to_dict(list):
dougal2@223
  5752
                    d = {}
dougal2@223
  5753
                    for t, k, v in list:
dougal2@223
  5754
                        if t == 'float':
dougal2@223
  5755
                            v = float(v)
dougal2@223
  5756
                            
dougal2@223
  5757
                        d[k] = v
dougal2@223
  5758
                    return d
dougal2@223
  5759
                
dougal2@223
  5760
                if   ('version' in d.keys() and d['version'] in ['0.6', '0.7']) \
dougal2@223
  5761
                and  ('type' in d.keys() and d['type'] in ['material', 'texture']) \
dougal2@223
  5762
                and  ('definition' in d.keys()):
dougal2@223
  5763
                    
dougal2@223
  5764
                    
dougal2@223
  5765
                    try:
dougal2@223
  5766
                        definition = lb_list_to_dict(d['definition'])
dougal2@223
  5767
                        
dougal2@223
  5768
                        if 'metadata' in d.keys():
dougal2@223
  5769
                            definition.update( lb_list_to_dict(d['metadata']) )
dougal2@223
  5770
                        
dougal2@223
  5771
                        return definition
dougal2@223
  5772
                    except:
dougal2@223
  5773
                        reason = 'Incorrect LBX definition data'
dougal2@223
  5774
                else: 
dougal2@223
  5775
                    reason = 'Missing/incorrect metadata'
dougal2@223
  5776
            else:
dougal2@223
  5777
                reason = 'Unknown LBX version'
dougal2@223
  5778
        else:
dougal2@223
  5779
            reason = 'Not a parsed dict'
dougal2@223
  5780
    else:
dougal2@223
  5781
        reason = 'Not a stored dict'
dougal2@223
  5782
            
dougal2@223
  5783
            
dougal2@223
  5784
    print "ERROR: string to material/texture conversion failed: %s" % reason
dougal2@223
  5785
    return None
zuegs@167
  5786
zuegs@167
  5787
zuegs@167
  5788
luxclipboard = None # global variable for copy/paste content
zuegs@167
  5789
def showMatTexMenu(mat, basekey='', tex=False):
dougal2@223
  5790
    global luxclipboard, ConnectLrmdb
dougal2@223
  5791
    if tex: menu="Texture menu:%t"
dougal2@223
  5792
    else: menu="Material menu:%t"
dougal2@223
  5793
    menu += "|Copy%x1"
dougal2@223
  5794
    try:
dougal2@223
  5795
        if luxclipboard and (not(tex) ^ (luxclipboard["__type__"]=="texture")): menu +="|Paste%x2"
dougal2@223
  5796
    except: pass
dougal2@223
  5797
    if (tex):
dougal2@223
  5798
        menu += "|Load LBT%x3|Save LBT%x4"
dougal2@223
  5799
    else:
dougal2@223
  5800
        menu += "|Load LBM%x3|Save LBM%x4"
dougal2@223
  5801
    if  ConnectLrmdb:
dougal2@223
  5802
        menu += "|Download from DB%x5" #not(tex) and
dougal2@223
  5803
        menu += "|Upload to DB%x6"
dougal2@223
  5804
dougal2@223
  5805
#    menu += "|%l|dump material%x99|dump clipboard%x98"
dougal2@223
  5806
    r = Draw.PupMenu(menu)
dougal2@223
  5807
    if r==1:
dougal2@223
  5808
        luxclipboard = getMatTex(mat, basekey, tex)
dougal2@223
  5809
    elif r==2: putMatTex(mat, luxclipboard, basekey, tex)
dougal2@223
  5810
    elif r==3: 
dougal2@223
  5811
        scn = Scene.GetCurrent()
dougal2@223
  5812
        if (tex):
dougal2@223
  5813
            Window.FileSelector(lambda fn:loadMatTex(mat, fn, basekey, tex), "load texture", luxProp(scn, "lux", "").get()+os.sep+".lbt")
dougal2@223
  5814
        else:
dougal2@223
  5815
            Window.FileSelector(lambda fn:loadMatTex(mat, fn, basekey, tex), "load material", luxProp(scn, "lux", "").get()+os.sep+".lbm")
dougal2@223
  5816
    elif r==4:
dougal2@223
  5817
        scn = Scene.GetCurrent()
dougal2@223
  5818
        if (tex):
dougal2@223
  5819
            Window.FileSelector(lambda fn:saveMatTex(mat, fn, basekey, tex), "save texture", luxProp(scn, "lux", "").get()+os.sep+".lbt")
dougal2@223
  5820
        else:
dougal2@223
  5821
            Window.FileSelector(lambda fn:saveMatTex(mat, fn, basekey, tex), "save material", luxProp(scn, "lux", "").get()+os.sep+".lbm")
dougal2@223
  5822
    elif r==5:
dougal2@223
  5823
        if not tex:
dougal2@223
  5824
            id = Draw.PupStrInput("Material ID:", "", 32)
dougal2@223
  5825
        else:
dougal2@223
  5826
            id = Draw.PupStrInput("Texture ID:", "", 32)
dougal2@223
  5827
        if id: putMatTex(mat, downloadLRMDB(mat, id), basekey, tex)
dougal2@223
  5828
    elif r==6:
dougal2@223
  5829
        global lrmdb_connector
dougal2@223
  5830
        if not lrmdb_connector.submit_object(mat, basekey, tex):
dougal2@223
  5831
            msg = lrmdb_connector.last_error()
dougal2@223
  5832
        else:
dougal2@223
  5833
            msg = 'OK'
dougal2@223
  5834
            
dougal2@223
  5835
        Draw.PupMenu("Upload: "+msg+".%t|OK")
dougal2@223
  5836
#    elif r==99:
dougal2@223
  5837
#        for k,v in mat.properties['luxblend'].convert_to_pyobject().items(): print k+"="+repr(v)
dougal2@223
  5838
#    elif r==98:
dougal2@223
  5839
#        for k,v in luxclipboard.items(): print k+"="+repr(v)
dougal2@223
  5840
#    print ""
dougal2@223
  5841
    Draw.Redraw()
zuegs@167
  5842
zuegs@167
  5843
zuegs@198
  5844
def saveMatTex(mat, fn, basekey='', tex=False):
dougal2@223
  5845
    global LuxIsGUI
dougal2@223
  5846
    d = getMatTex(mat, basekey, tex)
dougal2@223
  5847
    file = open(fn, 'w')
dougal2@223
  5848
    file.write(MatTex2str(d, tex))
dougal2@223
  5849
    file.close()
dougal2@223
  5850
    if LuxIsGUI: Draw.Redraw()
zuegs@167
  5851
zuegs@167
  5852
zuegs@198
  5853
def loadMatTex(mat, fn, basekey='', tex=None):
dougal2@223
  5854
    global LuxIsGUI
dougal2@223
  5855
    file = open(fn, 'r')
dougal2@223
  5856
    data = file.read()
dougal2@223
  5857
    file.close()
dougal2@223
  5858
    data = str2MatTex(data, tex)
dougal2@223
  5859
    putMatTex(mat, data, basekey, tex) 
dougal2@223
  5860
    if LuxIsGUI: Draw.Redraw()
zuegs@167
  5861
zuegs@83
  5862
zuegs@21
  5863
activemat = None
zuegs@21
  5864
def setactivemat(mat):
dougal2@223
  5865
    global activemat
dougal2@223
  5866
    activemat = mat
zuegs@21
  5867
zuegs@38
  5868
zuegs@38
  5869
# scrollbar
zuegs@38
  5870
class scrollbar:
dougal2@223
  5871
    def __init__(self):
dougal2@223
  5872
        self.position = 0 # current position at top (inside 0..height-viewHeight)
dougal2@223
  5873
        self.height = 0 # total height of the content
dougal2@223
  5874
        self.viewHeight = 0 # height of window
dougal2@223
  5875
        self.x = 0 # horizontal position of the scrollbar
dougal2@223
  5876
        self.scrolling = self.over = False # start without scrolling ;)
dougal2@223
  5877
    def calcRects(self):
dougal2@223
  5878
        # Blender doesn't give us direct access to the window size yet, but it does set the
dougal2@223
  5879
        # GL scissor box for it, so we can get the size from that. (thx to Daniel Dunbar)
dougal2@223
  5880
        size = BGL.Buffer(BGL.GL_FLOAT, 4)
dougal2@223
  5881
        BGL.glGetFloatv(BGL.GL_SCISSOR_BOX, size)
dougal2@223
  5882
        size = size.list # [winx, winy, width, height]
dougal2@223
  5883
        self.winrect = size[:]
dougal2@223
  5884
        self.viewHeight = size[3]
dougal2@223
  5885
        size[0], size[1] = size[2]-20, 0 # [scrollx1, scrolly1, scrollx2, scrolly2]
dougal2@223
  5886
        self.rect = size[:]
dougal2@223
  5887
        if self.position < 0: self.position = 0
dougal2@223
  5888
        if self.height < self.viewHeight: self.height = self.viewHeight
dougal2@223
  5889
        if self.position > self.height-self.viewHeight: self.position = self.height-self.viewHeight
dougal2@223
  5890
        self.factor = (size[3]-size[1]-4)/self.height
dougal2@223
  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]
dougal2@223
  5892
    def draw(self):
dougal2@223
  5893
        self.calcRects()
dougal2@223
  5894
        BGL.glColor3f(0.5,0.5,0.5); BGL.glRectf(self.rect[0],self.rect[1],self.rect[2],self.rect[3])
dougal2@223
  5895
        if self.over or self.scrolling: BGL.glColor3f(1.0,1.0,0.7)
dougal2@223
  5896
        else: BGL.glColor3f(0.7,0.7,0.7)
dougal2@223
  5897
        BGL.glRectf(self.sliderRect[0],self.sliderRect[1],self.sliderRect[2],self.sliderRect[3])
dougal2@223
  5898
    def getTop(self):
dougal2@223
  5899
        return self.viewHeight+self.position
dougal2@223
  5900
    def scroll(self, delta):
dougal2@223
  5901
        self.position = self.position + delta
dougal2@223
  5902
        self.calcRects()
dougal2@223
  5903
        Draw.Redraw()
dougal2@223
  5904
    def Mouse(self):
dougal2@223
  5905
        self.calcRects()
dougal2@223
  5906
        coord, buttons = Window.GetMouseCoords(), Window.GetMouseButtons()
dougal2@223
  5907
        over = (coord[0]>=self.winrect[0]+self.rect[0]) and (coord[0]<=self.winrect[0]+self.rect[2]) and \
dougal2@223
  5908
               (coord[1]>=self.winrect[1]+self.rect[1]) and (coord[1]<=self.winrect[1]+self.rect[3])
dougal2@223
  5909
        if Window.MButs.L and buttons > 0:
dougal2@223
  5910
            if self.scrolling:
dougal2@223
  5911
                if self.factor > 0: self.scroll((self.lastcoord[1]-coord[1])/self.factor)
dougal2@223
  5912
                Draw.Redraw()
dougal2@223
  5913
            elif self.over:
dougal2@223
  5914
                self.scrolling = True
dougal2@223
  5915
            self.lastcoord = coord
dougal2@223
  5916
        elif self.scrolling:
dougal2@223
  5917
            self.scrolling = False
dougal2@223
  5918
            Draw.Redraw()
dougal2@223
  5919
        if self.over != over: Draw.Redraw()
dougal2@223
  5920
        self.over = over
zuegs@38
  5921
zuegs@38
  5922
scrollbar = scrollbar()
zuegs@38
  5923
zuegs@38
  5924
zuegs@21
  5925
# gui main draw
zuegs@21
  5926
def luxDraw():
dougal2@223
  5927
    global icon_luxblend
dougal2@223
  5928
dougal2@223
  5929
    BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
dougal2@223
  5930
dougal2@223
  5931
    y = int(scrollbar.getTop()) # 420
dougal2@223
  5932
    BGL.glColor3f(0.1,0.1,0.1); BGL.glRectf(0,0,440,y)
jensverwiebe@338
  5933
    BGL.glColor3f(1.0,0.5,0.0); BGL.glRasterPos2i(130,y-21); Draw.Text("v0.6RC5")
dougal2@223
  5934
    BGL.glColor3f(0.9,0.9,0.9);
dougal2@223
  5935
dougal2@223
  5936
    drawLogo(icon_luxblend, 6, y-25);
dougal2@223
  5937
dougal2@223
  5938
    scn = Scene.GetCurrent()
dougal2@223
  5939
    if scn:
dougal2@223
  5940
        luxpage = luxProp(scn, "page", 0)
dougal2@223
  5941
        gui = luxGui(y-70)
dougal2@223
  5942
dougal2@223
  5943
        # render presets
dougal2@223
  5944
        BGL.glRasterPos2i(10,y-45); Draw.Text("Render presets:")
dougal2@223
  5945
        luxpreset = luxProp(scn, "preset", "1C - Final - medium MLT/Path Tracing (indoor) (recommended)")
dougal2@223
  5946
        presets = getScenePresets()
dougal2@223
  5947
        presetskeys = presets.keys()
dougal2@223
  5948
        presetskeys.sort()
dougal2@223
  5949
        presetskeys.insert(0, "")
dougal2@223
  5950
        presetsstr = "presets: %t"
dougal2@223
  5951
        for i, v in enumerate(presetskeys): presetsstr = "%s %%x%d|%s"%(v, i, presetsstr)
dougal2@223
  5952
        try: i = presetskeys.index(luxpreset.get())
dougal2@223
  5953
        except ValueError: i = 0
dougal2@223
  5954
        Draw.Menu(presetsstr, evtLuxGui, 110, y-50, 220, 18, i, "", lambda e,v: luxpreset.set(presetskeys[v]))
dougal2@223
  5955
        Draw.Button("save", evtSavePreset, 330, y-50, 40, 18, "create a render-settings preset")
dougal2@223
  5956
        Draw.Button("del", evtDeletePreset, 370, y-50, 40, 18, "delete a render-settings preset")
dougal2@223
  5957
dougal2@223
  5958
        # if preset is selected load values
dougal2@223
  5959
        if luxpreset.get() != "":
dougal2@223
  5960
            try:
dougal2@223
  5961
                d = presets[luxpreset.get()]
dougal2@223
  5962
                for k,v in d.items(): scn.properties['luxblend'][k] = v
dougal2@223
  5963
            except: pass
dougal2@223
  5964
dougal2@223
  5965
        Draw.Button("Material", evtLuxGui, 10, y-70, 80, 16, "", lambda e,v:luxpage.set(0))
dougal2@223
  5966
        Draw.Button("Cam/Env", evtLuxGui, 90, y-70, 80, 16, "", lambda e,v:luxpage.set(1))
dougal2@223
  5967
        Draw.Button("Render", evtLuxGui, 170, y-70, 80, 16, "", lambda e,v:luxpage.set(2))
dougal2@223
  5968
        Draw.Button("Output", evtLuxGui, 250, y-70, 80, 16, "", lambda e,v:luxpage.set(3))
dougal2@223
  5969
        Draw.Button("System", evtLuxGui, 330, y-70, 80, 16, "", lambda e,v:luxpage.set(4))
dougal2@223
  5970
        if luxpage.get() == 0:
dougal2@223
  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)
dougal2@223
  5972
            obj = scn.objects.active
dougal2@223
  5973
            if obj:
dougal2@223
  5974
                if (obj.getType() == "Lamp"):
dougal2@223
  5975
                    ltype = obj.getData(mesh=1).getType() # data
dougal2@223
  5976
                    if (ltype == Lamp.Types["Area"]): luxLight("Area LIGHT", "", obj, gui, 0)
dougal2@223
  5977
                    elif (ltype == Lamp.Types["Spot"]): luxSpot("Spot LIGHT", "", obj, gui, 0)
dougal2@223
  5978
                    elif (ltype == Lamp.Types["Lamp"]): luxLamp("Point LIGHT", "", obj, gui, 0)
dougal2@223
  5979
                else:
dougal2@223
  5980
                    matfilter = luxProp(scn, "matlistfilter", "false")
dougal2@223
  5981
                    mats = getMaterials(obj, True)
dougal2@223
  5982
                    if (activemat == None) and (len(mats) > 0):
dougal2@223
  5983
                        setactivemat(mats[0])
dougal2@223
  5984
                    if matfilter.get() == "false":
dougal2@223
  5985
                        mats = Material.Get()
dougal2@223
  5986
                    matindex = 0
dougal2@223
  5987
                    for i, v in enumerate(mats):
dougal2@223
  5988
                        if v==activemat: matindex = i
dougal2@223
  5989
                    matnames = [m.getName() for m in mats]
dougal2@223
  5990
                    menustr = "Material: %t"
dougal2@223
  5991
                    for i, v in enumerate(matnames): menustr = "%s %%x%d|%s"%(v, i, menustr)
dougal2@223
  5992
                    gui.newline("MATERIAL:", 8) 
dougal2@223
  5993
                    r = gui.getRect(1.1, 1)
dougal2@223
  5994
                    Draw.Button("C", evtConvertMaterial, r[0]-gui.h, gui.y-gui.h, gui.h, gui.h, "convert blender material to lux material")
dougal2@223
  5995
                    Draw.Menu(menustr, evtLuxGui, r[0], r[1], r[2], r[3], matindex, "", lambda e,v: setactivemat(mats[v]))
dougal2@223
  5996
                    luxBool("", matfilter, "filter", "only show active object materials", gui, 0.5)
dougal2@223
  5997
dougal2@223
  5998
                    Draw.Button("L", evtLoadMaterial, gui.x, gui.y-gui.h, gui.h, gui.h, "load a material preset")
dougal2@223
  5999
                    Draw.Button("S", evtSaveMaterial, gui.x+gui.h, gui.y-gui.h, gui.h, gui.h, "save a material preset")
dougal2@223
  6000
                    Draw.Button("D", evtDeleteMaterial, gui.x+gui.h*2, gui.y-gui.h, gui.h, gui.h, "delete a material preset")
dougal2@223
  6001
                    if len(mats) > 0:
dougal2@223
  6002
                        setactivemat(mats[matindex])
dougal2@223
  6003
                        luxMaterial(activemat, gui)
dougal2@223
  6004
        if luxpage.get() == 1:
dougal2@223
  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)
dougal2@223
  6006
            cam = scn.getCurrentCamera()
dougal2@223
  6007
            if cam:
dougal2@223
  6008
                r = gui.getRect(1.1, 1)
dougal2@223
  6009
                luxCamera(cam.data, scn.getRenderingContext(), gui)
dougal2@223
  6010
            gui.newline("", 10)
dougal2@223
  6011
            luxEnvironment(scn, gui)
dougal2@223
  6012
        if luxpage.get() == 2:
dougal2@223
  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)
dougal2@223
  6014
            r = gui.getRect(1.1, 1)
dougal2@223
  6015
            luxSampler(scn, gui)
dougal2@223
  6016
            gui.newline("", 10)
dougal2@223
  6017
            luxSurfaceIntegrator(scn, gui)
dougal2@223
  6018
            gui.newline("", 10)
dougal2@223
  6019
            luxVolumeIntegrator(scn, gui)
dougal2@223
  6020
            gui.newline("", 10)
dougal2@223
  6021
            luxPixelFilter(scn, gui)
dougal2@223
  6022
        if luxpage.get() == 3:
dougal2@223
  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)
dougal2@223
  6024
            r = gui.getRect(1.1, 1)
dougal2@223
  6025
            luxFilm(scn, gui)
dougal2@223
  6026
        if luxpage.get() == 4:
dougal2@223
  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)
dougal2@223
  6028
            luxSystem(scn, gui)
dougal2@223
  6029
            gui.newline("", 10)
dougal2@223
  6030
            luxAccelerator(scn, gui)
dougal2@223
  6031
            gui.newline("MATERIALS:", 10)
dougal2@223
  6032
            r = gui.getRect(2,1)
dougal2@223
  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())
dougal2@223
  6034
            gui.newline("SETTINGS:", 10)
dougal2@223
  6035
            r = gui.getRect(2,1)
dougal2@223
  6036
            Draw.Button("save defaults", 0, r[0], r[1], r[2], r[3], "save current settings as defaults", lambda e,v:saveluxdefaults())
dougal2@223
  6037
        y = gui.y - 80
dougal2@223
  6038
        if y > 0: y = 0 # bottom align of render button
dougal2@223
  6039
        run = luxProp(scn, "run", "true")
dougal2@223
  6040
        dlt = luxProp(scn, "default", "true")
dougal2@223
  6041
        clay = luxProp(scn, "clay", "false")
doughammond@325
  6042
        nolg = luxProp(scn, "nolg", "false")
dougal2@223
  6043
        lxs = luxProp(scn, "lxs", "true")
dougal2@223
  6044
        lxo = luxProp(scn, "lxo", "true")
dougal2@223
  6045
        lxm = luxProp(scn, "lxm", "true")
dougal2@223
  6046
        lxv = luxProp(scn, "lxv", "true")
dougal2@223
  6047
        net = luxProp(scn, "netrenderctl", "false")
dougal2@223
  6048
        donet = luxProp(scn, "donetrender", "true")
dougal2@223
  6049
        if (run.get()=="true"):
dougal2@223
  6050
            Draw.Button("Render", 0, 10, y+20, 100, 36, "Render with Lux", lambda e,v:CBluxExport(dlt.get()=="true", True))
dougal2@223
  6051
            Draw.Button("Render Anim", 0, 110, y+20, 100, 36, "Render animation with Lux", lambda e,v:CBluxAnimExport(dlt.get()=="true", True))
dougal2@223
  6052
        else:
dougal2@223
  6053
            Draw.Button("Export", 0, 10, y+20, 100, 36, "Export", lambda e,v:CBluxExport(dlt.get()=="true", False))
dougal2@223
  6054
            Draw.Button("Export Anim", 0, 110, y+20, 100, 36, "Export animation", lambda e,v:CBluxAnimExport(dlt.get()=="true", False))
dougal2@223
  6055
doughammond@325
  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)]))
doughammond@325
  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)]))
doughammond@325
  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)]))
doughammond@325
  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)]))
dougal2@223
  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)]))
dougal2@223
  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)]))
dougal2@223
  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)]))
dougal2@223
  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)]))
dougal2@223
  6064
    BGL.glColor3f(0.9, 0.9, 0.9) ; BGL.glRasterPos2i(340,y+5) ; Draw.Text("Press Q or ESC to quit.", "tiny")
dougal2@223
  6065
    scrollbar.height = scrollbar.getTop() - y
dougal2@223
  6066
    scrollbar.draw()
jromang@0
  6067
radiance29@155
  6068
mouse_xr=1 
radiance29@155
  6069
mouse_yr=1 
jromang@0
  6070
dougal2@192
  6071
activeObject = None
dougal2@192
  6072
activeEvent = None
dougal2@193
  6073
lastEventTime = 0
dougal2@196
  6074
key_tabs = {
dougal2@223
  6075
    Draw.ONEKEY:     0,
dougal2@223
  6076
    Draw.TWOKEY:     1,
dougal2@223
  6077
    Draw.THREEKEY:   2,
dougal2@223
  6078
    Draw.FOURKEY:    3,
dougal2@223
  6079
    Draw.FIVEKEY:    4,
dougal2@196
  6080
}
zuegs@21
  6081
def luxEvent(evt, val):  # function that handles keyboard and mouse events
dougal2@223
  6082
    global activeObject, activemat, activeEvent, lastEventTime, key_tabs
dougal2@223
  6083
    if evt == Draw.ESCKEY or evt == Draw.QKEY:
dougal2@223
  6084
        stop = Draw.PupMenu("OK?%t|Cancel export %x1")
dougal2@223
  6085
        if stop == 1:
dougal2@223
  6086
            Draw.Exit()
dougal2@223
  6087
            return
dougal2@223
  6088
    scn = Scene.GetCurrent()
dougal2@223
  6089
    if scn:
dougal2@223
  6090
        if scn.objects.active != activeObject:
dougal2@223
  6091
            activeObject = scn.objects.active
dougal2@223
  6092
            activemat = None
dougal2@223
  6093
            Window.QRedrawAll()
dougal2@223
  6094
    if (evt == Draw.MOUSEX) or (evt == Draw.MOUSEY): scrollbar.Mouse()
dougal2@223
  6095
    if evt == Draw.WHEELUPMOUSE: scrollbar.scroll(-16)
dougal2@223
  6096
    if evt == Draw.WHEELDOWNMOUSE: scrollbar.scroll(16)
dougal2@223
  6097
    if evt == Draw.PAGEUPKEY: scrollbar.scroll(-50)
dougal2@223
  6098
    if evt == Draw.PAGEDOWNKEY: scrollbar.scroll(50)
dougal2@223
  6099
dougal2@223
  6100
    # scroll to [T]op and [B]ottom
dougal2@223
  6101
    if evt == Draw.TKEY:
dougal2@223
  6102
        scrollbar.scroll(-scrollbar.position)
dougal2@223
  6103
    if evt == Draw.BKEY:
dougal2@223
  6104
        scrollbar.scroll(100000)   # Some large number should be enough ?!
dougal2@223
  6105
dougal2@223
  6106
    # R key shortcut to launch render
dougal2@223
  6107
    # E key shortcut to export current scene (not render)
dougal2@223
  6108
    # P key shortcut to preview current material
dougal2@223
  6109
    # These keys need time and process-complete locks
dougal2@223
  6110
    if evt in [Draw.RKEY, Draw.EKEY, Draw.PKEY]:
dougal2@223
  6111
        if activeEvent == None and (sys.time() - lastEventTime) > 5:
dougal2@223
  6112
            lastEventTime = sys.time()
dougal2@223
  6113
            if evt == Draw.RKEY:
dougal2@223
  6114
                activeEvent = 'RKEY'
dougal2@223
  6115
                CBluxExport(luxProp(scn, "default", "true").get() == "true", True)
dougal2@223
  6116
                activeEvent = None
dougal2@223
  6117
            if evt == Draw.EKEY:
dougal2@223
  6118
                activeEvent = 'EKEY'
dougal2@223
  6119
                CBluxExport(luxProp(scn, "default", "true").get() == "true", False)
dougal2@223
  6120
                activeEvent = None
dougal2@223
  6121
            if evt == Draw.PKEY:
dougal2@223
  6122
                activeEvent = 'PKEY'
dougal2@223
  6123
                if activemat != None:
dougal2@223
  6124
                    Preview_Update(activemat, '', True, 0, None, None, None)
dougal2@223
  6125
                activeEvent = None
dougal2@223
  6126
        
dougal2@223
  6127
    # Switch GUI tabs with number keys
dougal2@223
  6128
    if evt in key_tabs.keys():
dougal2@223
  6129
        luxProp(scn, "page", 0).set(key_tabs[evt])        
dougal2@223
  6130
        luxDraw()
dougal2@223
  6131
        Window.QRedrawAll()
dougal2@223
  6132
          
dougal2@223
  6133
dougal2@223
  6134
    # Handle icon button events - note - radiance - this is a work in progress! :)
dougal2@223
  6135
#    if evt == Draw.LEFTMOUSE and not val: 
dougal2@223
  6136
#           size=BGL.Buffer(BGL.GL_FLOAT, 4) 
dougal2@223
  6137
#           BGL.glGetFloatv(BGL.GL_SCISSOR_BOX, size) 
dougal2@223
  6138
#            size= [int(s) for s in size] 
dougal2@223
  6139
#        mx, my = Window.GetMouseCoords()
dougal2@223
  6140
#        mousex = mx - size[0]
dougal2@223
  6141
#        print "mousex = %i"%mousex
dougal2@223
  6142
#        #if((mousex > 2) and (mousex < 25)):
dougal2@223
  6143
#            # Mouse clicked in left button bar
dougal2@223
  6144
#        if((mousex > 399) and (mousex < 418)):
dougal2@223
  6145
#            # Mouse clicked in right button bar
dougal2@223
  6146
#            mousey = my - size[1] - scrollbar.position
dougal2@223
  6147
#            print "mousey = %i"%mousey
dougal2@223
  6148
            
dougal2@223
  6149
    
zuegs@21
  6150
def luxButtonEvt(evt):  # function that handles button events
dougal2@223
  6151
    global usedproperties, usedpropertiesfilterobj
dougal2@223
  6152
    if evt == evtLuxGui:
dougal2@223
  6153
        Draw.Redraw()
dougal2@223
  6154
    if evt == evtSavePreset:
dougal2@223
  6155
        scn = Scene.GetCurrent()
dougal2@223
  6156
        if scn:
dougal2@223
  6157
            name = Draw.PupStrInput("preset name: ", "")
dougal2@223
  6158
            if name != "":
dougal2@223
  6159
                usedproperties = {}
dougal2@223
  6160
                usedpropertiesfilterobj = None
dougal2@223
  6161
                luxSurfaceIntegrator(scn)
dougal2@223
  6162
                luxSampler(scn)
dougal2@223
  6163
                luxPixelFilter(scn)
dougal2@223
  6164
                # luxFilm(scn)
dougal2@223
  6165
                luxAccelerator(scn)
dougal2@223
  6166
                # luxEnvironment(scn)
dougal2@223
  6167
                saveScenePreset(name, usedproperties.copy())
dougal2@223
  6168
                luxProp(scn, "preset", "").set(name)
dougal2@223
  6169
                Draw.Redraw()
dougal2@223
  6170
    if evt == evtDeletePreset:
dougal2@223
  6171
        presets = getScenePresets().keys()
dougal2@223
  6172
        presets.sort()
dougal2@223
  6173
        presetsstr = "delete preset: %t"
dougal2@223
  6174
        for i, v in enumerate(presets): presetsstr += "|%s %%x%d"%(v, i)
dougal2@223
  6175
        r = Draw.PupMenu(presetsstr, 20)
dougal2@223
  6176
        if r >= 0:
dougal2@223
  6177
            saveScenePreset(presets[r], None)
dougal2@223
  6178
            Draw.Redraw()
dougal2@223
  6179
dougal2@223
  6180
    if evt == evtLoadMaterial:
dougal2@223
  6181
        if activemat:
dougal2@223
  6182
            mats = getMaterialPresets()
dougal2@223
  6183
            matskeys = mats.keys()
dougal2@223
  6184
            matskeys.sort()
dougal2@223
  6185
            matsstr = "load preset: %t"
dougal2@223
  6186
            for i, v in enumerate(matskeys): matsstr += "|%s %%x%d"%(v, i)
dougal2@223
  6187
            r = Draw.PupMenu(matsstr, 20)
dougal2@223
  6188
            if r >= 0:
dougal2@223
  6189
                name = matskeys[r]
dougal2@223
  6190
                try:
dougal2@223
  6191
#                    for k,v in mats[name].items(): activemat.properties['luxblend'][k] = v
dougal2@223
  6192
                    for k,v in mats[name].items(): luxProp(activemat, k, None).set(v)
dougal2@223
  6193
                except: pass
dougal2@223
  6194
                Draw.Redraw()
dougal2@223
  6195
    if evt == evtSaveMaterial:
dougal2@223
  6196
        if activemat:
dougal2@223
  6197
            name = Draw.PupStrInput("preset name: ", "")
dougal2@223
  6198
            if name != "":
dougal2@223
  6199
                usedproperties = {}
dougal2@223
  6200
                usedpropertiesfilterobj = activemat
dougal2@223
  6201
                luxMaterial(activemat)
dougal2@223
  6202
                saveMaterialPreset(name, usedproperties.copy())
dougal2@223
  6203
                Draw.Redraw()
dougal2@223
  6204
    if evt == evtDeleteMaterial:
dougal2@223
  6205
        matskeys = getMaterialPresets().keys()
dougal2@223
  6206
        matskeys.sort()
dougal2@223
  6207
        matsstr = "delete preset: %t"
dougal2@223
  6208
        for i, v in enumerate(matskeys): matsstr += "|%s %%x%d"%(v, i)
dougal2@223
  6209
        r = Draw.PupMenu(matsstr, 20)
dougal2@223
  6210
        if r >= 0:
dougal2@223
  6211
            saveMaterialPreset(matskeys[r], None)
dougal2@223
  6212
            Draw.Redraw()
dougal2@223
  6213
    if evt == evtConvertMaterial:
dougal2@223
  6214
        if activemat: convertMaterial(activemat)
dougal2@223
  6215
        Draw.Redraw()
dougal2@223
  6216
    if evt == evtLoadMaterial2:
dougal2@223
  6217
        if activemat:
dougal2@223
  6218
            scn = Scene.GetCurrent()
dougal2@223
  6219
            Window.FileSelector(lambda fn:loadMatTex(activemat, fn), "load material", luxProp(scn, "lux", "").get()+os.sep+".lbm")
dougal2@223
  6220
    if evt == evtSaveMaterial2:
dougal2@223
  6221
        if activemat:
dougal2@223
  6222
            scn = Scene.GetCurrent()
dougal2@223
  6223
            Window.FileSelector(lambda fn:saveMaterial(activemat, fn), "save material", luxProp(scn, "lux", "").get()+os.sep+".lbm")
dougal2@223
  6224
    
jromang@0
  6225
jromang@0
  6226
def setFocus(target):
dougal2@223
  6227
    currentscene = Scene.GetCurrent()
dougal2@223
  6228
    camObj = currentscene.objects.camera # currentscene.getCurrentCamera()
dougal2@223
  6229
    if target == "S":
dougal2@223
  6230
        try:
dougal2@223
  6231
            refLoc = (Object.GetSelected()[0]).getLocation()
dougal2@223
  6232
        except:
dougal2@223
  6233
            print "select an object to focus\n"
dougal2@223
  6234
    elif target == "C":
dougal2@223
  6235
        refLoc = Window.GetCursorPos()
dougal2@223
  6236
    else:
dougal2@223
  6237
        refLoc = (Object.Get(target)).getLocation()
dougal2@223
  6238
    dist = Mathutils.Vector(refLoc) - Mathutils.Vector(camObj.getLocation())
dougal2@223
  6239
    camDir = camObj.getMatrix()[2]*(-1.0)
dougal2@223
  6240
    camObj.getData(mesh=1).dofDist = (camDir[0]*dist[0]+camDir[1]*dist[1]+camDir[2]*dist[2])/camDir.length # data
zuegs@10
  6241
jromang@0
  6242
radiance29@113
  6243
# Parse command line arguments for batch mode rendering if supplied
zuegs@171
  6244
zuegs@171
  6245
try:
dougal2@223
  6246
    batchindex = osys.argv.index('--batch')
dougal2@223
  6247
    pyargs = osys.argv[osys.argv.index('--batch')+1:]
radiance29@113
  6248
except: pyargs = []
radiance29@113
  6249
zuegs@171
  6250
if (pyargs != []) and (batchindex != 0):
jensverwiebe@338
  6251
    print "\n\nLuxBlend v0.6RC5 - BATCH mode\n"
dougal2@223
  6252
    LuxIsGUI = False
dougal2@223
  6253
dougal2@223
  6254
    scene = Scene.GetCurrent()
dougal2@223
  6255
    context = scene.getRenderingContext()
dougal2@223
  6256
dougal2@223
  6257
    luxpath = ""
dougal2@223
  6258
    import getopt
dougal2@223
  6259
    o, a = getopt.getopt(pyargs, 's:e:o:t:l:',["scale=","haltspp=","run=", "lbm=", "lbt="])
dougal2@223
  6260
dougal2@223
  6261
    opts = {}
dougal2@223
  6262
    for k,v in o:
dougal2@223
  6263
        opts[k] = v
dougal2@223
  6264
dougal2@223
  6265
    if (opts.has_key('--run')) and (opts['--run'] == 'false'):
dougal2@223
  6266
        print "Run: false"
dougal2@223
  6267
        luxProp(scene, "run", "true").set("false")
dougal2@223
  6268
    else:
dougal2@223
  6269
        luxProp(scene, "run", "true").set("true")
dougal2@223
  6270
dougal2@223
  6271
    if opts.has_key('--scale'):
dougal2@223
  6272
        print "Zoom: %s" %opts['--scale']
dougal2@223
  6273
        luxProp(scene, "film.scale", "100 %").set(opts['--scale'])
dougal2@223
  6274
dougal2@223
  6275
    if opts.has_key('--haltspp'):
dougal2@223
  6276
        print "haltspp: %s" %opts['--haltspp']
dougal2@223
  6277
        luxProp(scene, "haltspp", 0).set(int(opts['--haltspp']))
dougal2@223
  6278
dougal2@223
  6279
    if opts.has_key('-s'):
dougal2@223
  6280
        print "Start frame: %s" %opts['-s']
dougal2@223
  6281
        context.startFrame(int(opts['-s']))
dougal2@223
  6282
    else:
dougal2@223
  6283
        print "Error: Start frame not supplied (-s)"; osys.exit(1)
dougal2@223
  6284
    if opts.has_key('-e'):
dougal2@223
  6285
        print "End frame: %s" %opts['-e']
dougal2@223
  6286
        context.endFrame(int(opts['-e']))
dougal2@223
  6287
    else:
dougal2@223
  6288
        print "Error: End frame not supplied (-e)"; osys.exit(1)
dougal2@223
  6289
    if opts.has_key('-l'):
dougal2@223
  6290
        print "Path to lux binary: %s" %opts['-l']
dougal2@258
  6291
        luxbatchconsolemode = luxProp(scene, "luxbatchc", "false")
dougal2@258
  6292
        luxbatchconsolemode.set("true")
dougal2@223
  6293
        luxpathprop = luxProp(scene, "lux", "")
dougal2@223
  6294
        luxpathprop.set(opts['-l'])
dougal2@223
  6295
    else:
dougal2@223
  6296
        print "Error: path to lux binary not supplied (-l)"; osys.exit(1)    
dougal2@223
  6297
    if opts.has_key('-o'):
dougal2@223
  6298
        print "Image output path: %s" %opts['-o']
dougal2@223
  6299
        luxProp(scene, "overrideoutputpath", "").set(opts['-o'])
dougal2@223
  6300
    else:
dougal2@223
  6301
        print "Error: image output path not supplied (-o)"; osys.exit(1)    
dougal2@223
  6302
    if opts.has_key('-t'):
dougal2@223
  6303
        print "Temporary export path: %s" %opts['-t']
dougal2@223
  6304
        luxProp(scene, "datadir", "").set(opts['-t'])
dougal2@223
  6305
    else:
dougal2@223
  6306
        print "Error: Temporary export path not supplied (-t)"; osys.exit(1)            
dougal2@223
  6307
    
dougal2@223
  6308
    if opts.has_key('--lbm'):
dougal2@223
  6309
        print "Load material: %s" %opts['--lbm']
dougal2@223
  6310
        mat = Material.Get("Material")
dougal2@223
  6311
        if mat: loadMatTex(mat, opts['--lbm'])
dougal2@223
  6312
        else:
dougal2@223
  6313
            print "Error: No material with name \"Material\" found (--lbm)"; osys.exit(1)
dougal2@223
  6314
            
dougal2@223
  6315
    if opts.has_key('--lbt'):
dougal2@223
  6316
        print "Load material: %s" %opts['--lbt']
dougal2@223
  6317
        mat = Material.Get("Material")
dougal2@223
  6318
        if mat: loadMatTex(mat, opts['--lbt'], ':Kd')
dougal2@223
  6319
        else:
dougal2@223
  6320
            print "Error: No material with name \"Material\" found (--lbt)"; osys.exit(1)
dougal2@223
  6321
dougal2@223
  6322
#    CBluxAnimExport(True, True)
radiance29@245
  6323
    CBluxAnimExport(True, True, False) # as by zukazuka (http://www.luxrender.net/forum/viewtopic.php?f=11&t=1288)
dougal2@223
  6324
    osys.exit(0)
radiance29@113
  6325
radiance29@113
  6326
else:
jensverwiebe@338
  6327
    print "\n\nLuxBlend v0.6RC5 - UI mode\n"
dougal2@223
  6328
    from Blender.Window import DrawProgressBar
dougal2@223
  6329
    LuxIsGUI = True
dougal2@223
  6330
    
dougal2@223
  6331
    Draw.Register(luxDraw, luxEvent, luxButtonEvt) # init GUI
dougal2@223
  6332
dougal2@223
  6333
    luxpathprop = luxProp(Scene.GetCurrent(), "lux", "")
dougal2@223
  6334
    luxpath = luxpathprop.get()
dougal2@223
  6335
    luxrun = luxProp(Scene.GetCurrent(), "run", True).get()
dougal2@223
  6336
    checkluxpath = luxProp(Scene.GetCurrent(), "checkluxpath", True).get()
dougal2@223
  6337
dougal2@223
  6338
    if checkluxpath and luxrun:
dougal2@223
  6339
        if (luxpath is None) or (sys.exists(luxpath)<=0):
dougal2@223
  6340
            # luxpath not valid, so delete entry from .blend scene file ...
dougal2@223
  6341
            luxpathprop.delete()
dougal2@223
  6342
            # and re-get luxpath, so we get the path from default-settings
dougal2@223
  6343
            luxpath = luxpathprop.get()
dougal2@223
  6344
            if (luxpath is None) or (sys.exists(luxpath)<=0):
dougal2@223
  6345
                print "WARNING: LuxPath \"%s\" is not valid\n"%(luxpath)
dougal2@223
  6346
                scn = Scene.GetCurrent()
dougal2@223
  6347
                if scn:
dougal2@223
  6348
                    r = Draw.PupMenu("Installation: Set path to the lux render software?%t|Yes%x1|No%x0|Never%x2")
dougal2@223
  6349
                    if r == 1:
dougal2@223
  6350
                        Window.FileSelector(lambda s:luxProp(scn, "lux", "").set(Blender.sys.dirname(s)+os.sep), "Select file in Lux path")
dougal2@223
  6351
                        saveluxdefaults()
dougal2@223
  6352
                    if r == 2:
dougal2@223
  6353
                        newluxdefaults["checkluxpath"] = False
dougal2@223
  6354
                        saveluxdefaults()
dougal2@223
  6355
    else    :
dougal2@223
  6356
        print "Lux path check disabled\n"