LuxBlend_0.1.py
author jensverwiebe
Tue Oct 13 20:33:01 2009 +0200 (2009-10-13)
changeset 414 bc1e3bef1607
parent 413 728fbc9db8b2
child 416 6ad00238e6be
child 423 83cdf52989cd
permissions -rw-r--r--
tagging for v0.6
lordcrc@384
     1
#!BPY
lordcrc@384
     2
# -*- coding: utf-8 -*-
lordcrc@384
     3
# coding=utf-8
lordcrc@384
     4
"""Registration info for Blender menus:
jensverwiebe@414
     5
Name: 'LuxBlend v0.6 Exporter'
lordcrc@384
     6
Blender: 248
lordcrc@384
     7
Group: 'Render'
jensverwiebe@414
     8
Tooltip: 'Export/Render to LuxRender v0.6 scene format (.lxs)'
lordcrc@384
     9
"""
lordcrc@384
    10
lordcrc@384
    11
__author__ = "radiance, zuegs, ideasman42, luxblender, dougal2"
jensverwiebe@414
    12
__version__ = "0.6"
lordcrc@384
    13
__url__ = [
lordcrc@384
    14
	"http://www.luxrender.net/",
lordcrc@384
    15
	"http://www.luxrender.net/forum/viewforum.php?f=11",
lordcrc@384
    16
	"http://www.luxrender.net/wiki/index.php/Tutorial_1:_Your_first_scene_%26_render"
lordcrc@384
    17
]
lordcrc@384
    18
__bpydoc__ = """\
lordcrc@384
    19
LuxRender is an open-source rendering system for physically correct, unbiased image synthesis.
lordcrc@384
    20
This is the Luxrender Blender Export Script.
lordcrc@384
    21
lordcrc@384
    22
Useful links:
lordcrc@384
    23
- For updates: http://www.luxrender.net/forum/viewforum.php?f=11
lordcrc@384
    24
- For Blender Tutorial: http://www.luxrender.net/wiki/index.php/Tutorial_1:_Your_first_scene_%26_render
lordcrc@384
    25
lordcrc@384
    26
Usage: 
lordcrc@384
    27
- Run the script from the render menu.
lordcrc@384
    28
- Set the default location of the Luxrender.exe.
lordcrc@384
    29
lordcrc@384
    30
Please check the lux tutorials & forums for more information.
lordcrc@384
    31
"""
lordcrc@384
    32
lordcrc@384
    33
#
lordcrc@384
    34
# ***** BEGIN GPL LICENSE BLOCK *****
lordcrc@384
    35
#
lordcrc@384
    36
# --------------------------------------------------------------------------
jensverwiebe@414
    37
# LuxBlend v0.6 exporter
lordcrc@384
    38
# --------------------------------------------------------------------------
lordcrc@384
    39
#
lordcrc@384
    40
# Authors:
lordcrc@384
    41
# radiance, zuegs, ideasman42, luxblender, dougal2
lordcrc@384
    42
#
lordcrc@384
    43
# This program is free software; you can redistribute it and/or
lordcrc@384
    44
# modify it under the terms of the GNU General Public License
lordcrc@384
    45
# as published by the Free Software Foundation; either version 2
lordcrc@384
    46
# of the License, or (at your option) any later version.
lordcrc@384
    47
#
lordcrc@384
    48
# This program is distributed in the hope that it will be useful,
lordcrc@384
    49
# but WITHOUT ANY WARRANTY; without even the implied warranty of
lordcrc@384
    50
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
lordcrc@384
    51
# GNU General Public License for more details.
lordcrc@384
    52
#
lordcrc@384
    53
# You should have received a copy of the GNU General Public License
lordcrc@384
    54
# along with this program; if not, write to the Free Software Foundation,
lordcrc@384
    55
# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
lordcrc@384
    56
#
lordcrc@384
    57
# ***** END GPL LICENCE BLOCK *****
lordcrc@384
    58
# --------------------------------------------------------------------------
lordcrc@384
    59
lordcrc@384
    60
lordcrc@384
    61
lordcrc@384
    62
lordcrc@384
    63
######################################################
lordcrc@384
    64
# Importing modules
lordcrc@384
    65
######################################################
lordcrc@384
    66
lordcrc@384
    67
import math
lordcrc@384
    68
import time
lordcrc@384
    69
import os
lordcrc@384
    70
import sys as osys
lordcrc@384
    71
import types
lordcrc@384
    72
import subprocess
lordcrc@384
    73
import Blender
lordcrc@384
    74
from Blender import Mesh, Scene, Object, Material, Texture, Window, sys, Draw, BGL, Mathutils, Lamp, Image
lordcrc@384
    75
lordcrc@384
    76
lordcrc@384
    77
lordcrc@384
    78
lordcrc@384
    79
######################################################
lordcrc@384
    80
# Functions
lordcrc@384
    81
######################################################
lordcrc@384
    82
lordcrc@384
    83
# New name based on old with a different extension
lordcrc@384
    84
def newFName(ext):
lordcrc@384
    85
    return Blender.Get('filename')[: -len(Blender.Get('filename').split('.', -1)[-1]) ] + ext
lordcrc@384
    86
lordcrc@384
    87
lordcrc@384
    88
# some helpers
lordcrc@384
    89
def luxstr(str):
lordcrc@384
    90
    return str.replace("\\", "\\\\")
lordcrc@384
    91
lordcrc@384
    92
lordcrc@384
    93
### relpath ##########################
lordcrc@384
    94
def relpath(base, target):
lordcrc@384
    95
    if target[0:2] == "\\\\" or target[0:2] == "//":
lordcrc@384
    96
        return target[2:len(target)]
lordcrc@384
    97
    if not os.path.isabs(base):
lordcrc@384
    98
        base = os.path.abspath(base)
lordcrc@384
    99
    if not os.path.isabs(target):
lordcrc@384
   100
        target = os.path.abspath(target)
lordcrc@384
   101
    if os.sep == "\\":
lordcrc@384
   102
        base = os.path.normcase(base)
lordcrc@384
   103
        target = os.path.normcase(target)
lordcrc@384
   104
    if base == os.sep:
lordcrc@384
   105
        return '.' + target
lordcrc@384
   106
    baselist = base.split(os.sep)
lordcrc@384
   107
    if baselist[-1] == "":
lordcrc@384
   108
        baselist = baselist[:-1]
lordcrc@384
   109
    targetlist = target.split(os.sep)
lordcrc@384
   110
    i = 0
lordcrc@384
   111
    top = min([len(baselist), len(targetlist)])
lordcrc@384
   112
    while i < top and baselist[i] == targetlist[i]:
lordcrc@384
   113
        i+=1
lordcrc@384
   114
    if i == 0:
lordcrc@384
   115
        return os.sep.join(targetlist)
lordcrc@384
   116
    if i == len(baselist):
lordcrc@384
   117
        return os.sep.join(targetlist[i:])
lordcrc@384
   118
    else:
lordcrc@384
   119
        return ('..' + os.sep) * (len(baselist) - i) + os.sep.join(targetlist[i:])
lordcrc@384
   120
lordcrc@384
   121
### luxFilePath #####################
lordcrc@384
   122
lxs_filename = ""
lordcrc@384
   123
previewing = False
lordcrc@384
   124
def luxFilePath(filename):
lordcrc@384
   125
    global lxs_filename, previewing
lordcrc@384
   126
    scn = Scene.GetCurrent()
lordcrc@384
   127
    pm = luxProp(scn, "pathmode", "absolute").get()
lordcrc@384
   128
    if (pm=="absolute") or previewing: # absolute paths (the old / default mode)
lordcrc@384
   129
        return filename
lordcrc@384
   130
    elif pm=="relative": # relative paths
lordcrc@384
   131
        base = os.path.dirname(lxs_filename)
lordcrc@384
   132
        return relpath(base, filename)
lordcrc@384
   133
    elif pm=="flat": # flat mode - only filename
lordcrc@384
   134
        return os.path.basename(filename)
lordcrc@384
   135
lordcrc@384
   136
lordcrc@384
   137
lordcrc@384
   138
###### RGC ##########################
lordcrc@384
   139
def rg(col):
lordcrc@384
   140
    scn = Scene.GetCurrent()
lordcrc@384
   141
    if luxProp(scn, "RGC", "true").get()=="true":
lordcrc@384
   142
        gamma = luxProp(scn, "film.gamma", 2.2).get()
lordcrc@384
   143
    else:
lordcrc@384
   144
        gamma = 1.0
lordcrc@384
   145
    ncol = col**gamma
lordcrc@384
   146
    if luxProp(scn, "colorclamp", "false").get()=="true":
lordcrc@384
   147
        ncol = ncol * 0.9
lordcrc@384
   148
        if ncol > 0.9:
lordcrc@384
   149
            ncol = 0.9
lordcrc@384
   150
        if ncol < 0.0:
lordcrc@384
   151
            ncol = 0.0
lordcrc@384
   152
    return ncol
lordcrc@384
   153
lordcrc@384
   154
def texturegamma():
lordcrc@384
   155
    scn = Scene.GetCurrent()
lordcrc@384
   156
    if luxProp(scn, "RGC", "true").get()=="true":
lordcrc@384
   157
        return luxProp(scn, "film.gamma", 2.2).get()
lordcrc@384
   158
    else:
lordcrc@384
   159
        return 1.0
lordcrc@384
   160
lordcrc@384
   161
def exportMaterial(mat):
lordcrc@384
   162
    str = "# Material '%s'\n" %mat.name
lordcrc@384
   163
    return str+luxMaterial(mat)+"\n"
lordcrc@384
   164
lordcrc@384
   165
lordcrc@384
   166
def exportMaterialGeomTag(mat):
lordcrc@384
   167
    return "%s\n"%(luxProp(mat, "link", "").get())
lordcrc@384
   168
lordcrc@384
   169
lordcrc@384
   170
lordcrc@384
   171
lordcrc@384
   172
################################################################
lordcrc@384
   173
lordcrc@384
   174
lordcrc@384
   175
dummyMat = 2394723948 # random identifier for dummy material
lordcrc@384
   176
clayMat = None
lordcrc@384
   177
lordcrc@384
   178
#-------------------------------------------------
lordcrc@384
   179
# getMaterials(obj)
lordcrc@384
   180
# helper function to get the material list of an object in respect of obj.colbits
lordcrc@384
   181
#-------------------------------------------------
lordcrc@384
   182
def getMaterials(obj, compress=False):
lordcrc@384
   183
    global clayMat
lordcrc@384
   184
    mats = [None]*16
lordcrc@384
   185
    colbits = obj.colbits
lordcrc@384
   186
    objMats = obj.getMaterials(1)
lordcrc@384
   187
    data = obj.getData(mesh=1)
lordcrc@384
   188
    try:
lordcrc@384
   189
        dataMats = data.materials
lordcrc@384
   190
    except:
lordcrc@384
   191
        try:
lordcrc@384
   192
            dataMats = data.getMaterials(1)
lordcrc@384
   193
        except:
lordcrc@384
   194
            dataMats = []
lordcrc@384
   195
            colbits = 0xffff
lordcrc@384
   196
    m = max(len(objMats), len(dataMats))
lordcrc@384
   197
    if m>0:
lordcrc@384
   198
        objMats.extend([None]*16)
lordcrc@384
   199
        dataMats.extend([None]*16)
lordcrc@384
   200
        for i in range(m):
lordcrc@384
   201
            if (colbits & (1<<i) > 0):
lordcrc@384
   202
                mats[i] = objMats[i]
lordcrc@384
   203
            else:
lordcrc@384
   204
                mats[i] = dataMats[i]
lordcrc@384
   205
        if compress:
lordcrc@384
   206
            mats = [m for m in mats if m]
tom@405
   207
    
tom@405
   208
    slots = [m for m in mats if m]
tom@405
   209
    if m==0 or not slots:
lordcrc@384
   210
        print("Warning: object %s has no material assigned" % (obj.getName()))
lordcrc@384
   211
        mats = []
lordcrc@384
   212
    # clay option
lordcrc@384
   213
    if luxProp(Scene.GetCurrent(), "clay", "false").get()=="true":
lordcrc@384
   214
        if clayMat==None: clayMat = Material.New("lux_clayMat")
lordcrc@384
   215
        for i in range(len(mats)):
lordcrc@384
   216
            if mats[i]:
lordcrc@384
   217
                mattype = luxProp(mats[i], "type", "").get()
lordcrc@384
   218
                if (mattype not in ["portal","light","boundvolume"]): mats[i] = clayMat
lordcrc@384
   219
    return mats
lordcrc@384
   220
lordcrc@384
   221
lordcrc@384
   222
lordcrc@384
   223
######################################################
lordcrc@384
   224
# luxExport class
lordcrc@384
   225
######################################################
lordcrc@384
   226
lordcrc@384
   227
class luxExport:
lordcrc@384
   228
    #-------------------------------------------------
lordcrc@384
   229
    # __init__
lordcrc@384
   230
    # initializes the exporter object
lordcrc@384
   231
    #-------------------------------------------------
lordcrc@384
   232
    def __init__(self, scene):
lordcrc@384
   233
        self.scene = scene
lordcrc@384
   234
        self.camera = scene.objects.camera
lordcrc@384
   235
        self.objects = []
lordcrc@384
   236
        self.portals = []
lordcrc@384
   237
        self.volumes = []
lordcrc@384
   238
        self.meshes = {}
lordcrc@384
   239
        self.materials = []
lordcrc@384
   240
        self.lights = []
lordcrc@384
   241
        self.duplis = set()
lordcrc@384
   242
lordcrc@384
   243
    #-------------------------------------------------
lordcrc@384
   244
    # analyseObject(self, obj, matrix, name)
lordcrc@384
   245
    # called by analyseScene to build the lists before export
lordcrc@384
   246
    #-------------------------------------------------
lordcrc@384
   247
    def analyseObject(self, obj, matrix, name, isOriginal=True, isDupli=False):
lordcrc@384
   248
        light = False
lordcrc@384
   249
        if (obj.users > 0):
lordcrc@384
   250
            obj_type = obj.getType()
lordcrc@384
   251
            if (obj.enableDupFrames and isOriginal):
lordcrc@384
   252
                for o, m in obj.DupObjects:
lordcrc@384
   253
                    self.analyseObject(o, m, "%s.%s"%(name, o.getName()), False)    
lordcrc@384
   254
            if (obj.enableDupGroup or obj.enableDupVerts or obj.enableDupFaces):
lordcrc@384
   255
                self.duplis.add(obj)
lordcrc@384
   256
                for o, m in obj.DupObjects:
lordcrc@384
   257
                    self.analyseObject(o, m, "%s.%s"%(name, o.getName()), True, True)    
lordcrc@384
   258
            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"))):
lordcrc@384
   259
                mats = getMaterials(obj)
lordcrc@384
   260
                if (len(mats)>0) and (mats[0]!=None) and ((mats[0].name=="PORTAL") or (luxProp(mats[0], "type", "").get()=="portal")):
lordcrc@384
   261
                    self.portals.append([obj, matrix])
lordcrc@384
   262
                elif (len(mats)>0) and (luxProp(mats[0], "type", "").get()=="boundvolume"):
lordcrc@384
   263
                    self.volumes.append([obj, matrix])
lordcrc@384
   264
                else:
lordcrc@384
   265
                    for mat in mats:
lordcrc@384
   266
                        if (mat!=None) and (mat not in self.materials):
lordcrc@384
   267
                            self.materials.append(mat)
lordcrc@384
   268
                        if (mat!=None) and ((luxProp(mat, "type", "").get()=="light") or (luxProp(mat, "emission", "false").get()=="true")):
lordcrc@384
   269
                            light = True
lordcrc@384
   270
                    mesh_name = obj.getData(name_only=True)
lordcrc@384
   271
                    try:
lordcrc@384
   272
                        self.meshes[mesh_name] += [obj]
lordcrc@384
   273
                    except KeyError:
lordcrc@384
   274
                        self.meshes[mesh_name] = [obj]                
lordcrc@384
   275
                    self.objects.append([obj, matrix])
lordcrc@384
   276
            elif (obj_type == "Lamp"):
lordcrc@384
   277
                ltype = obj.getData(mesh=1).getType() # data
lordcrc@384
   278
                if (ltype == Lamp.Types["Lamp"]) or (ltype == Lamp.Types["Spot"]) or (ltype == Lamp.Types["Area"]):
lordcrc@384
   279
                    self.lights.append([obj, matrix])
lordcrc@384
   280
                    light = True
lordcrc@384
   281
        return light
lordcrc@384
   282
lordcrc@384
   283
    #-------------------------------------------------
lordcrc@384
   284
    # analyseScene(self)
lordcrc@384
   285
    # this function builds the lists of object, lights, meshes and materials before export
lordcrc@384
   286
    #-------------------------------------------------
lordcrc@384
   287
    def analyseScene(self):
lordcrc@384
   288
        light = False
lordcrc@384
   289
        for obj in self.scene.objects:
lordcrc@384
   290
            if ((obj.Layers & self.scene.Layers) > 0):
lordcrc@384
   291
                if self.analyseObject(obj, obj.getMatrix(), obj.getName()): light = True
lordcrc@384
   292
        return light
lordcrc@384
   293
lordcrc@384
   294
    #-------------------------------------------------
lordcrc@384
   295
    # exportMaterialLink(self, file, mat)
lordcrc@384
   296
    # exports material link. LuxRender "Material" 
lordcrc@384
   297
    #-------------------------------------------------
lordcrc@384
   298
    def exportMaterialLink(self, file, mat):
lordcrc@384
   299
        if mat == dummyMat:
lordcrc@384
   300
            file.write("\tMaterial \"matte\" # dummy material\n")
lordcrc@384
   301
        else:
lordcrc@384
   302
            file.write("\t%s"%exportMaterialGeomTag(mat)) # use original methode
lordcrc@384
   303
lordcrc@384
   304
    #-------------------------------------------------
lordcrc@384
   305
    # exportMaterial(self, file, mat)
lordcrc@384
   306
    # exports material. LuxRender "Texture" 
lordcrc@384
   307
    #-------------------------------------------------
lordcrc@384
   308
    def exportMaterial(self, file, mat):
lordcrc@384
   309
        print("material %s"%(mat.getName()))
lordcrc@384
   310
        file.write("\t%s"%exportMaterial(mat)) # use original methode        
lordcrc@384
   311
    
lordcrc@384
   312
    #-------------------------------------------------
lordcrc@384
   313
    # exportMaterials(self, file)
lordcrc@384
   314
    # exports materials to the file
lordcrc@384
   315
    #-------------------------------------------------
lordcrc@384
   316
    def exportMaterials(self, file):
lordcrc@384
   317
        for mat in self.materials:
lordcrc@384
   318
            
lordcrc@384
   319
            self.exportMaterial(file, mat)
lordcrc@384
   320
lordcrc@384
   321
    #-------------------------------------------------
lordcrc@384
   322
    # getMeshType(self, vertcount, mat)
lordcrc@384
   323
    # returns type of mesh as string to use depending on thresholds
lordcrc@384
   324
    #-------------------------------------------------
lordcrc@384
   325
    def getMeshType(self, vertcount, mat):
lordcrc@384
   326
        scn = Scene.GetCurrent()
lordcrc@384
   327
        if mat != dummyMat:
lordcrc@384
   328
            usesubdiv = luxProp(mat, "subdiv", "false")
lordcrc@384
   329
            usedisp = luxProp(mat, "dispmap", "false")
lordcrc@384
   330
            sharpbound = luxProp(mat, "sharpbound", "false")
lordcrc@384
   331
            nsmooth = luxProp(mat, "nsmooth", "true")
lordcrc@384
   332
            sdoffset = luxProp(mat, "sdoffset", 0.0)
lordcrc@384
   333
            dstr = ""
lordcrc@384
   334
            if usesubdiv.get() == "true":
lordcrc@384
   335
                nlevels = luxProp(mat, "sublevels", 1)
lordcrc@384
   336
                dstr += "\"loopsubdiv\" \"integer nlevels\" [%i] \"bool dmnormalsmooth\" [\"%s\"] \"bool dmsharpboundary\" [\"%s\"]"% (nlevels.get(), nsmooth.get(), sharpbound.get())
lordcrc@384
   337
            
lordcrc@384
   338
            if usedisp.get() == "true":
lordcrc@384
   339
                dstr += " \"string displacementmap\" [\"%s::dispmap.scale\"] \"float dmscale\" [-1.0] \"float dmoffset\" [%f]"%(mat.getName(), sdoffset.get()) # scale is scaled in texture
lordcrc@384
   340
lordcrc@384
   341
            if dstr != "": return dstr
lordcrc@384
   342
lordcrc@384
   343
        return "\"trianglemesh\""
lordcrc@384
   344
lordcrc@384
   345
    #-------------------------------------------------
lordcrc@384
   346
    # exportMesh(self, file, mesh, mats, name, portal)
lordcrc@384
   347
    # exports mesh to the file without any optimization
lordcrc@384
   348
    #-------------------------------------------------
lordcrc@384
   349
    def exportMesh(self, file, mesh, mats, name, portal=False):
lordcrc@384
   350
        if mats == []:
lordcrc@384
   351
            mats = [dummyMat]
lordcrc@384
   352
        for matIndex in range(len(mats)):
lordcrc@384
   353
            if (mats[matIndex] != None):
lordcrc@384
   354
                mesh_str = getMeshType(len(mesh.verts), mats[matIndex])
lordcrc@384
   355
                if (portal):
lordcrc@384
   356
                    file.write("\tShape %s \"integer indices\" [\n"% mesh_str)
lordcrc@384
   357
                else:
lordcrc@384
   358
                    self.exportMaterialLink(file, mats[matIndex])
lordcrc@384
   359
                    file.write("\tPortalShape %s \"integer indices\" [\n"% mesh_str)
lordcrc@384
   360
                index = 0
lordcrc@384
   361
                ffaces = [f for f in mesh.faces if f.mat == matIndex]
lordcrc@384
   362
                for face in ffaces:
lordcrc@384
   363
                    file.write("%d %d %d\n"%(index, index+1, index+2))
lordcrc@384
   364
                    if (len(face)==4):
lordcrc@384
   365
                        file.write("%d %d %d\n"%(index, index+2, index+3))
lordcrc@384
   366
                    index += len(face.verts)
lordcrc@384
   367
                file.write("\t] \"point P\" [\n")
lordcrc@384
   368
                for face in ffaces:
lordcrc@384
   369
                    for vertex in face:
lordcrc@384
   370
                        file.write("%f %f %f\n"% tuple(vertex.co))
lordcrc@384
   371
                file.write("\t] \"normal N\" [\n")
lordcrc@384
   372
                for face in ffaces:
lordcrc@384
   373
                    normal = face.no
lordcrc@384
   374
                    for vertex in face:
lordcrc@384
   375
                        if (face.smooth):
lordcrc@384
   376
                            normal = vertex.no
lordcrc@384
   377
                        file.write("%f %f %f\n"% tuple(normal))
lordcrc@384
   378
                if (mesh.faceUV):
lordcrc@384
   379
                    file.write("\t] \"float uv\" [\n")
lordcrc@384
   380
                    for face in ffaces:
lordcrc@384
   381
                        for uv in face.uv:
lordcrc@384
   382
                            file.write("%f %f\n"% tuple(uv))
lordcrc@384
   383
                file.write("\t]\n")
lordcrc@384
   384
lordcrc@384
   385
    #-------------------------------------------------
lordcrc@384
   386
    # exportMeshOpt(self, file, mesh, mats, name, portal, optNormals)
lordcrc@384
   387
    # exports mesh to the file with optimization.
lordcrc@384
   388
    # portal: export without normals and UVs
lordcrc@384
   389
    # optNormals: speed and filesize optimization, flat faces get exported without normals
lordcrc@384
   390
    #-------------------------------------------------
lordcrc@384
   391
    def exportMeshOpt(self, file, mesh, mats, name, portal=False, optNormals=True):
lordcrc@384
   392
        shapeList, smoothFltr, shapeText = [0], [[0,1]], [""]
lordcrc@384
   393
        if portal:
lordcrc@384
   394
            normalFltr, uvFltr, shapeText = [0], [0], ["portal"] # portal, no normals, no UVs
lordcrc@384
   395
        else:
lordcrc@384
   396
            uvFltr, normalFltr, shapeText = [1], [1], ["mixed with normals"] # normals and UVs
lordcrc@384
   397
            if optNormals: # one pass for flat faces without normals and another pass for smoothed faces with normals, all with UVs
lordcrc@384
   398
                shapeList, smoothFltr, normalFltr, uvFltr, shapeText = [0,1], [[0],[1]], [0,1], [1,1], ["flat w/o normals", "smoothed with normals"]
lordcrc@384
   399
        if mats == []:
lordcrc@384
   400
            mats = [dummyMat]
tom@406
   401
        usedmats = [f.mat for f in mesh.faces]
lordcrc@384
   402
        for matIndex in range(len(mats)):
tom@406
   403
            if not matIndex in usedmats:
tom@406
   404
                continue
tom@406
   405
            if not(portal):
tom@406
   406
                mat = mats[matIndex]
tom@406
   407
                if not mat:
tom@406
   408
                   mat = dummyMat
tom@406
   409
                self.exportMaterialLink(file, mat)
tom@406
   410
            for shape in shapeList:
tom@406
   411
                blenderExportVertexMap = []
tom@406
   412
                exportVerts = []
tom@406
   413
                exportFaces = []
tom@406
   414
                ffaces = [f for f in mesh.faces if (f.mat == matIndex) and (f.smooth in smoothFltr[shape])]
tom@406
   415
                for face in ffaces:
tom@406
   416
                    exportVIndices = []
tom@406
   417
                    index = 0
tom@406
   418
                    for vertex in face:
lordcrc@384
   419
#                            v = [vertex.co[0], vertex.co[1], vertex.co[2]]
tom@406
   420
                        v = [vertex.co]
tom@406
   421
                        if normalFltr[shape]:
tom@406
   422
                            if (face.smooth):
lordcrc@384
   423
#                                    v.extend(vertex.no)
tom@406
   424
                                v.append(vertex.no)
tom@406
   425
                            else:
lordcrc@384
   426
#                                    v.extend(face.no)
tom@406
   427
                                v.append(face.no)
tom@406
   428
                        if (uvFltr[shape]) and (mesh.faceUV):
lordcrc@384
   429
#                                v.extend(face.uv[index])
tom@406
   430
                            v.append(face.uv[index])
tom@406
   431
                        blenderVIndex = vertex.index
tom@406
   432
                        newExportVIndex = -1
tom@406
   433
                        length = len(v)
tom@406
   434
                        if (blenderVIndex < len(blenderExportVertexMap)):
tom@406
   435
                            for exportVIndex in blenderExportVertexMap[blenderVIndex]:
tom@406
   436
                                v2 = exportVerts[exportVIndex]
tom@406
   437
                                if (length==len(v2)) and (v == v2):
tom@406
   438
                                    newExportVIndex = exportVIndex
tom@406
   439
                                    break
tom@406
   440
                        if (newExportVIndex < 0):
tom@406
   441
                            newExportVIndex = len(exportVerts)
tom@406
   442
                            exportVerts.append(v)
tom@406
   443
                            while blenderVIndex >= len(blenderExportVertexMap):
tom@406
   444
                                blenderExportVertexMap.append([])
tom@406
   445
                            blenderExportVertexMap[blenderVIndex].append(newExportVIndex)
tom@406
   446
                        exportVIndices.append(newExportVIndex)
tom@406
   447
                        index += 1
tom@406
   448
                    exportFaces.append(exportVIndices)
tom@406
   449
                if (len(exportVerts)>0):
tom@406
   450
                    mesh_str = self.getMeshType(len(exportVerts), mats[matIndex])
tom@406
   451
                    if (portal):
tom@406
   452
                        file.write("\tPortalShape %s \"integer indices\" [\n"% mesh_str)
tom@406
   453
                    else:
tom@406
   454
                        file.write("\tShape %s \"integer indices\" [\n"% mesh_str)
tom@406
   455
                    for face in exportFaces:
tom@406
   456
                        file.write("%d %d %d\n"%(face[0], face[1], face[2]))
tom@406
   457
                        if (len(face)==4):
tom@406
   458
                            file.write("%d %d %d\n"%(face[0], face[2], face[3]))
tom@406
   459
                    file.write("\t] \"point P\" [\n")
lordcrc@384
   460
#                        for vertex in exportVerts:
lordcrc@384
   461
#                            file.write("%f %f %f\n"%(vertex[0], vertex[1], vertex[2]))
tom@406
   462
                    file.write("".join(["%f %f %f\n"%tuple(vertex[0]) for vertex in exportVerts]))
tom@406
   463
                    if normalFltr[shape]:
tom@406
   464
                        file.write("\t] \"normal N\" [\n")
lordcrc@384
   465
#                            for vertex in exportVerts:
lordcrc@384
   466
#                                file.write("%f %f %f\n"%(vertex[3], vertex[4], vertex[5]))
tom@406
   467
                        file.write("".join(["%f %f %f\n"%tuple(vertex[1]) for vertex in exportVerts])) 
tom@406
   468
                        if (uvFltr[shape]) and (mesh.faceUV):
tom@406
   469
                            file.write("\t] \"float uv\" [\n")
lordcrc@384
   470
#                                for vertex in exportVerts:
lordcrc@384
   471
#                                    file.write("%f %f\n"%(vertex[6], vertex[7]))
tom@406
   472
                            file.write("".join(["%f %f\n"%tuple(vertex[2]) for vertex in exportVerts])) 
tom@406
   473
                    else:            
tom@406
   474
                        if (uvFltr[shape]) and (mesh.faceUV):
tom@406
   475
                            file.write("\t] \"float uv\" [\n")
lordcrc@384
   476
#                                for vertex in exportVerts:
lordcrc@384
   477
#                                    file.write("%f %f\n"%(vertex[3], vertex[4]))
tom@406
   478
                            file.write("".join(["%f %f\n"%tuple(vertex[1]) for vertex in exportVerts])) 
tom@406
   479
                    file.write("\t]\n")
tom@406
   480
                    print("  shape(%s): %d vertices, %d faces"%(shapeText[shape], len(exportVerts), len(exportFaces)))
lordcrc@384
   481
    
lordcrc@384
   482
    #-------------------------------------------------
lordcrc@384
   483
    # exportMeshes(self, file)
lordcrc@384
   484
    # exports meshes that uses instancing (meshes that are used by at least "instancing_threshold" objects)
lordcrc@384
   485
    #-------------------------------------------------
lordcrc@384
   486
    def exportMeshes(self, file):
lordcrc@384
   487
        scn = Scene.GetCurrent()
lordcrc@384
   488
        instancing_threshold = luxProp(scn, "instancing_threshold", 2).get()
lordcrc@384
   489
        mesh_optimizing = luxProp(scn, "mesh_optimizing", True).get()
lordcrc@384
   490
        mesh = Mesh.New('')
lordcrc@384
   491
        for (mesh_name, objs) in self.meshes.items():
lordcrc@384
   492
            allow_instancing = True
lordcrc@384
   493
            mats = getMaterials(objs[0]) # mats = obj.getData().getMaterials()
lordcrc@384
   494
            for mat in mats: # don't instance if one of the materials is emissive
lordcrc@384
   495
                if (mat!=None) and (luxProp(mat, "type", "").get()=="light"):
lordcrc@384
   496
                    allow_instancing = False
lordcrc@384
   497
            for obj in objs: # don't instance if the objects with same mesh uses different materials
lordcrc@384
   498
                ms = getMaterials(obj)
lordcrc@384
   499
                if ms != mats:
lordcrc@384
   500
                    allow_instancing = False
lordcrc@384
   501
            if obj.modifiers.__len__() > 0:
lordcrc@384
   502
                allow_instancing = False
lordcrc@384
   503
            if allow_instancing and (len(objs) > instancing_threshold):
lordcrc@384
   504
                del self.meshes[mesh_name]
lordcrc@384
   505
                mesh.getFromObject(objs[0], 0, 1)
lordcrc@384
   506
                print("blender-mesh: %s (%d vertices, %d faces)"%(mesh_name, len(mesh.verts), len(mesh.faces)))
lordcrc@384
   507
                file.write("ObjectBegin \"%s\"\n"%mesh_name)
tom@406
   508
lordcrc@384
   509
                if (mesh_optimizing):
lordcrc@384
   510
                    self.exportMeshOpt(file, mesh, mats, mesh_name)
lordcrc@384
   511
                else:
lordcrc@384
   512
                    self.exportMesh(file, mesh, mats, mesh_name)
lordcrc@384
   513
                file.write("ObjectEnd # %s\n\n"%mesh_name)
lordcrc@384
   514
        mesh.verts = None
lordcrc@384
   515
lordcrc@384
   516
    #-------------------------------------------------
lordcrc@384
   517
    # exportObjects(self, file)
lordcrc@384
   518
    # exports objects to the file
lordcrc@384
   519
    #-------------------------------------------------
lordcrc@384
   520
    def exportObjects(self, file):
lordcrc@384
   521
        scn = Scene.GetCurrent()
lordcrc@384
   522
        cam = scn.getCurrentCamera().data
lordcrc@384
   523
        objectmblur = luxProp(cam, "objectmblur", "true")
lordcrc@384
   524
        usemblur = luxProp(cam, "usemblur", "false")
lordcrc@384
   525
        mesh_optimizing = luxProp(scn, "mesh_optimizing", True).get()
lordcrc@384
   526
        mesh = Mesh.New('')
lordcrc@384
   527
        for [obj, matrix] in self.objects:
lordcrc@384
   528
            print("object: %s"%(obj.getName()))
lordcrc@384
   529
            mesh_name = obj.getData(name_only=True)
lordcrc@384
   530
lordcrc@384
   531
            motion = None
lordcrc@384
   532
            if(objectmblur.get() == "true" and usemblur.get() == "true"):
lordcrc@384
   533
                # motion blur
lordcrc@384
   534
                frame = Blender.Get('curframe')
lordcrc@384
   535
                Blender.Set('curframe', frame+1)
lordcrc@384
   536
                m1 = 1.0*matrix # multiply by 1.0 to get a copy of orignal matrix (will be frame-independant) 
lordcrc@384
   537
                Blender.Set('curframe', frame)
lordcrc@384
   538
                if m1 != matrix:
lordcrc@384
   539
                    print("  motion blur")
lordcrc@384
   540
                    motion = m1
lordcrc@384
   541
    
lordcrc@384
   542
            if motion: # motion-blur only works with instances, so ensure mesh is exported as instance first
lordcrc@384
   543
                if mesh_name in self.meshes:
lordcrc@384
   544
                    del self.meshes[mesh_name]
lordcrc@384
   545
                    mesh.getFromObject(obj, 0, 1)
lordcrc@384
   546
                    mats = getMaterials(obj)
lordcrc@384
   547
                    print("  blender-mesh: %s (%d vertices, %d faces)"%(mesh_name, len(mesh.verts), len(mesh.faces)))
lordcrc@384
   548
                    file.write("ObjectBegin \"%s\"\n"%mesh_name)
lordcrc@384
   549
                    if (mesh_optimizing):
lordcrc@384
   550
                        self.exportMeshOpt(file, mesh, mats, mesh_name)
lordcrc@384
   551
                    else:
lordcrc@384
   552
                        self.exportMesh(file, mesh, mats, mesh_name)
lordcrc@384
   553
                    file.write("ObjectEnd # %s\n\n"%mesh_name)
lordcrc@384
   554
lordcrc@384
   555
            file.write("AttributeBegin # %s\n"%obj.getName())
lordcrc@384
   556
            file.write("\tTransform [%s %s %s %s  %s %s %s %s  %s %s %s %s  %s %s %s %s]\n"\
lordcrc@384
   557
                %(matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3],\
lordcrc@384
   558
                  matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3],\
lordcrc@384
   559
                  matrix[2][0], matrix[2][1], matrix[2][2], matrix[2][3],\
lordcrc@384
   560
                    matrix[3][0], matrix[3][1], matrix[3][2], matrix[3][3]))
lordcrc@384
   561
            if motion:
lordcrc@384
   562
                file.write("\tTransformBegin\n")
lordcrc@384
   563
                file.write("\t\tIdentity\n")
lordcrc@384
   564
                file.write("\t\tTransform [%s %s %s %s  %s %s %s %s  %s %s %s %s  %s %s %s %s]\n"\
lordcrc@384
   565
                    %(motion[0][0], motion[0][1], motion[0][2], motion[0][3],\
lordcrc@384
   566
                      motion[1][0], motion[1][1], motion[1][2], motion[1][3],\
lordcrc@384
   567
                      motion[2][0], motion[2][1], motion[2][2], motion[2][3],\
lordcrc@384
   568
                        motion[3][0], motion[3][1], motion[3][2], motion[3][3]))
lordcrc@384
   569
                file.write("\t\tCoordinateSystem \"%s\"\n"%(obj.getName()+"_motion"))
lordcrc@384
   570
                file.write("\tTransformEnd\n")
lordcrc@384
   571
            if mesh_name in self.meshes:
lordcrc@384
   572
                mesh.getFromObject(obj, 0, 1)
lordcrc@384
   573
                mats = getMaterials(obj)
lordcrc@384
   574
                print("  blender-mesh: %s (%d vertices, %d faces)"%(mesh_name, len(mesh.verts), len(mesh.faces)))
lordcrc@384
   575
                if (mesh_optimizing):
lordcrc@384
   576
                    self.exportMeshOpt(file, mesh, mats, mesh_name)
lordcrc@384
   577
                else:
lordcrc@384
   578
                    self.exportMesh(file, mesh, mats, mesh_name)
lordcrc@384
   579
            else:
lordcrc@384
   580
                print("  instance %s"%(mesh_name))
lordcrc@384
   581
                if motion:
lordcrc@384
   582
                    file.write("\tMotionInstance \"%s\" 0.0 1.0 \"%s\"\n"%(mesh_name, obj.getName()+"_motion"))
lordcrc@384
   583
                else:
lordcrc@384
   584
                    file.write("\tObjectInstance \"%s\"\n"%mesh_name)
lordcrc@384
   585
            file.write("AttributeEnd\n\n")
lordcrc@384
   586
        mesh.verts = None
lordcrc@384
   587
lordcrc@384
   588
    #-------------------------------------------------
lordcrc@384
   589
    # exportPortals(self, file)
lordcrc@384
   590
    # exports portals objects to the file
lordcrc@384
   591
    #-------------------------------------------------
lordcrc@384
   592
    def exportPortals(self, file):
lordcrc@384
   593
        scn = Scene.GetCurrent()
lordcrc@384
   594
        mesh_optimizing = luxProp(scn, "mesh_optimizing", True).get()
lordcrc@384
   595
        mesh = Mesh.New('')
lordcrc@384
   596
        for [obj, matrix] in self.portals:
lordcrc@384
   597
            print("portal: %s"%(obj.getName()))
lordcrc@384
   598
            file.write("\tTransform [%s %s %s %s  %s %s %s %s  %s %s %s %s  %s %s %s %s]\n"\
lordcrc@384
   599
                %(matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3],\
lordcrc@384
   600
                  matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3],\
lordcrc@384
   601
                  matrix[2][0], matrix[2][1], matrix[2][2], matrix[2][3],\
lordcrc@384
   602
                    matrix[3][0], matrix[3][1], matrix[3][2], matrix[3][3]))
lordcrc@384
   603
            mesh_name = obj.getData(name_only=True)
lordcrc@384
   604
            mesh.getFromObject(obj, 0, 1)
lordcrc@384
   605
            mats = getMaterials(obj) # mats = obj.getData().getMaterials()
lordcrc@384
   606
            if (mesh_optimizing):
lordcrc@384
   607
                self.exportMeshOpt(file, mesh, mats, mesh_name, True)
lordcrc@384
   608
            else:
lordcrc@384
   609
                self.exportMesh(file, mesh, mats, mesh_name, True)
lordcrc@384
   610
        mesh.verts = None
lordcrc@384
   611
lordcrc@384
   612
    #-------------------------------------------------
lordcrc@384
   613
    # exportLights(self, file)
lordcrc@384
   614
    # exports lights to the file
lordcrc@384
   615
    #-------------------------------------------------
lordcrc@384
   616
    def exportLights(self, file):
lordcrc@384
   617
        for [obj, matrix] in self.lights:
lordcrc@384
   618
            ltype = obj.getData(mesh=1).getType() # data
lordcrc@384
   619
            if (ltype == Lamp.Types["Lamp"]) or (ltype == Lamp.Types["Spot"]) or (ltype == Lamp.Types["Area"]):
lordcrc@384
   620
                print("light: %s"%(obj.getName()))
lordcrc@384
   621
                if ltype == Lamp.Types["Area"]:
lordcrc@384
   622
                    (str, link) = luxLight("", "", obj, None, 0)
lordcrc@384
   623
                    file.write(str)
lordcrc@384
   624
                if ltype == Lamp.Types["Area"]: file.write("AttributeBegin # %s\n"%obj.getName())
lordcrc@384
   625
                else: file.write("TransformBegin # %s\n"%obj.getName())
lordcrc@384
   626
                file.write("\tTransform [%s %s %s %s  %s %s %s %s  %s %s %s %s  %s %s %s %s]\n"\
lordcrc@384
   627
                    %(matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3],\
lordcrc@384
   628
                      matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3],\
lordcrc@384
   629
                      matrix[2][0], matrix[2][1], matrix[2][2], matrix[2][3],\
lordcrc@384
   630
                        matrix[3][0], matrix[3][1], matrix[3][2], matrix[3][3]))
lordcrc@384
   631
                col = obj.getData(mesh=1).col # data
lordcrc@384
   632
                energy = obj.getData(mesh=1).energy # data
lordcrc@384
   633
                if ltype == Lamp.Types["Lamp"]:
lordcrc@384
   634
                    lightgroup = luxProp(obj, "light.lightgroup", "default")
lordcrc@384
   635
                    if luxProp(Scene.GetCurrent(), "nolg", "false").get()!="true":
lordcrc@384
   636
                        file.write("LightGroup \"%s\"\n"%lightgroup.get())
lordcrc@384
   637
                    (str, link) = luxLamp("", "", obj, None, 0)
lordcrc@384
   638
                    file.write(str+"LightSource \"point\""+link+"\n")
lordcrc@384
   639
                if ltype == Lamp.Types["Spot"]:
lordcrc@384
   640
                    (str, link) = luxSpot("", "", obj, None, 0)
lordcrc@384
   641
                    file.write(str)
lordcrc@384
   642
                    proj = luxProp(obj, "light.usetexproj", "false")
lordcrc@384
   643
                    if luxProp(Scene.GetCurrent(), "nolg", "false").get()!="true":
lordcrc@384
   644
                        lightgroup = luxProp(obj, "light.lightgroup", "default")
lordcrc@384
   645
                        file.write("LightGroup \"%s\"\n"%lightgroup.get())
lordcrc@384
   646
                    if(proj.get() == "true"):
lordcrc@384
   647
                        file.write("Rotate 180 0 1 0\n")
lordcrc@384
   648
                        file.write("LightSource \"projection\" \"float fov\" [%f]"%(obj.getData(mesh=1).spotSize))
lordcrc@384
   649
                    else:
lordcrc@384
   650
                        file.write("LightSource \"spot\" \"point from\" [0 0 0] \"point to\" [0 0 -1] \"float coneangle\" [%f] \"float conedeltaangle\" [%f]"\
lordcrc@384
   651
                            %(obj.getData(mesh=1).spotSize*0.5, obj.getData(mesh=1).spotSize*0.5*obj.getData(mesh=1).spotBlend)) # data
lordcrc@384
   652
                    file.write(link+"\n")
lordcrc@384
   653
                if ltype == Lamp.Types["Area"]:
lordcrc@384
   654
                    lightgroup = luxProp(obj, "light.lightgroup", "default")
lordcrc@384
   655
                    if luxProp(Scene.GetCurrent(), "nolg", "false").get()!="true":
lordcrc@384
   656
                        file.write("LightGroup \"%s\"\n"%lightgroup.get())
lordcrc@384
   657
                    file.write("\tAreaLightSource \"area\"")
lordcrc@384
   658
                    file.write(link)
lordcrc@384
   659
#                    file.write(luxLight("", "", obj, None, 0))
lordcrc@384
   660
                    file.write("\n")
lordcrc@384
   661
                    areax = obj.getData(mesh=1).getAreaSizeX()
lordcrc@384
   662
                    # lamps "getAreaShape()" not implemented yet - so we can't detect shape! Using square as default
lordcrc@384
   663
                    # todo: ideasman42
lordcrc@384
   664
                    if (True): areay = areax
lordcrc@384
   665
                    else: areay = obj.getData(mesh=1).getAreaSizeY()
lordcrc@384
   666
                    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})
lordcrc@384
   667
                if ltype == Lamp.Types["Area"]: file.write("AttributeEnd # %s\n"%obj.getName())
lordcrc@384
   668
                else: file.write("TransformEnd # %s\n"%obj.getName())
lordcrc@384
   669
                file.write("\n")
lordcrc@384
   670
lordcrc@384
   671
lordcrc@384
   672
    #-------------------------------------------------
lordcrc@384
   673
    # exportVolumes(self, file)
lordcrc@384
   674
    # exports volumes to the file
lordcrc@384
   675
    #-------------------------------------------------
lordcrc@384
   676
    def exportVolumes(self, file):
lordcrc@384
   677
        for [obj, matrix] in self.volumes:
lordcrc@384
   678
            print("volume: %s"%(obj.getName()))
lordcrc@384
   679
            file.write("# Volume: %s\n"%(obj.getName()))
lordcrc@384
   680
lordcrc@384
   681
            # trickery to obtain objectspace boundingbox AABB
lordcrc@384
   682
            mat = obj.matrixWorld.copy().invert()
lordcrc@384
   683
            bb = [vec * mat for vec in obj.getBoundBox()]
lordcrc@384
   684
            minx = miny = minz = 100000000000000.0
lordcrc@384
   685
            maxx = maxy = maxz = -100000000000000.0
lordcrc@384
   686
            for vec in bb:
lordcrc@384
   687
                if (vec[0] < minx): minx = vec[0]
lordcrc@384
   688
                if (vec[1] < miny): miny = vec[1]
lordcrc@384
   689
                if (vec[2] < minz): minz = vec[2]
lordcrc@384
   690
                if (vec[0] > maxx): maxx = vec[0]
lordcrc@384
   691
                if (vec[1] > maxy): maxy = vec[1]
lordcrc@384
   692
                if (vec[2] > maxz): maxz = vec[2]
lordcrc@384
   693
lordcrc@384
   694
            file.write("Transform [%s %s %s %s  %s %s %s %s  %s %s %s %s  %s %s %s %s]\n"\
lordcrc@384
   695
                %(matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3],\
lordcrc@384
   696
                  matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3],\
lordcrc@384
   697
                  matrix[2][0], matrix[2][1], matrix[2][2], matrix[2][3],\
lordcrc@384
   698
                    matrix[3][0], matrix[3][1], matrix[3][2], matrix[3][3]))
lordcrc@384
   699
lordcrc@384
   700
            str_opt = (" \"point p0\" [%f %f %f] \"point p1\" [%f %f %f]"%(minx, miny, minz, maxx, maxy, maxz))
lordcrc@384
   701
            mats = getMaterials(obj)
lordcrc@384
   702
            if (len(mats)>0) and (mats[0]!=None) and (luxProp(mats[0], "type", "").get()=="boundvolume"):
lordcrc@384
   703
                mat = mats[0]
lordcrc@384
   704
                (str, link) = luxMaterialBlock("", "", "", mat, None, 0, str_opt)
lordcrc@384
   705
                file.write("%s"%link)
lordcrc@384
   706
                file.write("\n\n")
lordcrc@384
   707
lordcrc@384
   708
lordcrc@384
   709
# Note - radiance - this is a work in progress
lordcrc@384
   710
def luxFlashBlock(camObj):
lordcrc@384
   711
    str = ""
lordcrc@384
   712
    str += "CoordSysTransform \"camera\"\n"
lordcrc@384
   713
lordcrc@384
   714
    str += "Texture \"camflashtex\" \"color\" \"blackbody\" \"float temperature\" [5500.0]"
lordcrc@384
   715
    str += "AreaLightSource \"area\" \"texture L\" [\"camflashtex\"] \"float power\" [100.000000] \"float efficacy\" [17.000000] \"float gain\" [1.000000]\n"
lordcrc@384
   716
lordcrc@384
   717
    up = 10.0
lordcrc@384
   718
lordcrc@384
   719
    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"
lordcrc@384
   720
lordcrc@384
   721
    return str
lordcrc@384
   722
lordcrc@384
   723
lordcrc@384
   724
######################################################
lordcrc@384
   725
# EXPORT
lordcrc@384
   726
######################################################
lordcrc@384
   727
lordcrc@384
   728
def save_lux(filename, unindexedname):
lordcrc@384
   729
    
lordcrc@384
   730
    export_total_steps = 12.0
lordcrc@384
   731
    
lordcrc@384
   732
    global meshlist, matnames, lxs_filename, geom_filename, geom_pfilename, mat_filename, mat_pfilename, vol_filename, vol_pfilename, LuxIsGUI
lordcrc@384
   733
lordcrc@384
   734
    global render_status_text
lordcrc@384
   735
    global render_status
lordcrc@384
   736
    render_status_text = 'Exporting...'
lordcrc@384
   737
    render_status = True
lordcrc@384
   738
lordcrc@384
   739
    print("Lux Render Export started...\n")
lordcrc@384
   740
    time1 = Blender.sys.time()
lordcrc@384
   741
    scn = Scene.GetCurrent()
lordcrc@384
   742
lordcrc@384
   743
    filepath = os.path.dirname(filename)
lordcrc@384
   744
    filebase = os.path.splitext(os.path.basename(filename))[0]
lordcrc@384
   745
lordcrc@384
   746
    lxs_filename = filename
lordcrc@384
   747
lordcrc@384
   748
    geom_filename = os.path.join(filepath, filebase + "-geom.lxo")
lordcrc@384
   749
    geom_pfilename = filebase + "-geom.lxo"
lordcrc@384
   750
lordcrc@384
   751
    mat_filename = os.path.join(filepath, filebase + "-mat.lxm")
lordcrc@384
   752
    mat_pfilename = filebase + "-mat.lxm"
lordcrc@384
   753
    
lordcrc@384
   754
    vol_filename = os.path.join(filepath, filebase + "-vol.lxv")
lordcrc@384
   755
    vol_pfilename = filebase + "-vol.lxv"
lordcrc@384
   756
lordcrc@384
   757
    ### Zuegs: initialization for export class
lordcrc@384
   758
    export = luxExport(Blender.Scene.GetCurrent())
lordcrc@384
   759
lordcrc@384
   760
    # check if a light is present
lordcrc@384
   761
    envtype = luxProp(scn, "env.type", "infinite").get()
lordcrc@384
   762
    if envtype == "sunsky":
lordcrc@384
   763
        sun = None
lordcrc@384
   764
        for obj in scn.objects:
lordcrc@384
   765
            if (obj.getType() == "Lamp") and ((obj.Layers & scn.Layers) > 0):
lordcrc@384
   766
                if obj.getData(mesh=1).getType() == 1: # sun object # data
lordcrc@384
   767
                    sun = obj
lordcrc@384
   768
    if not(export.analyseScene()) and not(envtype == "infinite") and not((envtype == "sunsky") and (sun != None)):
lordcrc@384
   769
        print("ERROR: No light source found")
lordcrc@384
   770
        Draw.PupMenu("ERROR: No light source found%t|OK%x1")
jeanphi@391
   771
        render_status_text = ''
jeanphi@391
   772
        render_status = False
jeanphi@391
   773
        Blender.Window.QRedrawAll()
jeanphi@391
   774
        del export
lordcrc@384
   775
        return False
lordcrc@384
   776
lordcrc@384
   777
    if LuxIsGUI: DrawProgressBar(0.0/export_total_steps,'Setting up Scene file')
lordcrc@384
   778
    
lordcrc@384
   779
    class output_proxy():
lordcrc@384
   780
        load_result = False
lordcrc@384
   781
        combine_all_output = False
lordcrc@384
   782
        f = None
lordcrc@384
   783
        def close(self):
lordcrc@384
   784
            if self.f is not None: self.f.close()
lordcrc@384
   785
        def write(self, str):
lordcrc@384
   786
            if self.f is not None:
lordcrc@384
   787
                self.f.write(str)
lordcrc@384
   788
                self.f.flush()
lordcrc@384
   789
            
lordcrc@384
   790
    class file_output(output_proxy):
lordcrc@384
   791
        def __init__(self,filename):
lordcrc@384
   792
            self.f = open(filename, "w")
lordcrc@384
   793
            
lordcrc@384
   794
    from threading import Thread
lordcrc@384
   795
    class pipe_output(output_proxy, Thread):
lordcrc@384
   796
        combine_all_output = True
lordcrc@384
   797
        
lordcrc@384
   798
        def __init__(self, xr,yr, haltspp, filename):
lordcrc@384
   799
            Thread.__init__(self)
lordcrc@384
   800
            
lordcrc@384
   801
            self.filename = filename
lordcrc@384
   802
            self.haltspp = haltspp
lordcrc@384
   803
            self.xr = xr
lordcrc@384
   804
            self.yr = yr
lordcrc@384
   805
            
lordcrc@384
   806
            if self.haltspp > 0:
lordcrc@384
   807
                bintype = "luxconsole"
lordcrc@384
   808
                self.load_result = True
lordcrc@384
   809
            else:
lordcrc@384
   810
                bintype = "luxrender"
lordcrc@384
   811
               
lordcrc@384
   812
            print("pipe: using %s" % bintype)
lordcrc@384
   813
                
lordcrc@384
   814
            self.p = get_lux_pipe(scn, 1, bintype)
lordcrc@384
   815
            self.f = self.p.stdin
lordcrc@384
   816
        def close(self):
lordcrc@384
   817
            global render_status_text
lordcrc@384
   818
            global render_status
lordcrc@384
   819
            render_status = True
lordcrc@384
   820
            render_status_text = "Rendering ..."
lordcrc@384
   821
            Blender.Window.QRedrawAll()
lordcrc@384
   822
            self.start()
lordcrc@384
   823
        
lordcrc@384
   824
        def run(self):
lordcrc@384
   825
            if self.load_result: self.data = self.p.communicate()[0]
lordcrc@384
   826
            self.f.close()
tom@397
   827
            if self.load_result: # self.load_image()
tom@397
   828
                self.load_data()
lordcrc@384
   829
            print("LuxRender process finished")
lordcrc@384
   830
            self.update_status()
lordcrc@384
   831
            
lordcrc@384
   832
        def load_image(self):
lordcrc@384
   833
            i = Blender.Image.Load(self.filename)
lordcrc@384
   834
            i.makeCurrent()
lordcrc@384
   835
            i.reload()
lordcrc@384
   836
           
lordcrc@384
   837
        def load_data(self):
lordcrc@384
   838
            print("processing %i image bytes" % len(self.data))
lordcrc@384
   839
            i = Blender.Image.New('luxrender', self.xr, self.yr, 32)
lordcrc@384
   840
            raw_image = []
lordcrc@384
   841
            for j in self.data:
lordcrc@384
   842
                raw_image.append(ord(j))
lordcrc@384
   843
            del self.data
lordcrc@384
   844
            bi = 0
lordcrc@384
   845
            for y in range(self.yr-1, -1, -1):
lordcrc@384
   846
                for x in range(0, self.xr):
lordcrc@384
   847
                    i.setPixelI(x,y, raw_image[bi:bi+3]+[0])
lordcrc@384
   848
                    bi+=3
lordcrc@384
   849
            i.makeCurrent()
lordcrc@384
   850
            
lordcrc@384
   851
        def update_status(self):
lordcrc@384
   852
            global render_status_text
lordcrc@384
   853
            global render_status
lordcrc@384
   854
            render_status = False
lordcrc@384
   855
            render_status_text = "Rendering complete"
lordcrc@384
   856
            if self.haltspp>0: render_status_text += ", check Image Editor window"
lordcrc@384
   857
            Blender.Window.QRedrawAll()
lordcrc@384
   858
            
lordcrc@384
   859
    use_pipe_output = luxProp(scn, "pipe", "false").get() == "true" and luxProp(scn, "run", "true").get() == "true"
lordcrc@384
   860
    
lordcrc@384
   861
    file = output_proxy()
lordcrc@384
   862
    
lordcrc@384
   863
    if luxProp(scn, "lxs", "true").get()=="true" or use_pipe_output:
lordcrc@384
   864
        ##### Determine/open files
lordcrc@384
   865
        if use_pipe_output:
lordcrc@384
   866
            print("using pipe output")
lordcrc@384
   867
            print("Exporting scene to pipe")
lordcrc@384
   868
            xr,yr = get_render_resolution(scn)
lordcrc@384
   869
            file = pipe_output(xr, yr,
lordcrc@384
   870
                luxProp(scn, "haltspp", 0).get(),
lordcrc@384
   871
                os.path.join(filepath, filebase + ".png")
lordcrc@384
   872
            )
lordcrc@384
   873
        else:
lordcrc@384
   874
            print("using file output")
lordcrc@384
   875
            print("Exporting scene to '" + filename + "'...\n")
lordcrc@384
   876
            file = file_output(filename)
lordcrc@384
   877
lordcrc@384
   878
        ##### Write Header ######
jensverwiebe@414
   879
        file.write("# Lux Render v0.6 Scene File\n")
lordcrc@384
   880
        file.write("# Exported by LuxBlend Blender Exporter\n")
lordcrc@384
   881
        file.write("\n")
lordcrc@384
   882
    
lordcrc@384
   883
        ##### Write camera ######
lordcrc@384
   884
        camObj = scn.getCurrentCamera()
lordcrc@384
   885
lordcrc@384
   886
        if LuxIsGUI: DrawProgressBar(1.0/export_total_steps,'Exporting Camera')
lordcrc@384
   887
        if camObj:
lordcrc@384
   888
            print("processing Camera...")
lordcrc@384
   889
            cam = camObj.data
lordcrc@384
   890
            cammblur = luxProp(cam, "cammblur", "true")
lordcrc@384
   891
            usemblur = luxProp(cam, "usemblur", "false")
lordcrc@384
   892
lordcrc@384
   893
            matrix = camObj.getMatrix()
lordcrc@384
   894
lordcrc@384
   895
            motion = None
lordcrc@384
   896
            if(cammblur.get() == "true" and usemblur.get() == "true"):
lordcrc@384
   897
                # motion blur
lordcrc@384
   898
                frame = Blender.Get('curframe')
lordcrc@384
   899
                Blender.Set('curframe', frame+1)
lordcrc@384
   900
                m1 = 1.0*matrix # multiply by 1.0 to get a copy of original matrix (will be frame-independant) 
lordcrc@384
   901
                Blender.Set('curframe', frame)
lordcrc@384
   902
                if m1 != matrix:
lordcrc@384
   903
                    # Motion detected, write endtransform
lordcrc@384
   904
                    print("  motion blur")
lordcrc@384
   905
                    motion = m1
lordcrc@384
   906
                    pos = m1[3]
lordcrc@384
   907
                    forwards = -m1[2]
lordcrc@384
   908
                    target = pos + forwards
lordcrc@384
   909
                    up = m1[1]
lordcrc@384
   910
                    file.write("TransformBegin\n")
lordcrc@384
   911
                    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] ))
lordcrc@384
   912
                    file.write("   CoordinateSystem \"CameraEndTransform\"\n")
lordcrc@384
   913
                    file.write("TransformEnd\n\n")
lordcrc@384
   914
lordcrc@384
   915
            # Write original lookat transform
lordcrc@384
   916
            pos = matrix[3]
lordcrc@384
   917
            forwards = -matrix[2]
lordcrc@384
   918
            target = pos + forwards
lordcrc@384
   919
            up = matrix[1]
lordcrc@384
   920
            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] ))
lordcrc@384
   921
            file.write(luxCamera(camObj.data, scn.getRenderingContext()))
lordcrc@384
   922
            if motion:
lordcrc@384
   923
                file.write("\n   \"string endtransform\" [\"CameraEndTransform\"]")
lordcrc@384
   924
            file.write("\n")
lordcrc@384
   925
        file.write("\n")
lordcrc@384
   926
    
lordcrc@384
   927
        if LuxIsGUI: DrawProgressBar(2.0/export_total_steps,'Exporting Film Settings')
lordcrc@384
   928
        ##### Write film ######
lordcrc@384
   929
        file.write(luxFilm(scn))
lordcrc@384
   930
        file.write("\n")
lordcrc@384
   931
lordcrc@384
   932
        if LuxIsGUI: DrawProgressBar(3.0/export_total_steps,'Exporting Pixel Filter')
lordcrc@384
   933
        ##### Write Pixel Filter ######
lordcrc@384
   934
        file.write(luxPixelFilter(scn))
lordcrc@384
   935
        file.write("\n")
lordcrc@384
   936
    
lordcrc@384
   937
        if LuxIsGUI: DrawProgressBar(4.0/export_total_steps,'Exporting Sampler')
lordcrc@384
   938
        ##### Write Sampler ######
lordcrc@384
   939
        file.write(luxSampler(scn))
lordcrc@384
   940
        file.write("\n")
lordcrc@384
   941
    
lordcrc@384
   942
        if LuxIsGUI: DrawProgressBar(5.0/export_total_steps,'Exporting Surface Integrator')
lordcrc@384
   943
        ##### Write Surface Integrator ######
lordcrc@384
   944
        file.write(luxSurfaceIntegrator(scn))
lordcrc@384
   945
        file.write("\n")
lordcrc@384
   946
        
lordcrc@384
   947
        if LuxIsGUI: DrawProgressBar(6.0/export_total_steps,'Exporting Volume Integrator')
lordcrc@384
   948
        ##### Write Volume Integrator ######
lordcrc@384
   949
        file.write(luxVolumeIntegrator(scn))
lordcrc@384
   950
        file.write("\n")
lordcrc@384
   951
        
lordcrc@384
   952
        if LuxIsGUI: DrawProgressBar(7.0/export_total_steps,'Exporting Accelerator')
lordcrc@384
   953
        ##### Write Acceleration ######
lordcrc@384
   954
        file.write(luxAccelerator(scn))
lordcrc@384
   955
        file.write("\n")    
lordcrc@384
   956
    
lordcrc@384
   957
        ########## BEGIN World
lordcrc@384
   958
        file.write("\n")
lordcrc@384
   959
        file.write("WorldBegin\n")
lordcrc@384
   960
        file.write("\n")
lordcrc@384
   961
lordcrc@384
   962
        ########## World scale
lordcrc@384
   963
        #scale = luxProp(scn, "global.scale", 1.0).get()
lordcrc@384
   964
        #if scale != 1.0:
lordcrc@384
   965
        #    # TODO: not working yet !!!
lordcrc@384
   966
        #    # TODO: propabily scale needs to be applyed on camera coords too 
lordcrc@384
   967
        #    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))
lordcrc@384
   968
        #    file.write("\n")
lordcrc@384
   969
        
lordcrc@384
   970
        if LuxIsGUI: DrawProgressBar(8.0/export_total_steps,'Exporting Environment')
lordcrc@384
   971
        ##### Write World Background, Sunsky or Env map ######
lordcrc@384
   972
        env = luxEnvironment(scn)
lordcrc@384
   973
        if env != "":
lordcrc@384
   974
            file.write("AttributeBegin\n")
lordcrc@384
   975
            file.write(env)
lordcrc@384
   976
            export.exportPortals(file)
lordcrc@384
   977
            file.write("AttributeEnd\n")
lordcrc@384
   978
            file.write("\n")    
lordcrc@384
   979
lordcrc@384
   980
    # Note - radiance - this is a work in progress
lordcrc@384
   981
#        flash = luxFlashBlock(camObj)
lordcrc@384
   982
#        if flash != "":
lordcrc@384
   983
#            file.write("# Camera flash lamp\n")
lordcrc@384
   984
#            file.write("AttributeBegin\n")
lordcrc@384
   985
#            #file.write("CoordSysTransform \"camera\"\n")
lordcrc@384
   986
#            file.write(flash)
lordcrc@384
   987
#            file.write("AttributeEnd\n\n")
lordcrc@384
   988
lordcrc@384
   989
        #### Write material & geometry file includes in scene file
lordcrc@384
   990
        if not file.combine_all_output: file.write("Include \"%s\"\n\n" %(mat_pfilename))
lordcrc@384
   991
        if not file.combine_all_output: file.write("Include \"%s\"\n\n" %(geom_pfilename))
lordcrc@384
   992
        if not file.combine_all_output: file.write("Include \"%s\"\n\n" %(vol_pfilename))
lordcrc@384
   993
        
lordcrc@384
   994
    if luxProp(scn, "lxm", "true").get()=="true" or use_pipe_output:
lordcrc@384
   995
        if LuxIsGUI: DrawProgressBar(9.0/export_total_steps,'Exporting Materials')
lordcrc@384
   996
        ##### Write Material file #####
lordcrc@384
   997
        if not file.combine_all_output: print("Exporting materials to '" + mat_filename + "'...\n")
lordcrc@384
   998
        mat_file = open(mat_filename, 'w') if not file.combine_all_output else file
lordcrc@384
   999
        mat_file.write("")
lordcrc@384
  1000
        export.exportMaterials(mat_file)
lordcrc@384
  1001
        mat_file.write("")
lordcrc@384
  1002
        if not file.combine_all_output: mat_file.close()
lordcrc@384
  1003
    
lordcrc@384
  1004
    if luxProp(scn, "lxo", "true").get()=="true" or use_pipe_output:
lordcrc@384
  1005
        if LuxIsGUI: DrawProgressBar(10.0/export_total_steps,'Exporting Geometry')
lordcrc@384
  1006
        ##### Write Geometry file #####
lordcrc@384
  1007
        if not file.combine_all_output: print("Exporting geometry to '" + geom_filename + "'...\n")
lordcrc@384
  1008
        geom_file = open(geom_filename, 'w') if not file.combine_all_output else file
lordcrc@384
  1009
        meshlist = []
lordcrc@384
  1010
        geom_file.write("")
lordcrc@384
  1011
        export.exportLights(geom_file)
lordcrc@384
  1012
        export.exportMeshes(geom_file)
lordcrc@384
  1013
        export.exportObjects(geom_file)
lordcrc@384
  1014
        geom_file.write("")
lordcrc@384
  1015
        if not file.combine_all_output: geom_file.close()
lordcrc@384
  1016
lordcrc@384
  1017
    if luxProp(scn, "lxv", "true").get()=="true" or use_pipe_output:
lordcrc@384
  1018
        if LuxIsGUI: DrawProgressBar(11.0/export_total_steps,'Exporting Volumes')
lordcrc@384
  1019
        ##### Write Volume file #####
lordcrc@384
  1020
        if not file.combine_all_output: print("Exporting volumes to '" + vol_filename + "'...\n")
lordcrc@384
  1021
        vol_file = open(vol_filename, 'w') if not file.combine_all_output else file
lordcrc@384
  1022
        meshlist = []
lordcrc@384
  1023
        vol_file.write("")
lordcrc@384
  1024
        export.exportVolumes(vol_file)
lordcrc@384
  1025
        vol_file.write("")
lordcrc@384
  1026
        if not file.combine_all_output: vol_file.close()
lordcrc@384
  1027
lordcrc@384
  1028
    render_status_text = ''
lordcrc@384
  1029
    render_status = False
lordcrc@384
  1030
    Blender.Window.QRedrawAll()
lordcrc@384
  1031
lordcrc@384
  1032
    if luxProp(scn, "lxs", "true").get()=="true" or use_pipe_output:
lordcrc@384
  1033
        #### Write End Tag
lordcrc@384
  1034
        file.write("WorldEnd\n\n")
lordcrc@384
  1035
        file.close()
lordcrc@384
  1036
lordcrc@384
  1037
    if LuxIsGUI: DrawProgressBar(12.0/export_total_steps,'Export Finished')
lordcrc@384
  1038
    print("Finished.\n")
lordcrc@384
  1039
    del export
lordcrc@384
  1040
    
lordcrc@384
  1041
    time2 = Blender.sys.time()
lordcrc@384
  1042
    print("Processing time: %f\n" %(time2-time1))
tom@397
  1043
tom@397
  1044
    if use_pipe_output:
doug@403
  1045
        #if luxProp(scn, "haltspp", 0).get() > 0:
tom@397
  1046
            # Wait for piped luxconsole render thread to end
doug@403
  1047
        file.join()
tom@397
  1048
tom@397
  1049
        # Don't launch it again as a piped scene is started implicitly
tom@397
  1050
        return False
tom@397
  1051
lordcrc@384
  1052
    return True
lordcrc@384
  1053
lordcrc@384
  1054
########################################################################
lordcrc@384
  1055
####  Construct server string argument
lordcrc@384
  1056
########################################################################
lordcrc@384
  1057
lordcrc@384
  1058
def networkstring(scn):
lordcrc@384
  1059
    servers_string = ""
lordcrc@384
  1060
    if  (luxProp(scn,"network","false").get() == "true"):
lordcrc@384
  1061
        if (luxProp(scn,"network_use_file","false").get() == "true"):
lordcrc@384
  1062
            print("read network servers from file: "+ luxProp(scn,"network_file_path","false").get())
lordcrc@384
  1063
            f = open(luxProp(scn,"network_file_path","false").get())
lordcrc@384
  1064
            for s in f:
lordcrc@384
  1065
                s = s.strip("\n")
lordcrc@384
  1066
                print("add server :" + s)
lordcrc@384
  1067
                servers_string=servers_string+" -u "+ s
lordcrc@384
  1068
            f.close
lordcrc@384
  1069
        else : 
lordcrc@384
  1070
             if  luxProp(scn,"network_servers","").get():
lordcrc@384
  1071
                 for server in luxProp(scn,"network_servers","").get().split(","):
lordcrc@384
  1072
                    servers_string=servers_string+" -u "+ server
lordcrc@384
  1073
    return servers_string
lordcrc@384
  1074
lordcrc@384
  1075
lordcrc@384
  1076
#########################################################################
lordcrc@384
  1077
###     LAUNCH LuxRender AND RENDER CURRENT SCENE
lordcrc@384
  1078
#########################################################################
lordcrc@384
  1079
lordcrc@384
  1080
def get_lux_exec(scn, type="luxrender"):
lordcrc@384
  1081
    
lordcrc@384
  1082
    #get blenders 'bpydata' directory
lordcrc@384
  1083
    datadir=Blender.Get("datadir")
lordcrc@384
  1084
    
lordcrc@384
  1085
    ic = luxProp(scn, "lux", "").get()
lordcrc@384
  1086
    ic = Blender.sys.dirname(ic) + os.sep + type
lordcrc@384
  1087
    
lordcrc@384
  1088
    if osys.platform == "win32": ic = ic + ".exe"
lordcrc@384
  1089
    
lordcrc@384
  1090
    if type=="luxrender" and osys.platform == "darwin": ic = ic + ".app/Contents/MacOS/luxrender"
lordcrc@384
  1091
    
lordcrc@384
  1092
    return ic
lordcrc@384
  1093
    
tom@396
  1094
def get_lux_args(filename, extra_args=[], anim=False):
lordcrc@384
  1095
    ostype = osys.platform
lordcrc@384
  1096
    scn = Scene.GetCurrent()
tom@396
  1097
    
tom@396
  1098
    ic = get_lux_exec(scn, type=(anim and 'luxconsole' or 'luxrender'))
lordcrc@384
  1099
    
lordcrc@384
  1100
    servers_string = networkstring(scn)
lordcrc@384
  1101
    update_int=luxProp(scn,"newtork_interval",180).get()
lordcrc@384
  1102
    
lordcrc@384
  1103
    checkluxpath = luxProp(scn, "checkluxpath", True).get()
lordcrc@384
  1104
    if checkluxpath:
lordcrc@384
  1105
        if sys.exists(ic) != 1:
lordcrc@384
  1106
            Draw.PupMenu("Error: Lux renderer not found. Please set path on System page.%t|OK")
lordcrc@384
  1107
            return
lordcrc@384
  1108
    autothreads = luxProp(scn, "autothreads", "true").get()
lordcrc@384
  1109
    threads = luxProp(scn, "threads", 1).get()
lordcrc@384
  1110
    luxnice = luxProp(scn, "luxnice", 0).get()
lordcrc@384
  1111
    noopengl = luxProp(scn, "noopengl", "false").get()
lordcrc@384
  1112
    
lordcrc@384
  1113
    if noopengl == "true":
lordcrc@384
  1114
        extra_args.append("--noopengl")
lordcrc@384
  1115
    
lordcrc@384
  1116
    lux_args = "\"%s\" " % ic
lordcrc@384
  1117
    
lordcrc@384
  1118
    extra_args.append('%s'%servers_string)
lordcrc@384
  1119
    extra_args.append("-i %d " % update_int)
lordcrc@384
  1120
    
lordcrc@384
  1121
    if autothreads != "true":
lordcrc@384
  1122
        extra_args.append("--threads=%d " % threads)
lordcrc@384
  1123
    
lordcrc@384
  1124
    lux_args2 = ' '.join(extra_args)
lordcrc@384
  1125
    
lordcrc@384
  1126
    if filename == '-':
lordcrc@384
  1127
        lux_args2 = " - " + lux_args2
lordcrc@384
  1128
    else:
lordcrc@384
  1129
        filename = "\"%s\"" % filename
lordcrc@384
  1130
        lux_args2 = lux_args2 + filename
lordcrc@384
  1131
        
lordcrc@384
  1132
    lux_args += lux_args2
lordcrc@384
  1133
    
lordcrc@384
  1134
    if ostype == "win32":
lordcrc@384
  1135
        prio = ""
lordcrc@384
  1136
        if luxnice > 15: prio = "/low"
lordcrc@384
  1137
        elif luxnice > 5: prio = "/belownormal"
lordcrc@384
  1138
        elif luxnice > -5: prio = "/normal"
lordcrc@384
  1139
        elif luxnice > -15: prio = "/abovenormal"
lordcrc@384
  1140
        else: prio = "/high"
lordcrc@384
  1141
        
doug@401
  1142
        if not anim:
doug@401
  1143
            cmd = "start /b %s \"\" %s" % (prio, lux_args)
doug@401
  1144
        else:
doug@401
  1145
            cmd = "start /WAIT %s \"\" %s" % (prio, lux_args)
lordcrc@384
  1146
        
jensverwiebe@394
  1147
#    if ostype == "linux2" or ostype == "darwin":
jensverwiebe@394
  1148
    else:
tom@396
  1149
        if not anim:
tom@396
  1150
            cmd = "(nice -n %d %s)&"%(luxnice, lux_args)
tom@396
  1151
        else:
tom@396
  1152
            cmd = "(nice -n %d %s)"%(luxnice, lux_args)
lordcrc@384
  1153
    
lordcrc@384
  1154
    return cmd, lux_args2
lordcrc@384
  1155
lordcrc@384
  1156
def get_lux_pipe(scn, buf = 1024, type="luxconsole"):
lordcrc@384
  1157
    bin = "\"%s\"" % get_lux_exec(scn, type)
lordcrc@384
  1158
    
lordcrc@384
  1159
    print("piping to lux binary: " + bin)
lordcrc@384
  1160
    
lordcrc@384
  1161
    PIPE = subprocess.PIPE
lordcrc@384
  1162
    
lordcrc@384
  1163
    cmd, raw_args = get_lux_args('-',
lordcrc@384
  1164
        extra_args=['-b'] if type=="luxconsole" else []
lordcrc@384
  1165
    )
lordcrc@384
  1166
    
lordcrc@384
  1167
    return subprocess.Popen(bin + raw_args, shell=True, bufsize=buf, stdin=PIPE, stdout=PIPE, stderr=PIPE)
lordcrc@384
  1168
lordcrc@384
  1169
def launchLux(filename):
lordcrc@384
  1170
    cmd, raw_args = get_lux_args(filename, extra_args=[])
lordcrc@384
  1171
    print("Running Luxrender:\n"+cmd)
lordcrc@384
  1172
    os.system(cmd)
lordcrc@384
  1173
tom@396
  1174
def launchLuxWait(filename, anim=False):
jensverwiebe@393
  1175
    ostype = osys.platform
tom@396
  1176
    cmd, raw_args = get_lux_args(filename, extra_args=[], anim=anim)
lordcrc@384
  1177
    
lordcrc@384
  1178
    if ostype == "win32":
lordcrc@384
  1179
        os.system(cmd)
lordcrc@384
  1180
    
jensverwiebe@394
  1181
#    if ostype == "linux2" or ostype == "darwin":
jensverwiebe@394
  1182
    else:
lordcrc@384
  1183
        subprocess.call(cmd,shell=True)
lordcrc@384
  1184
doug@402
  1185
#### SAVE ANIMATION ####
doug@402
  1186
doug@402
  1187
doug@404
  1188
#def save_anim(filename):
doug@404
  1189
#    global LuxIsGUI
doug@404
  1190
#    scn = Scene.GetCurrent()
doug@404
  1191
#    to = luxProp(scn, 'export.threaded', 'true').get()
doug@404
  1192
#    run = luxProp(scn, "run", "true").get()
doug@404
  1193
#    deflt = luxProp(scn, "default", "true").get()
doug@404
  1194
#    if to == 'true' and run == 'true' and deflt == 'false':
doug@404
  1195
#        import threading
doug@404
  1196
#        anim_thread = threading.Thread(target=save_anim_real, args=(filename,True))
doug@404
  1197
#        anim_thread.start()
doug@404
  1198
#    else:
doug@404
  1199
#        save_anim_real(filename)
doug@404
  1200
doug@404
  1201
def save_anim(filename, as_thread=False):
doug@403
  1202
    if as_thread: print('SAR thread started')
doug@403
  1203
    global MatSaved, LuxIsGUI
lordcrc@384
  1204
    
lordcrc@384
  1205
    MatSaved = 0
lordcrc@384
  1206
    startF = Blender.Get('staframe')
lordcrc@384
  1207
    endF = Blender.Get('endframe')
lordcrc@384
  1208
    scn = Scene.GetCurrent()
lordcrc@384
  1209
lordcrc@384
  1210
    Run = luxProp(scn, "run", "true").get()
lordcrc@384
  1211
tom@397
  1212
    if Run == "true":
tom@397
  1213
        haltspp = luxProp(scn, "haltspp", 0).get()
tom@397
  1214
        if haltspp == 0:
tom@397
  1215
            Draw.PupMenu("ERROR: You must set a limit for spp (Output->halt) when doing animation and the 'run' flag is switched on")
tom@397
  1216
            if LuxIsGUI:
tom@397
  1217
                Draw.Redraw()
tom@397
  1218
            return
tom@397
  1219
lordcrc@384
  1220
    print("\n\nRendering animation (frame %i to %i)\n\n"%(startF, endF))
lordcrc@384
  1221
doug@403
  1222
    v_frame = Blender.Get('curframe')
doug@403
  1223
lordcrc@384
  1224
    for i in range (startF, endF+1):
doug@403
  1225
        # Seems to get stuck unless we redraw the UI
doug@404
  1226
#        if LuxIsGUI:
doug@404
  1227
#            Window.QRedrawAll()
lordcrc@384
  1228
        Blender.Set('curframe', i)
lordcrc@384
  1229
        print("Rendering frame %i"%(i))
lordcrc@384
  1230
        Blender.Redraw()
lordcrc@384
  1231
        frameindex = ("-%05d" % (i)) + ".lxs"
lordcrc@384
  1232
        indexedname = sys.makename(filename, frameindex)
lordcrc@384
  1233
        unindexedname = filename
lordcrc@384
  1234
        luxProp(scn, "filename", Blender.Get("filename")).set(sys.makename(filename, "-%05d" %  (Blender.Get('curframe'))))
lordcrc@384
  1235
lordcrc@384
  1236
        if Run == "true":
lordcrc@384
  1237
            if save_lux(filename, unindexedname):
tom@396
  1238
                launchLuxWait(filename, anim=True)
lordcrc@384
  1239
        else:
lordcrc@384
  1240
            save_lux(indexedname, unindexedname)
lordcrc@384
  1241
lordcrc@384
  1242
        MatSaved = 1
doug@403
  1243
        # Seems to get stuck unless we redraw the UI
doug@404
  1244
#        if LuxIsGUI:
doug@404
  1245
#            Window.QRedrawAll()
doug@403
  1246
            
doug@403
  1247
    Blender.Set('curframe', v_frame)
lordcrc@384
  1248
lordcrc@384
  1249
    print("\n\nFinished Rendering animation\n")
doug@403
  1250
    if as_thread: print('SAR thread finished')
lordcrc@384
  1251
lordcrc@384
  1252
#### SAVE STILL (hackish...) ####
doug@402
  1253
doug@404
  1254
#import threading
doug@404
  1255
#def save_still(filename):
doug@404
  1256
#    global LuxIsGUI
doug@404
  1257
#    scn = Scene.GetCurrent()
doug@404
  1258
#    to = luxProp(scn, 'export.threaded', 'true').get()
doug@404
  1259
#    if to == 'true' and luxProp(scn, "run", "true").get() == "true":
doug@404
  1260
#        import threading
doug@404
  1261
#        still_thread = threading.Thread(target=save_still_real, args=(filename,))
doug@404
  1262
#        still_thread.start()
doug@404
  1263
#    else:
doug@404
  1264
#        save_still_real(filename)
doug@404
  1265
lordcrc@384
  1266
def save_still(filename):
doug@403
  1267
    global MatSaved, runRenderAfterExport
lordcrc@384
  1268
    scn = Scene.GetCurrent()
lordcrc@384
  1269
    luxProp(scn, "filename", Blender.Get("filename")).set(sys.makename(filename, ""))
lordcrc@384
  1270
    MatSaved = 0
lordcrc@384
  1271
    unindexedname = filename
doug@403
  1272
    # Seems to get stuck unless we redraw the UI
doug@404
  1273
#    if LuxIsGUI:
doug@404
  1274
#        Window.QRedrawAll()
lordcrc@384
  1275
    if save_lux(filename, unindexedname):
lordcrc@384
  1276
        if runRenderAfterExport and luxProp(scn, "pipe", "false").get() == "false": #(run == None and luxProp(scn, "run", "true").get() == "true") or run:
lordcrc@384
  1277
            launchLux(filename)
doug@403
  1278
            
doug@403
  1279
    # Seems to get stuck unless we redraw the UI
doug@404
  1280
#    if LuxIsGUI:
doug@404
  1281
#        Window.QRedrawAll()
lordcrc@384
  1282
lordcrc@384
  1283
lordcrc@384
  1284
######################################################
lordcrc@384
  1285
# Icons
lordcrc@384
  1286
######################################################
lordcrc@384
  1287
lordcrc@384
  1288
def base64value(char):
lordcrc@384
  1289
    if 64 < ord(char) < 91: return ord(char)-65
lordcrc@384
  1290
    if 96 < ord(char) < 123: return ord(char)-97+26
lordcrc@384
  1291
    if 47 < ord(char) < 58: return ord(char)-48+52
lordcrc@384
  1292
    if char == '+': return 62
lordcrc@384
  1293
    return 63
lordcrc@384
  1294
lordcrc@384
  1295
def decodeIconStr(s):
lordcrc@384
  1296
    buf = BGL.Buffer(BGL.GL_BYTE, [16,16,4])
lordcrc@384
  1297
    offset = 0
lordcrc@384
  1298
    for y in range(16):
lordcrc@384
  1299
        for x in range(16):
lordcrc@384
  1300
            for c in range(4):
lordcrc@384
  1301
                buf[y][x][c] = int(base64value(s[offset])*4.048)
lordcrc@384
  1302
                offset += 1
lordcrc@384
  1303
    return buf
lordcrc@384
  1304
lordcrc@384
  1305
def decodeLogoStr(s):
lordcrc@384
  1306
    buf = BGL.Buffer(BGL.GL_BYTE, [18,118,4])
lordcrc@384
  1307
    offset = 0
lordcrc@384
  1308
    for y in range(18):
lordcrc@384
  1309
        for x in range(118):
lordcrc@384
  1310
            for c in range(4):
lordcrc@384
  1311
                buf[y][x][c] = int(base64value(s[offset])*4.048)
lordcrc@384
  1312
                offset += 1
lordcrc@384
  1313
    return buf
lordcrc@384
  1314
lordcrc@384
  1315
def decodeArrowStr(s):
lordcrc@384
  1316
    buf = BGL.Buffer(BGL.GL_BYTE, [22,22,4])
lordcrc@384
  1317
    offset = 0
lordcrc@384
  1318
    for y in range(22):
lordcrc@384
  1319
        for x in range(22):
lordcrc@384
  1320
            for c in range(4):
lordcrc@384
  1321
                buf[y][x][c] = int(base64value(s[offset])*4.048)
lordcrc@384
  1322
                offset += 1
lordcrc@384
  1323
    return buf
lordcrc@384
  1324
lordcrc@384
  1325
def decodeBarStr(s):
lordcrc@384
  1326
    buf = BGL.Buffer(BGL.GL_BYTE, [17,138,4])
lordcrc@384
  1327
    offset = 0
lordcrc@384
  1328
    for y in range(17):
lordcrc@384
  1329
        for x in range(138):
lordcrc@384
  1330
            for c in range(4):
lordcrc@384
  1331
                buf[y][x][c] = int(base64value(s[offset])*4.048)
lordcrc@384
  1332
                offset += 1
lordcrc@384
  1333
    return buf
lordcrc@384
  1334
lordcrc@384
  1335
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")
lordcrc@384
  1336
lordcrc@384
  1337
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")
lordcrc@384
  1338
lordcrc@384
  1339
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")
lordcrc@384
  1340
lordcrc@384
  1341
lordcrc@384
  1342
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")
lordcrc@384
  1343
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")
lordcrc@384
  1344
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")
lordcrc@384
  1345
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")
lordcrc@384
  1346
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")
lordcrc@384
  1347
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")
lordcrc@384
  1348
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")
lordcrc@384
  1349
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")
lordcrc@384
  1350
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")
lordcrc@384
  1351
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")
lordcrc@384
  1352
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")
lordcrc@384
  1353
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")
lordcrc@384
  1354
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")
lordcrc@384
  1355
lordcrc@384
  1356
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")
lordcrc@384
  1357
lordcrc@384
  1358
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")
lordcrc@384
  1359
lordcrc@384
  1360
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")
lordcrc@384
  1361
lordcrc@384
  1362
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")
lordcrc@384
  1363
lordcrc@384
  1364
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")
lordcrc@384
  1365
lordcrc@384
  1366
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")
lordcrc@384
  1367
lordcrc@384
  1368
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")
lordcrc@384
  1369
lordcrc@384
  1370
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")
lordcrc@384
  1371
lordcrc@384
  1372
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")
lordcrc@384
  1373
lordcrc@384
  1374
lordcrc@384
  1375
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")
lordcrc@384
  1376
lordcrc@384
  1377
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//")
lordcrc@384
  1378
lordcrc@384
  1379
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") 
lordcrc@384
  1380
lordcrc@384
  1381
def drawIcon(icon, x, y):
lordcrc@384
  1382
    BGL.glEnable(BGL.GL_BLEND)
lordcrc@384
  1383
    BGL.glBlendFunc(BGL.GL_SRC_ALPHA, BGL.GL_ONE_MINUS_SRC_ALPHA) 
lordcrc@384
  1384
    BGL.glRasterPos2f(int(x)+0.5, int(y)+0.5)
lordcrc@384
  1385
    BGL.glDrawPixels(16, 16, BGL.GL_RGBA, BGL.GL_UNSIGNED_BYTE, icon)
lordcrc@384
  1386
    BGL.glDisable(BGL.GL_BLEND)
lordcrc@384
  1387
lordcrc@384
  1388
def drawArrow(icon, x, y):
lordcrc@384
  1389
    BGL.glEnable(BGL.GL_BLEND)
lordcrc@384
  1390
    BGL.glBlendFunc(BGL.GL_SRC_ALPHA, BGL.GL_ONE_MINUS_SRC_ALPHA) 
lordcrc@384
  1391
    BGL.glRasterPos2f(int(x)+0.5, int(y)+0.5)
lordcrc@384
  1392
    BGL.glDrawPixels(22, 22, BGL.GL_RGBA, BGL.GL_UNSIGNED_BYTE, icon)
lordcrc@384
  1393
    BGL.glDisable(BGL.GL_BLEND)
lordcrc@384
  1394
lordcrc@384
  1395
def drawLogo(icon, x, y):
lordcrc@384
  1396
    BGL.glEnable(BGL.GL_BLEND)
lordcrc@384
  1397
    BGL.glBlendFunc(BGL.GL_SRC_ALPHA, BGL.GL_ONE_MINUS_SRC_ALPHA) 
lordcrc@384
  1398
    BGL.glRasterPos2f(int(x)+0.5, int(y)+0.5)
lordcrc@384
  1399
    BGL.glDrawPixels(118, 18, BGL.GL_RGBA, BGL.GL_UNSIGNED_BYTE, icon)
lordcrc@384
  1400
    BGL.glDisable(BGL.GL_BLEND)
lordcrc@384
  1401
lordcrc@384
  1402
def drawBar(icon, x, y):
lordcrc@384
  1403
    BGL.glEnable(BGL.GL_BLEND)
lordcrc@384
  1404
    BGL.glBlendFunc(BGL.GL_SRC_ALPHA, BGL.GL_ONE_MINUS_SRC_ALPHA) 
lordcrc@384
  1405
    BGL.glRasterPos2f(int(x)+0.5, int(y)+0.5)
lordcrc@384
  1406
    BGL.glDrawPixels(138, 17, BGL.GL_RGBA, BGL.GL_UNSIGNED_BYTE, icon)
lordcrc@384
  1407
    BGL.glDisable(BGL.GL_BLEND)
lordcrc@384
  1408
lordcrc@384
  1409
lordcrc@384
  1410
lordcrc@384
  1411
#-------------------------------------------------
lordcrc@384
  1412
# luxImage()
lordcrc@384
  1413
# helper class to handle images and icons for the GUI
lordcrc@384
  1414
#-------------------------------------------------
lordcrc@384
  1415
lordcrc@384
  1416
class luxImage:
lordcrc@384
  1417
    def resize(self, width, height):
lordcrc@384
  1418
        self.width = width
lordcrc@384
  1419
        self.height = height
lordcrc@384
  1420
        self.buf = BGL.Buffer(BGL.GL_BYTE, [width,height,4]) # GL buffer
lordcrc@384
  1421
    def __init__(self, width=0, height=0):
lordcrc@384
  1422
        self.resize(width, height)
lordcrc@384
  1423
    def draw(self, x, y):
lordcrc@384
  1424
        BGL.glEnable(BGL.GL_BLEND)
lordcrc@384
  1425
        BGL.glBlendFunc(BGL.GL_SRC_ALPHA, BGL.GL_ONE_MINUS_SRC_ALPHA) 
lordcrc@384
  1426
        BGL.glRasterPos2f(int(x)+0.5, int(y)+0.5)
lordcrc@384
  1427
        BGL.glDrawPixels(self.width, self.height, BGL.GL_RGBA, BGL.GL_UNSIGNED_BYTE, self.buf)
lordcrc@384
  1428
        BGL.glDisable(BGL.GL_BLEND)        
lordcrc@384
  1429
    def decodeStr(self, width, height, s):
lordcrc@384
  1430
        self.resize(width, height)
lordcrc@384
  1431
        offset = 0
lordcrc@384
  1432
        for y in range(self.height):
lordcrc@384
  1433
            for x in range(self.width):
lordcrc@384
  1434
                for c in range(4):
lordcrc@384
  1435
                    self.buf[y][x][c] = int(base64value(s[offset])*4.048)
lordcrc@384
  1436
                    offset += 1
lordcrc@384
  1437
lordcrc@384
  1438
    def decodeLuxConsole(self, width, height, data):
lordcrc@384
  1439
        self.resize(width, height)
lordcrc@384
  1440
        offset = 0
lordcrc@384
  1441
        for y in range(self.height-1,-1,-1):
lordcrc@384
  1442
            for x in range(self.width):
lordcrc@384
  1443
                for c in range(3):
lordcrc@384
  1444
                    self.buf[y][x][c] = ord(data[offset])
lordcrc@384
  1445
                    offset += 1
lordcrc@384
  1446
                self.buf[y][x][3] = 255
lordcrc@384
  1447
lordcrc@384
  1448
lordcrc@384
  1449
previewCache = {}  # dictionary that will hold all preview images
lordcrc@384
  1450
lordcrc@384
  1451
lordcrc@384
  1452
######################################################
lordcrc@384
  1453
# New GUI by Zuegs
lordcrc@384
  1454
######################################################
lordcrc@384
  1455
lordcrc@384
  1456
from types import *
lordcrc@384
  1457
lordcrc@384
  1458
evtLuxGui = 99
lordcrc@384
  1459
evtSavePreset = 98
lordcrc@384
  1460
evtDeletePreset = 97
lordcrc@384
  1461
evtSaveMaterial = 96
lordcrc@384
  1462
evtLoadMaterial = 95
lordcrc@384
  1463
evtDeleteMaterial = 94
lordcrc@384
  1464
evtConvertMaterial = 92
lordcrc@384
  1465
evtSaveMaterial2 = 91
lordcrc@384
  1466
evtLoadMaterial2 = 90
lordcrc@384
  1467
lordcrc@384
  1468
lordcrc@384
  1469
# default settings
lordcrc@384
  1470
defaultsExclude = ['preset','filename','page','link']
lordcrc@384
  1471
try:
lordcrc@384
  1472
    luxdefaults = Blender.Registry.GetKey('luxblend', True)
lordcrc@384
  1473
    if not(type(luxdefaults) is DictType):
lordcrc@384
  1474
        luxdefaults = {}
lordcrc@384
  1475
except:
lordcrc@384
  1476
    luxdefaults = {}
lordcrc@384
  1477
newluxdefaults = luxdefaults.copy()
lordcrc@384
  1478
lordcrc@384
  1479
lordcrc@384
  1480
def saveluxdefaults():
lordcrc@384
  1481
    try: del newluxdefaults['page']
lordcrc@384
  1482
    except: pass
lordcrc@384
  1483
    try: Blender.Registry.SetKey('luxblend', newluxdefaults, True)
lordcrc@384
  1484
    except: pass
lordcrc@384
  1485
lordcrc@384
  1486
lordcrc@384
  1487
lordcrc@384
  1488
lordcrc@384
  1489
lordcrc@384
  1490
# *** PRESETS **************************************
lordcrc@384
  1491
presetsExclude = ['preset','lux','datadir','threads','filename','page','RGC','film.gamma','colorclamp','link']
lordcrc@384
  1492
def getPresets(key):
lordcrc@384
  1493
    presets = Blender.Registry.GetKey(key, True)
lordcrc@384
  1494
    if not(type(presets) is DictType):
lordcrc@384
  1495
        presets = {}
lordcrc@384
  1496
    return presets
lordcrc@384
  1497
def getScenePresets():
lordcrc@384
  1498
    presets = getPresets('luxblend_presets').copy()
lordcrc@384
  1499
lordcrc@384
  1500
    # radiance's hardcoded render presets:
lordcrc@384
  1501
lordcrc@384
  1502
    presets['0 Preview - Direct Lighting'] = {
lordcrc@384
  1503
    'film.displayinterval': 4,
lordcrc@384
  1504
    'haltspp': 0,
lordcrc@384
  1505
    'useparamkeys': 'false',
lordcrc@384
  1506
    'sampler.showadvanced': 'false',
lordcrc@384
  1507
    'sintegrator.showadvanced': 'false',
lordcrc@384
  1508
    'pixelfilter.showadvanced': 'false',
lordcrc@384
  1509
lordcrc@384
  1510
    'sampler.type': 'lowdiscrepancy',
lordcrc@384
  1511
    'sampler.lowdisc.pixelsamples': 1,
lordcrc@384
  1512
    'sampler.lowdisc.pixelsampler': 'lowdiscrepancy',
lordcrc@384
  1513
lordcrc@384
  1514
    'sintegrator.type': 'directlighting',
lordcrc@384
  1515
    'sintegrator.dlighting.maxdepth': 5,
lordcrc@384
  1516
lordcrc@384
  1517
    'pixelfilter.type': 'mitchell',
lordcrc@384
  1518
    'pixelfilter.mitchell.sharp': 0.250, 
lordcrc@384
  1519
    'pixelfilter.mitchell.xwidth': 2.0, 
lordcrc@384
  1520
    'pixelfilter.mitchell.ywidth': 2.0, 
lordcrc@384
  1521
    'pixelfilter.mitchell.optmode': "slider" }
lordcrc@384
  1522
lordcrc@384
  1523
    presets['1 Final - MLT/Bidir Path Tracing (interior) (recommended)'] =  {
lordcrc@384
  1524
    'film.displayinterval': 8,
lordcrc@384
  1525
    'haltspp': 0,
lordcrc@384
  1526
    'useparamkeys': 'false',
lordcrc@384
  1527
    'sampler.showadvanced': 'false',
lordcrc@384
  1528
    'sintegrator.showadvanced': 'false',
lordcrc@384
  1529
    'pixelfilter.showadvanced': 'false',
lordcrc@384
  1530
lordcrc@384
  1531
    'sampler.type': 'metropolis',
lordcrc@384
  1532
    'sampler.metro.strength': 0.6,
lordcrc@384
  1533
    'sampler.metro.lmprob': 0.4,
lordcrc@384
  1534
    'sampler.metro.maxrejects': 512,
lordcrc@384
  1535
    #'sampler.metro.initsamples': 262144,
lordcrc@384
  1536
    'sampler.metro.usevariance': "false",
lordcrc@384
  1537
lordcrc@384
  1538
    'sintegrator.type': 'bidirectional',
lordcrc@384
  1539
    'sintegrator.bidir.bounces': 16,
lordcrc@384
  1540
    'sintegrator.bidir.eyedepth': 16,
lordcrc@384
  1541
    'sintegrator.bidir.lightdepth': 16,
lordcrc@384
  1542
lordcrc@384
  1543
    'pixelfilter.type': 'mitchell',
lordcrc@384
  1544
    'pixelfilter.mitchell.sharp': 0.250, 
lordcrc@384
  1545
    'pixelfilter.mitchell.xwidth': 2.0, 
lordcrc@384
  1546
    'pixelfilter.mitchell.ywidth': 2.0, 
lordcrc@384
  1547
    'pixelfilter.mitchell.optmode': "slider" }
lordcrc@384
  1548
lordcrc@384
  1549
    presets['2 Final - MLT/Path Tracing (exterior)'] =  {
lordcrc@384
  1550
    'film.displayinterval': 8,
lordcrc@384
  1551
    'haltspp': 0,
lordcrc@384
  1552
    'useparamkeys': 'false',
lordcrc@384
  1553
    'sampler.showadvanced': 'false',
lordcrc@384
  1554
    'sintegrator.showadvanced': 'false',
lordcrc@384
  1555
    'pixelfilter.showadvanced': 'false',
lordcrc@384
  1556
lordcrc@384
  1557
    'sampler.type': 'metropolis',
lordcrc@384
  1558
    'sampler.metro.strength': 0.6,
lordcrc@384
  1559
    'sampler.metro.lmprob': 0.4,
lordcrc@384
  1560
    'sampler.metro.maxrejects': 512,
lordcrc@384
  1561
    #'sampler.metro.initsamples': 262144,
lordcrc@384
  1562
    'sampler.metro.usevariance': "false",
lordcrc@384
  1563
lordcrc@384
  1564
    'sintegrator.type': 'path',
lordcrc@384
  1565
    'sintegrator.bidir.bounces': 10,
lordcrc@384
  1566
    'sintegrator.bidir.maxdepth': 10,
lordcrc@384
  1567
lordcrc@384
  1568
    'pixelfilter.type': 'mitchell',
lordcrc@384
  1569
    'pixelfilter.mitchell.sharp': 0.250, 
lordcrc@384
  1570
    'pixelfilter.mitchell.xwidth': 2.0, 
lordcrc@384
  1571
    'pixelfilter.mitchell.ywidth': 2.0, 
lordcrc@384
  1572
    'pixelfilter.mitchell.optmode': "slider" }
lordcrc@384
  1573
    
lordcrc@384
  1574
    presets['4 '] = { }
lordcrc@384
  1575
lordcrc@384
  1576
    presets['5 Progressive - Bidir Path Tracing (interior)'] =  {
lordcrc@384
  1577
    'film.displayinterval': 8,
lordcrc@384
  1578
    'haltspp': 0,
lordcrc@384
  1579
    'useparamkeys': 'false',
lordcrc@384
  1580
    'sampler.showadvanced': 'false',
lordcrc@384
  1581
    'sintegrator.showadvanced': 'false',
lordcrc@384
  1582
    'pixelfilter.showadvanced': 'false',
lordcrc@384
  1583
lordcrc@384
  1584
    'sampler.type': 'lowdiscrepancy',
lordcrc@384
  1585
    'sampler.lowdisc.pixelsamples': 1,
lordcrc@384
  1586
    'sampler.lowdisc.pixelsampler': 'lowdiscrepancy',
lordcrc@384
  1587
lordcrc@384
  1588
    'sintegrator.type': 'bidirectional',
lordcrc@384
  1589
    'sintegrator.bidir.bounces': 16,
lordcrc@384
  1590
    'sintegrator.bidir.eyedepth': 16,
lordcrc@384
  1591
    'sintegrator.bidir.lightdepth': 16,
lordcrc@384
  1592
lordcrc@384
  1593
    'pixelfilter.type': 'mitchell',
lordcrc@384
  1594
    'pixelfilter.mitchell.sharp': 0.250, 
lordcrc@384
  1595
    'pixelfilter.mitchell.xwidth': 2.0, 
lordcrc@384
  1596
    'pixelfilter.mitchell.ywidth': 2.0, 
lordcrc@384
  1597
    'pixelfilter.mitchell.optmode': "slider" }
lordcrc@384
  1598
lordcrc@384
  1599
    presets['6 Progressive - Path Tracing (exterior)'] =  {
lordcrc@384
  1600
    'film.displayinterval': 8,
lordcrc@384
  1601
    'haltspp': 0,
lordcrc@384
  1602
    'useparamkeys': 'false',
lordcrc@384
  1603
    'sampler.showadvanced': 'false',
lordcrc@384
  1604
    'sintegrator.showadvanced': 'false',
lordcrc@384
  1605
    'pixelfilter.showadvanced': 'false',
lordcrc@384
  1606
lordcrc@384
  1607
    'sampler.type': 'lowdiscrepancy',
lordcrc@384
  1608
    'sampler.lowdisc.pixelsamples': 1,
lordcrc@384
  1609
    'sampler.lowdisc.pixelsampler': 'lowdiscrepancy',
lordcrc@384
  1610
lordcrc@384
  1611
    'sintegrator.type': 'path',
lordcrc@384
  1612
    'sintegrator.bidir.bounces': 10,
lordcrc@384
  1613
    'sintegrator.bidir.maxdepth': 10,
lordcrc@384
  1614
lordcrc@384
  1615
    'pixelfilter.type': 'mitchell',
lordcrc@384
  1616
    'pixelfilter.mitchell.sharp': 0.250, 
lordcrc@384
  1617
    'pixelfilter.mitchell.xwidth': 2.0, 
lordcrc@384
  1618
    'pixelfilter.mitchell.ywidth': 2.0, 
lordcrc@384
  1619
    'pixelfilter.mitchell.optmode': "slider" }
lordcrc@384
  1620
lordcrc@384
  1621
    presets['7 '] = { }
lordcrc@384
  1622
lordcrc@384
  1623
    presets['8 Bucket - Bidir Path Tracing (interior)'] =  {
lordcrc@384
  1624
    'film.displayinterval': 8,
lordcrc@384
  1625
    'haltspp': 0,
lordcrc@384
  1626
    'useparamkeys': 'false',
lordcrc@384
  1627
    'sampler.showadvanced': 'false',
lordcrc@384
  1628
    'sintegrator.showadvanced': 'false',
lordcrc@384
  1629
    'pixelfilter.showadvanced': 'false',
lordcrc@384
  1630
lordcrc@384
  1631
    'sampler.type': 'lowdiscrepancy',
lordcrc@384
  1632
    'sampler.lowdisc.pixelsamples': 64,
lordcrc@384
  1633
    'sampler.lowdisc.pixelsampler': 'hilbert',
lordcrc@384
  1634
lordcrc@384
  1635
    'sintegrator.type': 'bidirectional',
lordcrc@384
  1636
    'sintegrator.bidir.bounces': 8,
lordcrc@384
  1637
    'sintegrator.bidir.eyedepth': 8,
lordcrc@384
  1638
    'sintegrator.bidir.lightdepth': 10,
lordcrc@384
  1639
lordcrc@384
  1640
    'pixelfilter.type': 'mitchell',
lordcrc@384
  1641
    'pixelfilter.mitchell.sharp': 0.250, 
lordcrc@384
  1642
    'pixelfilter.mitchell.xwidth': 2.0, 
lordcrc@384
  1643
    'pixelfilter.mitchell.ywidth': 2.0, 
lordcrc@384
  1644
    'pixelfilter.mitchell.optmode': "slider" }
lordcrc@384
  1645
lordcrc@384
  1646
    presets['9 Bucket - Path Tracing (exterior)'] =  {
lordcrc@384
  1647
    'film.displayinterval': 8,
lordcrc@384
  1648
    'haltspp': 0,
lordcrc@384
  1649
    'useparamkeys': 'false',
lordcrc@384
  1650
    'sampler.showadvanced': 'false',
lordcrc@384
  1651
    'sintegrator.showadvanced': 'false',
lordcrc@384
  1652
    'pixelfilter.showadvanced': 'false',
lordcrc@384
  1653
lordcrc@384
  1654
    'sampler.type': 'lowdiscrepancy',
lordcrc@384
  1655
    'sampler.lowdisc.pixelsamples': 64,
lordcrc@384
  1656
    'sampler.lowdisc.pixelsampler': 'hilbert',
lordcrc@384
  1657
lordcrc@384
  1658
    'sintegrator.type': 'path',
lordcrc@384
  1659
    'sintegrator.bidir.bounces': 8,
lordcrc@384
  1660
    'sintegrator.bidir.maxdepth': 8,
lordcrc@384
  1661
lordcrc@384
  1662
    'pixelfilter.type': 'mitchell',
lordcrc@384
  1663
    'pixelfilter.mitchell.sharp': 0.333, 
lordcrc@384
  1664
    'pixelfilter.mitchell.xwidth': 2.0, 
lordcrc@384
  1665
    'pixelfilter.mitchell.ywidth': 2.0, 
lordcrc@384
  1666
    'pixelfilter.mitchell.optmode': "slider" }
lordcrc@384
  1667
lordcrc@384
  1668
    presets['A '] = { }
lordcrc@384
  1669
lordcrc@384
  1670
    presets['B Anim - Distributed/GI low Q'] =  {
lordcrc@384
  1671
    'film.displayinterval': 8,
lordcrc@384
  1672
    'haltspp': 1,
lordcrc@384
  1673
    'useparamkeys': 'false',
lordcrc@384
  1674
    'sampler.showadvanced': 'false',
lordcrc@384
  1675
    'sintegrator.showadvanced': 'false',
lordcrc@384
  1676
    'pixelfilter.showadvanced': 'false',
lordcrc@384
  1677
lordcrc@384
  1678
    'sampler.type': 'lowdiscrepancy',
lordcrc@384
  1679
    'sampler.lowdisc.pixelsamples': 16,
lordcrc@384
  1680
    'sampler.lowdisc.pixelsampler': 'hilbert',
lordcrc@384
  1681
lordcrc@384
  1682
    'sintegrator.type': 'distributedpath',
lordcrc@384
  1683
    'sintegrator.distributedpath.causticsonglossy': 'true',
lordcrc@384
  1684
    'sintegrator.distributedpath.diffuserefractdepth': 5,
lordcrc@384
  1685
    'sintegrator.distributedpath.indirectglossy': 'true',
lordcrc@384
  1686
    'sintegrator.distributedpath.directsamples': 1,
lordcrc@384
  1687
    'sintegrator.distributedpath.diffuserefractsamples': 1,
lordcrc@384
  1688
    'sintegrator.distributedpath.glossyreflectdepth': 2,
lordcrc@384
  1689
    'sintegrator.distributedpath.causticsondiffuse': 'false',
lordcrc@384
  1690
    'sintegrator.distributedpath.directsampleall': 'true',
lordcrc@384
  1691
    'sintegrator.distributedpath.indirectdiffuse': 'true',
lordcrc@384
  1692
    'sintegrator.distributedpath.specularreflectdepth': 3,
lordcrc@384
  1693
    'sintegrator.distributedpath.diffusereflectsamples': 1,
lordcrc@384
  1694
    'sintegrator.distributedpath.glossyreflectsamples': 1,
lordcrc@384
  1695
    'sintegrator.distributedpath.glossyrefractdepth': 5,
lordcrc@384
  1696
    'sintegrator.distributedpath.diffusereflectdepth': '2',
lordcrc@384
  1697
    'sintegrator.distributedpath.indirectsamples': 1,
lordcrc@384
  1698
    'sintegrator.distributedpath.indirectsampleall': 'false',
lordcrc@384
  1699
    'sintegrator.distributedpath.glossyrefractsamples': 1,
lordcrc@384
  1700
    'sintegrator.distributedpath.directdiffuse': 'true',
lordcrc@384
  1701
    'sintegrator.distributedpath.directglossy': 'true',
lordcrc@384
  1702
    'sintegrator.distributedpath.strategy': 'auto',
lordcrc@384
  1703
    'sintegrator.distributedpath.specularrefractdepth': 5,
lordcrc@384
  1704
lordcrc@384
  1705
    'pixelfilter.type': 'mitchell',
lordcrc@384
  1706
    'pixelfilter.mitchell.sharp': 0.333, 
lordcrc@384
  1707
    'pixelfilter.mitchell.xwidth': 2.0, 
lordcrc@384
  1708
    'pixelfilter.mitchell.ywidth': 2.0, 
lordcrc@384
  1709
    'pixelfilter.mitchell.optmode': "slider" }
lordcrc@384
  1710
lordcrc@384
  1711
    presets['C Anim - Distributed/GI medium Q'] =  {
lordcrc@384
  1712
    'film.displayinterval': 8,
lordcrc@384
  1713
    'haltspp': 1,
lordcrc@384
  1714
    'useparamkeys': 'false',
lordcrc@384
  1715
    'sampler.showadvanced': 'false',
lordcrc@384
  1716
    'sintegrator.showadvanced': 'false',
lordcrc@384
  1717
    'pixelfilter.showadvanced': 'false',
lordcrc@384
  1718
lordcrc@384
  1719
    'sampler.type': 'lowdiscrepancy',
lordcrc@384
  1720
    'sampler.lowdisc.pixelsamples': 64,
lordcrc@384
  1721
    'sampler.lowdisc.pixelsampler': 'hilbert',
lordcrc@384
  1722
lordcrc@384
  1723
    'sintegrator.type': 'distributedpath',
lordcrc@384
  1724
    'sintegrator.distributedpath.causticsonglossy': 'true',
lordcrc@384
  1725
    'sintegrator.distributedpath.diffuserefractdepth': 5,
lordcrc@384
  1726
    'sintegrator.distributedpath.indirectglossy': 'true',
lordcrc@384
  1727
    'sintegrator.distributedpath.directsamples': 1,
lordcrc@384
  1728
    'sintegrator.distributedpath.diffuserefractsamples': 1,
lordcrc@384
  1729
    'sintegrator.distributedpath.glossyreflectdepth': 2,
lordcrc@384
  1730
    'sintegrator.distributedpath.causticsondiffuse': 'false',
lordcrc@384
  1731
    'sintegrator.distributedpath.directsampleall': 'true',
lordcrc@384
  1732
    'sintegrator.distributedpath.indirectdiffuse': 'true',
lordcrc@384
  1733
    'sintegrator.distributedpath.specularreflectdepth': 3,
lordcrc@384
  1734
    'sintegrator.distributedpath.diffusereflectsamples': 1,
lordcrc@384
  1735
    'sintegrator.distributedpath.glossyreflectsamples': 1,
lordcrc@384
  1736
    'sintegrator.distributedpath.glossyrefractdepth': 5,
lordcrc@384
  1737
    'sintegrator.distributedpath.diffusereflectdepth': '2',
lordcrc@384
  1738
    'sintegrator.distributedpath.indirectsamples': 1,
lordcrc@384
  1739
    'sintegrator.distributedpath.indirectsampleall': 'false',
lordcrc@384
  1740
    'sintegrator.distributedpath.glossyrefractsamples': 1,
lordcrc@384
  1741
    'sintegrator.distributedpath.directdiffuse': 'true',
lordcrc@384
  1742
    'sintegrator.distributedpath.directglossy': 'true',
lordcrc@384
  1743
    'sintegrator.distributedpath.strategy': 'auto',
lordcrc@384
  1744
    'sintegrator.distributedpath.specularrefractdepth': 5,
lordcrc@384
  1745
lordcrc@384
  1746
    'pixelfilter.type': 'mitchell',
lordcrc@384
  1747
    'pixelfilter.mitchell.sharp': 0.333, 
lordcrc@384
  1748
    'pixelfilter.mitchell.xwidth': 2.0, 
lordcrc@384
  1749
    'pixelfilter.mitchell.ywidth': 2.0, 
lordcrc@384
  1750
    'pixelfilter.mitchell.optmode': "slider" }
lordcrc@384
  1751
    
lordcrc@384
  1752
    presets['D Anim - Distributed/GI high Q'] =  {
lordcrc@384
  1753
    'film.displayinterval': 8,
lordcrc@384
  1754
    'haltspp': 1,
lordcrc@384
  1755
    'useparamkeys': 'false',
lordcrc@384
  1756
    'sampler.showadvanced': 'false',
lordcrc@384
  1757
    'sintegrator.showadvanced': 'false',
lordcrc@384
  1758
    'pixelfilter.showadvanced': 'false',
lordcrc@384
  1759
lordcrc@384
  1760
    'sampler.type': 'lowdiscrepancy',
lordcrc@384
  1761
    'sampler.lowdisc.pixelsamples': 256,
lordcrc@384
  1762
    'sampler.lowdisc.pixelsampler': 'hilbert',
lordcrc@384
  1763
lordcrc@384
  1764
    'sintegrator.type': 'distributedpath',
lordcrc@384
  1765
    'sintegrator.distributedpath.causticsonglossy': 'true',
lordcrc@384
  1766
    'sintegrator.distributedpath.diffuserefractdepth': 5,
lordcrc@384
  1767
    'sintegrator.distributedpath.indirectglossy': 'true',
lordcrc@384
  1768
    'sintegrator.distributedpath.directsamples': 1,
lordcrc@384
  1769
    'sintegrator.distributedpath.diffuserefractsamples': 1,
lordcrc@384
  1770
    'sintegrator.distributedpath.glossyreflectdepth': 2,
lordcrc@384
  1771
    'sintegrator.distributedpath.causticsondiffuse': 'false',
lordcrc@384
  1772
    'sintegrator.distributedpath.directsampleall': 'true',
lordcrc@384
  1773
    'sintegrator.distributedpath.indirectdiffuse': 'true',
lordcrc@384
  1774
    'sintegrator.distributedpath.specularreflectdepth': 3,
lordcrc@384
  1775
    'sintegrator.distributedpath.diffusereflectsamples': 1,
lordcrc@384
  1776
    'sintegrator.distributedpath.glossyreflectsamples': 1,
lordcrc@384
  1777
    'sintegrator.distributedpath.glossyrefractdepth': 5,
lordcrc@384
  1778
    'sintegrator.distributedpath.diffusereflectdepth': '2',
lordcrc@384
  1779
    'sintegrator.distributedpath.indirectsamples': 1,
lordcrc@384
  1780
    'sintegrator.distributedpath.indirectsampleall': 'false',
lordcrc@384
  1781
    'sintegrator.distributedpath.glossyrefractsamples': 1,
lordcrc@384
  1782
    'sintegrator.distributedpath.directdiffuse': 'true',
lordcrc@384
  1783
    'sintegrator.distributedpath.directglossy': 'true',
lordcrc@384
  1784
    'sintegrator.distributedpath.strategy': 'auto',
lordcrc@384
  1785
    'sintegrator.distributedpath.specularrefractdepth': 5,
lordcrc@384
  1786
lordcrc@384
  1787
    'pixelfilter.type': 'mitchell',
lordcrc@384
  1788
    'pixelfilter.mitchell.sharp': 0.333, 
lordcrc@384
  1789
    'pixelfilter.mitchell.xwidth': 2.0, 
lordcrc@384
  1790
    'pixelfilter.mitchell.ywidth': 2.0, 
lordcrc@384
  1791
    'pixelfilter.mitchell.optmode': "slider" }
lordcrc@384
  1792
lordcrc@384
  1793
    presets['E Anim - Distributed/GI very high Q'] =  {
lordcrc@384
  1794
    'film.displayinterval': 8,
lordcrc@384
  1795
    'haltspp': 1,
lordcrc@384
  1796
    'useparamkeys': 'false',
lordcrc@384
  1797
    'sampler.showadvanced': 'false',
lordcrc@384
  1798
    'sintegrator.showadvanced': 'false',
lordcrc@384
  1799
    'pixelfilter.showadvanced': 'false',
lordcrc@384
  1800
lordcrc@384
  1801
    'sampler.type': 'lowdiscrepancy',
lordcrc@384
  1802
    'sampler.lowdisc.pixelsamples': 512,
lordcrc@384
  1803
    'sampler.lowdisc.pixelsampler': 'hilbert',
lordcrc@384
  1804
lordcrc@384
  1805
    'sintegrator.type': 'distributedpath',
lordcrc@384
  1806
    'sintegrator.distributedpath.causticsonglossy': 'true',
lordcrc@384
  1807
    'sintegrator.distributedpath.diffuserefractdepth': 5,
lordcrc@384
  1808
    'sintegrator.distributedpath.indirectglossy': 'true',
lordcrc@384
  1809
    'sintegrator.distributedpath.directsamples': 1,
lordcrc@384
  1810
    'sintegrator.distributedpath.diffuserefractsamples': 1,
lordcrc@384
  1811
    'sintegrator.distributedpath.glossyreflectdepth': 2,
lordcrc@384
  1812
    'sintegrator.distributedpath.causticsondiffuse': 'false',
lordcrc@384
  1813
    'sintegrator.distributedpath.directsampleall': 'true',
lordcrc@384
  1814
    'sintegrator.distributedpath.indirectdiffuse': 'true',
lordcrc@384
  1815
    'sintegrator.distributedpath.specularreflectdepth': 3,
lordcrc@384
  1816
    'sintegrator.distributedpath.diffusereflectsamples': 1,
lordcrc@384
  1817
    'sintegrator.distributedpath.glossyreflectsamples': 1,
lordcrc@384
  1818
    'sintegrator.distributedpath.glossyrefractdepth': 5,
lordcrc@384
  1819
    'sintegrator.distributedpath.diffusereflectdepth': '2',
lordcrc@384
  1820
    'sintegrator.distributedpath.indirectsamples': 1,
lordcrc@384
  1821
    'sintegrator.distributedpath.indirectsampleall': 'false',
lordcrc@384
  1822
    'sintegrator.distributedpath.glossyrefractsamples': 1,
lordcrc@384
  1823
    'sintegrator.distributedpath.directdiffuse': 'true',
lordcrc@384
  1824
    'sintegrator.distributedpath.directglossy': 'true',
lordcrc@384
  1825
    'sintegrator.distributedpath.strategy': 'auto',
lordcrc@384
  1826
    'sintegrator.distributedpath.specularrefractdepth': 5,
lordcrc@384
  1827
lordcrc@384
  1828
    'pixelfilter.type': 'mitchell',
lordcrc@384
  1829
    'pixelfilter.mitchell.sharp': 0.333, 
lordcrc@384
  1830
    'pixelfilter.mitchell.xwidth': 2.0, 
lordcrc@384
  1831
    'pixelfilter.mitchell.ywidth': 2.0, 
lordcrc@384
  1832
    'pixelfilter.mitchell.optmode': "slider" }
lordcrc@384
  1833
lordcrc@384
  1834
    return presets
lordcrc@384
  1835
lordcrc@384
  1836
def getMaterialPresets():
lordcrc@384
  1837
    return getPresets('luxblend_materials')
lordcrc@384
  1838
lordcrc@384
  1839
def savePreset(key, name, d):
lordcrc@384
  1840
    try:
lordcrc@384
  1841
        presets = getPresets(key)
lordcrc@384
  1842
        if d:
lordcrc@384
  1843
            presets[name] = d.copy()
lordcrc@384
  1844
        else:
lordcrc@384
  1845
            del presets[name]
lordcrc@384
  1846
        Blender.Registry.SetKey(key, presets, True)
lordcrc@384
  1847
    except: pass    
lordcrc@384
  1848
def saveScenePreset(name, d):
lordcrc@384
  1849
    try:
lordcrc@384
  1850
        for n in presetsExclude:
lordcrc@384
  1851
            try: del d[n]
lordcrc@384
  1852
            except: pass
lordcrc@384
  1853
        savePreset('luxblend_presets', name, d)
lordcrc@384
  1854
    except: pass
lordcrc@384
  1855
def saveMaterialPreset(name, d):
lordcrc@384
  1856
    try:
lordcrc@384
  1857
        for n in presetsExclude:
lordcrc@384
  1858
            try: del d[n]
lordcrc@384
  1859
            except: pass
lordcrc@384
  1860
        savePreset('luxblend_materials', name, d)
lordcrc@384
  1861
    except: pass
lordcrc@384
  1862
lordcrc@384
  1863
lordcrc@384
  1864
# **************************************************
lordcrc@384
  1865
lordcrc@384
  1866
lordcrc@384
  1867
lordcrc@384
  1868
lordcrc@384
  1869
lordcrc@384
  1870
usedproperties = {} # global variable to collect used properties for storing presets
lordcrc@384
  1871
usedpropertiesfilterobj = None # assign a object to only collect the properties that are assigned to this object
lordcrc@384
  1872
lordcrc@384
  1873
# class to access properties (for lux settings)
lordcrc@384
  1874
class luxProp:
lordcrc@384
  1875
    def __init__(self, obj, name, default):
lordcrc@384
  1876
        self.obj = obj
lordcrc@384
  1877
        self.name = name
lordcrc@384
  1878
#        if len(name)>31: print("Warning: property-name \"%s\" has more than 31 chars."%(name))
lordcrc@384
  1879
        self.hashmode = len(name)>31   # activate hash mode for keynames longer 31 chars (limited by blenders ID-prop)
lordcrc@384
  1880
        self.hashname = "__hash:%x"%(name.__hash__())
lordcrc@384
  1881
        self.default = default
lordcrc@384
  1882
    def parseassignment(self, s, name):
lordcrc@384
  1883
        l = s.split(" = ")
lordcrc@384
  1884
        if l[0] != name: print("Warning: property-name \"%s\" has hash-collide with \"%s\"."%(name, l[0]))
lordcrc@384
  1885
        return l[1]
lordcrc@384
  1886
    def createassignment(self, name, value):
lordcrc@384
  1887
        return "%s = %s"%(name, value)
lordcrc@384
  1888
    def get(self):
lordcrc@384
  1889
        global usedproperties, usedpropertiesfilterobj, luxdefaults
lordcrc@384
  1890
        if self.obj:
lordcrc@384
  1891
            try:
lordcrc@384
  1892
                value = self.obj.properties['luxblend'][self.name]
lordcrc@384
  1893
                if not(usedpropertiesfilterobj) or (usedpropertiesfilterobj == self.obj):
lordcrc@384
  1894
                    usedproperties[self.name] = value
lordcrc@384
  1895
                return value
lordcrc@384
  1896
            except KeyError:
lordcrc@384
  1897
                try:
lordcrc@384
  1898
                    value = self.parseassignment(self.obj.properties['luxblend'][self.hashname], self.name)
lordcrc@384
  1899
                    if not(usedpropertiesfilterobj) or (usedpropertiesfilterobj == self.obj):
lordcrc@384
  1900
                        usedproperties[self.name] = value
lordcrc@384
  1901
                    return value
lordcrc@384
  1902
                except KeyError:
lordcrc@384
  1903
                    if self.obj.__class__.__name__ == "Scene": # luxdefaults only for global setting
lordcrc@384
  1904
                        try:
lordcrc@384
  1905
                            value = luxdefaults[self.name]
lordcrc@384
  1906
                            if not(usedpropertiesfilterobj) or (usedpropertiesfilterobj == self.obj):
lordcrc@384
  1907
                                usedproperties[self.name] = value
lordcrc@384
  1908
                            return value
lordcrc@384
  1909
                        except KeyError:
lordcrc@384
  1910
                            if not(usedpropertiesfilterobj) or (usedpropertiesfilterobj == self.obj):
lordcrc@384
  1911
                                usedproperties[self.name] = self.default
lordcrc@384
  1912
                            return self.default
lordcrc@384
  1913
                    if not(usedpropertiesfilterobj) or (usedpropertiesfilterobj == self.obj):
lordcrc@384
  1914
                        usedproperties[self.name] = self.default
lordcrc@384
  1915
                    return self.default
lordcrc@384
  1916
        return None
lordcrc@384
  1917
    def getobj(self):
lordcrc@384
  1918
        if self.obj:
lordcrc@384
  1919
            return self.obj
lordcrc@384
  1920
        else:
lordcrc@384
  1921
            return None
lordcrc@384
  1922
    def getname(self):
lordcrc@384
  1923
        if self.name:
lordcrc@384
  1924
            return self.name
lordcrc@384
  1925
        else:
lordcrc@384
  1926
            return None
lordcrc@384
  1927
    def set(self, value):
lordcrc@384
  1928
        global newluxdefaults
lordcrc@384
  1929
        if self.obj:
lordcrc@384
  1930
            if self.hashmode: n, v = self.hashname, self.createassignment(self.name, value)
lordcrc@384
  1931
            else: n, v = self.name, value
lordcrc@384
  1932
            if value is not None:
lordcrc@384
  1933
                try: self.obj.properties['luxblend'][n] = v
lordcrc@384
  1934
                except (KeyError, TypeError):
lordcrc@384
  1935
                    self.obj.properties['luxblend'] = {}
lordcrc@384
  1936
                    self.obj.properties['luxblend'][n] = v
lordcrc@384
  1937
            else:
lordcrc@384
  1938
                try: del self.obj.properties['luxblend'][n]
lordcrc@384
  1939
                except:    pass
lordcrc@384
  1940
            if self.obj.__class__.__name__ == "Scene": # luxdefaults only for global setting
lordcrc@384
  1941
                # value has changed, so this are user settings, remove preset reference
lordcrc@384
  1942
                if not(self.name in defaultsExclude):
lordcrc@384
  1943
                    newluxdefaults[self.name] = value
lordcrc@384
  1944
                    try: self.obj.properties['luxblend']['preset']=""
lordcrc@384
  1945
                    except: pass
lordcrc@384
  1946
    def delete(self):
lordcrc@384
  1947
        if self.obj:
lordcrc@384
  1948
            try: del self.obj.properties['luxblend'][self.name]
lordcrc@384
  1949
            except:    pass
lordcrc@384
  1950
            try: del self.obj.properties['luxblend'][self.hashname]
lordcrc@384
  1951
            except:    pass
lordcrc@384
  1952
    def getFloat(self):
lordcrc@384
  1953
        v = self.get()
lordcrc@384
  1954
        if type(v) == types.FloatType: return float(v)
lordcrc@384
  1955
        try:
lordcrc@384
  1956
            if type(v) == types.StringType: return float(v.split(" ")[0])
lordcrc@384
  1957
        except: pass
lordcrc@384
  1958
        v = self.default
lordcrc@384
  1959
        if type(v) == types.FloatType: return float(v)
lordcrc@384
  1960
        try:
lordcrc@384
  1961
            if type(v) == types.StringType: return float(v.split(" ")[0])
lordcrc@384
  1962
        except: pass
lordcrc@384
  1963
        return 0.0
lordcrc@384
  1964
    def getInt(self):
lordcrc@384
  1965
        try: return int(self.get())
lordcrc@384
  1966
        except: return int(self.default)
lordcrc@384
  1967
    def getRGB(self):
lordcrc@384
  1968
        return self.getVector()
lordcrc@384
  1969
    def getVector(self):
lordcrc@384
  1970
        v = self.get()
lordcrc@384
  1971
        if type(v) in [types.FloatType, types.IntType]: return (float(v), float(v), float(v))
lordcrc@384
  1972
        l = None
lordcrc@384
  1973
        try:
lordcrc@384
  1974
            if type(v) == types.StringType: l = self.get().split(" ")
lordcrc@384
  1975
        except: pass
lordcrc@384
  1976
        try:
lordcrc@384
  1977
            if (l==None) or (len(l) != 3): l = self.default.split(" ")
lordcrc@384
  1978
            return (float(l[0]), float(l[1]), float(l[2]))
lordcrc@384
  1979
        except AttributeError:
lordcrc@384
  1980
            return (float(l[0]), float(l[0]), float(l[0]))
lordcrc@384
  1981
        
lordcrc@384
  1982
    def getVectorStr(self):
lordcrc@384
  1983
        return "%f %f %f"%self.getVector()
lordcrc@384
  1984
    def isFloat(self):
lordcrc@384
  1985
        return type(self.get()) == types.FloatType
lordcrc@384
  1986
    def getRGC(self):
lordcrc@384
  1987
        col = self.getRGB()
lordcrc@384
  1988
        return "%f %f %f"%(rg(col[0]), rg(col[1]),rg(col[2]))
lordcrc@384
  1989
    def setRGB(self, value):
lordcrc@384
  1990
        self.set("%f %f %f"%(value[0], value[1], value[2]))
lordcrc@384
  1991
    def setVector(self, value):
lordcrc@384
  1992
        self.set("%f %f %f"%(value[0], value[1], value[2]))
lordcrc@384
  1993
lordcrc@384
  1994
lordcrc@384
  1995
# class to access blender attributes (for lux settings)
lordcrc@384
  1996
class luxAttr:
lordcrc@384
  1997
    def __init__(self, obj, name):
lordcrc@384
  1998
        self.obj = obj
lordcrc@384
  1999
        self.name = name
lordcrc@384
  2000
    def get(self):
lordcrc@384
  2001
        if self.obj:
lordcrc@384
  2002
            return getattr(self.obj, self.name)
lordcrc@384
  2003
        else:
lordcrc@384
  2004
            return None
lordcrc@384
  2005
    def getFloat(self):
lordcrc@384
  2006
        return float(self.get())
lordcrc@384
  2007
    def getInt(self):
lordcrc@384
  2008
        return int(self.get())
lordcrc@384
  2009
    def getobj(self):
lordcrc@384
  2010
        if self.obj:
lordcrc@384
  2011
            return self.obj
lordcrc@384
  2012
        else:
lordcrc@384
  2013
            return None
lordcrc@384
  2014
    def getname(self):
lordcrc@384
  2015
        if self.name:
lordcrc@384
  2016
            return self.name
lordcrc@384
  2017
        else:
lordcrc@384
  2018
            return None
lordcrc@384
  2019
    def set(self, value):
lordcrc@384
  2020
        if self.obj:
lordcrc@384
  2021
            setattr(self.obj, self.name, value)
lordcrc@384
  2022
            Window.QRedrawAll()
lordcrc@384
  2023
lordcrc@384
  2024
lordcrc@384
  2025
# class for dynamic gui
lordcrc@384
  2026
class luxGui:
lordcrc@384
  2027
    def __init__(self, y=200):
lordcrc@384
  2028
        self.x = 110 # left start position after captions
lordcrc@384
  2029
        self.xmax = 110+2*(140+4)
lordcrc@384
  2030
        self.y = y
lordcrc@384
  2031
        self.w = 140 # default element width in pixels
lordcrc@384
  2032
        self.h = 18  # default element height in pixels
lordcrc@384
  2033
        self.hmax = 0
lordcrc@384
  2034
        self.xgap = 4
lordcrc@384
  2035
        self.ygap = 4
lordcrc@384
  2036
        self.resethmax = False
lordcrc@384
  2037
    def getRect(self, wu, hu):
lordcrc@384
  2038
        w = int(self.w * wu + self.xgap * (wu-1))
lordcrc@384
  2039
        h = int(self.h * hu + self.ygap * (hu-1))
lordcrc@384
  2040
        if self.x + w > self.xmax: self.newline()
lordcrc@384
  2041
        if self.resethmax: self.hmax = 0; self.resethmax = False
lordcrc@384
  2042
        rect = [int(self.x), int(self.y-h), int(w), int(h)]
lordcrc@384
  2043
        self.x += int(w + self.xgap)
lordcrc@384
  2044
        if h+self.ygap > self.hmax: self.hmax = int(h+self.ygap)
lordcrc@384
  2045
        return rect
lordcrc@384
  2046
    def newline(self, title="", distance=0, level=0, icon=None, color=None):
lordcrc@384
  2047
        self.x = 110
lordcrc@384
  2048
        if not(self.resethmax): self.y -= int(self.hmax + distance)
lordcrc@384
  2049
        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)
lordcrc@384
  2050
        if icon!=None: drawIcon(icon, 2+level*10, self.y-16)
lordcrc@384
  2051
        self.resethmax = True
lordcrc@384
  2052
        if title!="":
lordcrc@384
  2053
            self.getRect(0, 1)
lordcrc@384
  2054
            BGL.glColor3f(0.9,0.9,0.9); BGL.glRasterPos2i(20+level*10,self.y-self.h+5); Draw.Text(title)
lordcrc@384
  2055
    
lordcrc@384
  2056
def luxHelp(name, lux, caption, hint, gui, width=1.0):
lordcrc@384
  2057
    if gui:
lordcrc@384
  2058
        r = gui.getRect(width, 1)
lordcrc@384
  2059
        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)]))
lordcrc@384
  2060
        drawIcon(icon_help, r[0], r[1])
lordcrc@384
  2061
lordcrc@384
  2062
    return "\n   \"bool %s\" [\"%s\"]"%(name, lux.get())
lordcrc@384
  2063
lordcrc@384
  2064
# lux parameter types
lordcrc@384
  2065
def luxOption(name, lux, options, caption, hint, gui, width=1.0):
lordcrc@384
  2066
    if gui:
lordcrc@384
  2067
        menustr = caption+": %t"
lordcrc@384
  2068
        for i, v in enumerate(options): menustr = "%s %%x%d|%s"%(v, i, menustr)
lordcrc@384
  2069
        try:
lordcrc@384
  2070
            i = options.index(lux.get())
lordcrc@384
  2071
        except ValueError:
lordcrc@384
  2072
            try:
lordcrc@384
  2073
                lux.set(lux.default) # not found, so try default value
lordcrc@384
  2074
                i = options.index(lux.get())
lordcrc@384
  2075
            except ValueError:
lordcrc@384
  2076
                print("value %s not found in options list"%(lux.get()))
lordcrc@384
  2077
                i = 0
lordcrc@384
  2078
        r = gui.getRect(width, 1)
lordcrc@384
  2079
        Draw.Menu(menustr, evtLuxGui, r[0], r[1], r[2], r[3], i, hint, lambda e,v: lux.set(options[v]))
lordcrc@384
  2080
    return "\n   \"string %s\" [\"%s\"]"%(name, lux.get())
lordcrc@384
  2081
lordcrc@384
  2082
def luxOptionRect(name, lux, options, caption, hint, gui, x, y, xx, yy):
lordcrc@384
  2083
    if gui:
lordcrc@384
  2084
        menustr = caption+": %t"
lordcrc@384
  2085
        for i, v in enumerate(options): menustr = "%s %%x%d|%s"%(v, i, menustr)
lordcrc@384
  2086
        try:
lordcrc@384
  2087
            i = options.index(lux.get())
lordcrc@384
  2088
        except ValueError:
lordcrc@384
  2089
            try:
lordcrc@384
  2090
                lux.set(lux.default) # not found, so try default value
lordcrc@384
  2091
                i = options.index(lux.get())
lordcrc@384
  2092
            except ValueError:
lordcrc@384
  2093
                print ("value %s not found in options list"%(lux.get()))
lordcrc@384
  2094
                i = 0
lordcrc@384
  2095
        Draw.Menu(menustr, evtLuxGui, x, y, xx, yy, i, hint, lambda e,v: lux.set(options[v]))
lordcrc@384
  2096
    return "\n   \"string %s\" [\"%s\"]"%(name, lux.get())
lordcrc@384
  2097
lordcrc@384
  2098
def luxIdentifier(name, lux, options, caption, hint, gui, icon=None, width=1.0):
lordcrc@384
  2099
    if gui: gui.newline(caption+":", 8, 0, icon, [0.75,0.5,0.25])
lordcrc@384
  2100
    luxOption(name, lux, options, caption, hint, gui, width)
lordcrc@384
  2101
    return "\n%s \"%s\""%(name, lux.get())
lordcrc@384
  2102
lordcrc@384
  2103
def luxFloat(name, lux, min, max, caption, hint, gui, width=1.0, useslider=0):
lordcrc@384
  2104
    if gui:
lordcrc@384
  2105
        if (luxProp(Scene.GetCurrent(), "useparamkeys", "false").get()=="true"):
lordcrc@384
  2106
            r = gui.getRect(width-0.12, 1)
lordcrc@384
  2107
        else:
lordcrc@384
  2108
            r = gui.getRect(width, 1)
lordcrc@384
  2109
lordcrc@384
  2110
        # Value
lordcrc@384
  2111
        if(useslider==1):
lordcrc@384
  2112
            Draw.Slider(caption+": ", evtLuxGui, r[0], r[1], r[2], r[3], lux.getFloat(), min, max, 0, hint, lambda e,v: lux.set(v))
lordcrc@384
  2113
        else:
lordcrc@384
  2114
            Draw.Number(caption+": ", evtLuxGui, r[0], r[1], r[2], r[3], lux.getFloat(), min, max, hint, lambda e,v: lux.set(v))
lordcrc@384
  2115
        if (luxProp(Scene.GetCurrent(), "useparamkeys", "false").get()=="true"):
lordcrc@384
  2116
            # IPO Curve
lordcrc@384
  2117
            obj = lux.getobj()
lordcrc@384
  2118
            keyname = lux.getname()
lordcrc@384
  2119
    
lordcrc@384
  2120
            useipo = luxProp(obj, keyname+".IPOuse", "false")
lordcrc@384
  2121
            i = gui.getRect(0.12, 1)
lordcrc@384
  2122
            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)]))
lordcrc@384
  2123
            
lordcrc@384
  2124
            if useipo.get() == "true":
lordcrc@384
  2125
                if gui: gui.newline(caption+"IPO:", 8, 0, None, [0.5,0.45,0.35])
lordcrc@384
  2126
                curve = luxProp(obj, keyname+".IPOCurveName", "") 
lordcrc@384
  2127
                if curve.get() == "":
lordcrc@384
  2128
                    c = gui.getRect(2.0, 1)
lordcrc@384
  2129
                else:
lordcrc@384
  2130
                    c = gui.getRect(1.1, 1)
lordcrc@384
  2131
                
lordcrc@384
  2132
                Draw.String("Ipo:", evtLuxGui, c[0], c[1], c[2], c[3], curve.get(), 250, "Set IPO Name", lambda e,v: curve.set(v))
lordcrc@384
  2133
                
lordcrc@384
  2134
                usemapping = luxProp(obj, keyname+".IPOmap", "false")
lordcrc@384
  2135
                icu_value = 0
lordcrc@384
  2136
    
lordcrc@384
  2137
                # Apply IPO to value
lordcrc@384
  2138
                if curve.get() != "":
lordcrc@384
  2139
                    try:
lordcrc@384
  2140
                        ipoob = Blender.Ipo.Get(curve.get())
lordcrc@384
  2141
                    except: 
lordcrc@384
  2142
                        curve.set("")
lordcrc@384
  2143
                    pass
lordcrc@384
  2144
                    if curve.get() != "":
lordcrc@384
  2145
                        names = list([x[0] for x in ipoob.curveConsts.items()])
lordcrc@384
  2146
                        ipotype = luxProp(obj, keyname+".IPOCurveType", "OB_LOCZ")
lordcrc@384
  2147
                        luxOption("ipocurve", ipotype, names, "IPO Curve", "Set IPO Curve", gui, 0.6)
lordcrc@384
  2148
    
lordcrc@384
  2149
                        icu = ipoob[eval("Blender.Ipo.%s" % (ipotype.get()))]
lordcrc@384
  2150
                        icu_value = icu[Blender.Get('curframe')]
lordcrc@384
  2151
                        if usemapping.get() == "false": # if true is set during mapping below
lordcrc@384
  2152
                            lux.set(icu_value)    
lordcrc@384
  2153
    
lordcrc@384
  2154
                        # Mapping options
lordcrc@384
  2155
                        m = gui.getRect(0.3, 1)
lordcrc@384
  2156
                        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)]))
lordcrc@384
  2157
                        if usemapping.get() == "true":
lordcrc@384
  2158
                            if gui: gui.newline(caption+"IPO:", 8, 0, None, [0.5,0.45,0.35])
lordcrc@384
  2159
                            fmin = luxProp(obj, keyname+".IPOCurvefmin", 0.0)
lordcrc@384
  2160
                            luxFloatNoIPO("ipofmin", fmin, -100, 100, "fmin", "Map minimum value from Curve", gui, 0.5)
lordcrc@384
  2161
                            fmax = luxProp(obj, keyname+".IPOCurvefmax", 1.0)
lordcrc@384
  2162
                            luxFloatNoIPO("ipofmax", fmax, -100, 100, "fmax", "Map maximum value from Curve", gui, 0.5)
lordcrc@384
  2163
                            tmin = luxProp(obj, keyname+".IPOCurvetmin", min)
lordcrc@384
  2164
                            luxFloatNoIPO("ipotmin", tmin, min, max, "tmin", "Map miminum value to", gui, 0.5)
lordcrc@384
  2165
                            tmax = luxProp(obj, keyname+".IPOCurvetmax", max)
lordcrc@384
  2166
                            luxFloatNoIPO("ipotmax", tmax, min, max, "tmax", "Map maximum value to", gui, 0.5)
lordcrc@384
  2167
    
lordcrc@384
  2168
                            sval = (icu_value - fmin.getFloat()) / (fmax.getFloat() - fmin.getFloat())
lordcrc@384
  2169
                            lux.set(tmin.getFloat() + (sval * (tmax.getFloat() - tmin.getFloat())))
lordcrc@384
  2170
lordcrc@384
  2171
                            # invert
lordcrc@384
  2172
                            #v = gui.getRect(0.5, 1)
lordcrc@384
  2173
                            #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)]))
lordcrc@384
  2174
    else:
lordcrc@384
  2175
        if (luxProp(Scene.GetCurrent(), "useparamkeys", "false").get()=="true"):
lordcrc@384
  2176
            obj = lux.getobj()
lordcrc@384
  2177
            keyname = lux.getname()
lordcrc@384
  2178
            useipo = luxProp(obj, keyname+".IPOuse", "false")
lordcrc@384
  2179
            if useipo.get() == "true":
lordcrc@384
  2180
                curve = luxProp(obj, keyname+".IPOCurveName", "") 
lordcrc@384
  2181
                try:
lordcrc@384
  2182
                    ipoob = Blender.Ipo.Get(curve.get())
lordcrc@384
  2183
                except: 
lordcrc@384
  2184
                    curve.set("")
lordcrc@384
  2185
                pass
lordcrc@384
  2186
                usemapping = luxProp(obj, keyname+".IPOmap", "false")
lordcrc@384
  2187
                icu_value = 0
lordcrc@384
  2188
                if curve.get() != "":
lordcrc@384
  2189
                    names = list([x[0] for x in ipoob.curveConsts.items()])
lordcrc@384
  2190
                    ipotype = luxProp(obj, keyname+".IPOCurveType", "OB_LOCZ")
lordcrc@384
  2191
    
lordcrc@384
  2192
                    icu = ipoob[eval("Blender.Ipo.%s" % (ipotype.get()))]
lordcrc@384
  2193
                    icu_value = icu[Blender.Get('curframe')]
lordcrc@384
  2194
                    if usemapping.get() == "false": # if true is set during mapping below
lordcrc@384
  2195
                        lux.set(icu_value)    
lordcrc@384
  2196
    
lordcrc@384
  2197
                if usemapping.get() == "true":
lordcrc@384
  2198
                    if gui: gui.newline(caption+"IPO:", 8, 0, None, [0.5,0.45,0.35])
lordcrc@384
  2199
                    fmin = luxProp(obj, keyname+".IPOCurvefmin", 0.0)
lordcrc@384
  2200
                    fmax = luxProp(obj, keyname+".IPOCurvefmax", 1.0)
lordcrc@384
  2201
                    tmin = luxProp(obj, keyname+".IPOCurvetmin", min)
lordcrc@384
  2202
                    tmax = luxProp(obj, keyname+".IPOCurvetmax", max)
lordcrc@384
  2203
                    sval = (icu_value - fmin.getFloat()) / (fmax.getFloat() - fmin.getFloat())
lordcrc@384
  2204
                    lux.set(tmin.getFloat() + (sval * (tmax.getFloat() - tmin.getFloat())))
lordcrc@384
  2205
lordcrc@384
  2206
    return "\n   \"float %s\" [%f]"%(name, lux.getFloat())
lordcrc@384
  2207
lordcrc@384
  2208
def luxFloatNoIPO(name, lux, min, max, caption, hint, gui, width=1.0, useslider=0):
lordcrc@384
  2209
    if gui:
lordcrc@384
  2210
        r = gui.getRect(width, 1)
lordcrc@384
  2211
        if(useslider==1):
lordcrc@384
  2212
            Draw.Slider(caption+": ", evtLuxGui, r[0], r[1], r[2], r[3], lux.getFloat(), min, max, 0, hint, lambda e,v: lux.set(v))
lordcrc@384
  2213
        else:
lordcrc@384
  2214
            Draw.Number(caption+": ", evtLuxGui, r[0], r[1], r[2], r[3], lux.getFloat(), min, max, hint, lambda e,v: lux.set(v))
lordcrc@384
  2215
    return "\n   \"float %s\" [%f]"%(name, lux.getFloat())
lordcrc@384
  2216
lordcrc@384
  2217
lordcrc@384
  2218
lordcrc@384
  2219
def luxInt(name, lux, min, max, caption, hint, gui, width=1.0):
lordcrc@384
  2220
    if gui:
lordcrc@384
  2221
        r = gui.getRect(width, 1)
lordcrc@384
  2222
        Draw.Number(caption+": ", evtLuxGui, r[0], r[1], r[2], r[3], lux.getInt(), min, max, hint, lambda e,v: lux.set(v))
lordcrc@384
  2223
    return "\n   \"integer %s\" [%d]"%(name, lux.getInt())
lordcrc@384
  2224
lordcrc@384
  2225
def luxBool(name, lux, caption, hint, gui, width=1.0):
lordcrc@384
  2226
    if gui:
lordcrc@384
  2227
        r = gui.getRect(width, 1)
lordcrc@384
  2228
        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)]))
lordcrc@384
  2229
    return "\n   \"bool %s\" [\"%s\"]"%(name, lux.get())
lordcrc@384
  2230
doug@387
  2231
def luxLabel(caption, gui):
doug@387
  2232
    if gui:
doug@387
  2233
        r = gui.getRect(2,1); BGL.glRasterPos2i(r[0],r[1]+5)
doug@387
  2234
        Draw.Text(caption)
doug@387
  2235
lordcrc@384
  2236
def luxCollapse(name, lux, caption, hint, gui, width=1.0):
lordcrc@384
  2237
    if gui:
lordcrc@384
  2238
        r = gui.getRect(width, 1)
lordcrc@384
  2239
        if lux.get() == "true":
lordcrc@384
  2240
            drawArrow(arrow_down, r[0]-22, r[1]-2)
lordcrc@384
  2241
        else:
lordcrc@384
  2242
            drawArrow(arrow_right, r[0]-22, r[1]-2)
lordcrc@384
  2243
        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)]))
lordcrc@384
  2244
    return "\n   \"bool %s\" [\"%s\"]"%(name, lux.get())
lordcrc@384
  2245
lordcrc@384
  2246
def luxString(name, lux, caption, hint, gui, width=1.0):
lordcrc@384
  2247
    if gui:
lordcrc@384
  2248
        r = gui.getRect(width, 1)
lordcrc@384
  2249
        Draw.String(caption+": ", evtLuxGui, r[0], r[1], r[2], r[3], lux.get(), 250, hint, lambda e,v: lux.set(v))
lordcrc@384
  2250
    if lux.get()==lux.default: return ""
lordcrc@384
  2251
    else: return "\n   \"string %s\" [\"%s\"]"%(name, luxstr(lux.get()))
lordcrc@384
  2252
lordcrc@384
  2253
def luxFile(name, lux, caption, hint, gui, width=1.0):
lordcrc@384
  2254
    if gui:
lordcrc@384
  2255
        r = gui.getRect(width, 1)
lordcrc@384
  2256
        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))
lordcrc@384
  2257
        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()))
lordcrc@384
  2258
    return "\n   \"string %s\" [\"%s\"]"%(name, luxstr(luxFilePath(lux.get())))
lordcrc@384
  2259
lordcrc@384
  2260
def luxPath(name, lux, caption, hint, gui, width=1.0):
lordcrc@384
  2261
    if gui:
lordcrc@384
  2262
        r = gui.getRect(width, 1)
lordcrc@384
  2263
        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))
lordcrc@384
  2264
        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()))
lordcrc@384
  2265
    return "\n   \"string %s\" [\"%s\"]"%(name, luxstr(lux.get()))
lordcrc@384
  2266
lordcrc@384
  2267
def luxRGB(name, lux, max, caption, hint, gui, width=2.0):
lordcrc@384
  2268
    if gui:
lordcrc@384
  2269
        r = gui.getRect(width, 1)
lordcrc@384
  2270
        scale = 1.0
lordcrc@384
  2271
        rgb = lux.getRGB()
lordcrc@384
  2272
        if max > 1.0:
lordcrc@384
  2273
            for i in range(3):
lordcrc@384
  2274
                if rgb[i] > scale: scale = rgb[i]
lordcrc@384
  2275
            rgb = (rgb[0]/scale, rgb[1]/scale, rgb[2]/scale)
lordcrc@384
  2276
        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)))
lordcrc@384
  2277
        w = int((r[2]-r[3])/3); m = max
lordcrc@384
  2278
        if max > 1.0:
lordcrc@384
  2279
            w = int((r[2]-r[3])/4); m = 1.0
lordcrc@384
  2280
        drawR, drawG, drawB, drawS = Draw.Create(rgb[0]), Draw.Create(rgb[1]), Draw.Create(rgb[2]), Draw.Create(scale)
lordcrc@384
  2281
        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)))
lordcrc@384
  2282
        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)))
lordcrc@384
  2283
        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)))
lordcrc@384
  2284
        if max > 1.0:
lordcrc@384
  2285
            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)))
lordcrc@384
  2286
    if max <= 1.0:
lordcrc@384
  2287
        return "\n   \"color %s\" [%s]"%(name, lux.getRGC())
lordcrc@384
  2288
    return "\n   \"color %s\" [%s]"%(name, lux.get())
lordcrc@384
  2289
lordcrc@384
  2290
def luxVector(name, lux, min, max, caption, hint, gui, width=2.0):
lordcrc@384
  2291
    if gui:
lordcrc@384
  2292
        r = gui.getRect(width, 1)
lordcrc@384
  2293
        vec = lux.getVector()
lordcrc@384
  2294
        w = int(r[2]/3)
lordcrc@384
  2295
        drawX, drawY, drawZ = Draw.Create(vec[0]), Draw.Create(vec[1]), Draw.Create(vec[2])
lordcrc@384
  2296
        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)))
lordcrc@384
  2297
        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)))
lordcrc@384
  2298
        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)))
lordcrc@384
  2299
    return "\n   \"vector %s\" [%s]"%(name, lux.get())
lordcrc@384
  2300
lordcrc@384
  2301
def luxVectorUniform(name, lux, min, max, caption, hint, gui, width=2.0):
lordcrc@384
  2302
    def setUniform(lux, value):
lordcrc@384
  2303
        if value: lux.set(lux.getFloat())
lordcrc@384
  2304
        else: lux.setVector(lux.getVector())
lordcrc@384
  2305
    if gui:
lordcrc@384
  2306
        r = gui.getRect(width, 1)
lordcrc@384
  2307
        vec = lux.getVector()
lordcrc@384
  2308
        Draw.Toggle("U", evtLuxGui, r[0], r[1], gui.h, gui.h, lux.isFloat(), "uniform", lambda e,v: setUniform(lux, v))
lordcrc@384
  2309
        if lux.isFloat():
lordcrc@384
  2310
            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))
lordcrc@384
  2311
        else:
lordcrc@384
  2312
            w = int((r[2]-gui.h)/3)
lordcrc@384
  2313
            drawX, drawY, drawZ = Draw.Create(vec[0]), Draw.Create(vec[1]), Draw.Create(vec[2])
lordcrc@384
  2314
            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)))
lordcrc@384
  2315
            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)))
lordcrc@384
  2316
            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)))
lordcrc@384
  2317
    return "\n   \"vector %s\" [%s]"%(name, lux.getVectorStr())
lordcrc@384
  2318
lordcrc@384
  2319
lordcrc@384
  2320
# lux individual identifiers
lordcrc@384
  2321
def luxCamera(cam, context, gui=None):
lordcrc@384
  2322
    global icon_c_camera
lordcrc@384
  2323
    str = ""
lordcrc@384
  2324
    if cam:
lordcrc@384
  2325
        camtype = luxProp(cam, "camera.type", "perspective")
lordcrc@384
  2326
        # Radiance - remarked 'realistic' for v0.6 release
lordcrc@384
  2327
        #str = luxIdentifier("Camera", camtype, ["perspective","orthographic","environment","realistic"], "CAMERA", "select camera type", gui, icon_c_camera)
lordcrc@384
  2328
        str = luxIdentifier("Camera", camtype, ["perspective","orthographic","environment"], "CAMERA", "select camera type", gui, icon_c_camera)
lordcrc@384
  2329
        scale = 1.0
lordcrc@384
  2330
        if camtype.get() == "perspective":
lordcrc@384
  2331
            if gui: gui.newline("  View:")
lordcrc@384
  2332
            str += luxFloat("fov", luxAttr(cam, "angle"), 8.0, 170.0, "fov", "camera field-of-view angle", gui)
lordcrc@384
  2333
            fl = luxAttr(cam, "lens")
lordcrc@384
  2334
            if gui:
lordcrc@384
  2335
                luxFloat("lens", fl, 1.0, 250.0, "focallength", "camera focal length", gui)
lordcrc@384
  2336
            
lordcrc@384
  2337
        if camtype.get() == "orthographic" :
lordcrc@384
  2338
            str += luxFloat("scale", luxAttr(cam, "scale"), 0.01, 1000.0, "scale", "orthographic camera scale", gui)
lordcrc@384
  2339
            scale = cam.scale / 2
lordcrc@384
  2340
        if camtype.get() == "realistic":
lordcrc@384
  2341
            
lordcrc@384
  2342
            if gui: gui.newline("  View:")
lordcrc@384
  2343
            fov = luxAttr(cam, "angle")
lordcrc@384
  2344
            str += luxFloat("fov", fov, 8.0, 170.0, "fov", "camera field-of-view angle", gui)
lordcrc@384
  2345
            if gui: luxFloat("lens", luxAttr(cam, "lens"), 1.0, 250.0, "focallength", "camera focal length", gui)
lordcrc@384
  2346
            
lordcrc@384
  2347
            
lordcrc@384
  2348
            if gui: gui.newline()
lordcrc@384
  2349
            str += luxFile("specfile", luxProp(cam, "camera.realistic.specfile", ""), "spec-file", "", gui, 1.0)
lordcrc@384
  2350
#            if gui: gui.newline()
lordcrc@384
  2351
# auto calc        str += luxFloat("filmdistance", luxProp(cam, "camera.realistic.filmdistance", 70.0), 0.1, 1000.0, "film-dist", "film-distance [mm]", gui)
lordcrc@384
  2352
            filmdiag = luxProp(cam, "camera.realistic.filmdiag", 35.0)
lordcrc@384
  2353
            str += luxFloat("filmdiag", filmdiag, 0.1, 1000.0, "film-diag", "[mm]", gui)
lordcrc@384
  2354
            if gui: gui.newline()
lordcrc@384
  2355
            fstop = luxProp(cam, "camera.realistic.fstop", 1.0)
lordcrc@384
  2356
            luxFloat("aperture_diameter", fstop, 0.1, 100.0, "f-stop", "", gui)
lordcrc@384
  2357
            dofdist = luxAttr(cam, "dofDist")
lordcrc@384
  2358
            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)
lordcrc@384
  2359
            if gui:
lordcrc@384
  2360
                Draw.Button("S", evtLuxGui, gui.x, gui.y-gui.h, gui.h, gui.h, "focus selected object", lambda e,v:setFocus("S"))
lordcrc@384
  2361
                Draw.Button("C", evtLuxGui, gui.x+gui.h, gui.y-gui.h, gui.h, gui.h, "focus cursor", lambda e,v:setFocus("C"))
lordcrc@384
  2362
            focal = filmdiag.get()*0.001 / math.tan(fov.get() * math.pi / 360.0) / 2.0
lordcrc@384
  2363
            print("calculated focal length: %f mm"%(focal * 1000.0))
lordcrc@384
  2364
            aperture_diameter = focal / fstop.get()
lordcrc@384
  2365
            print("calculated aperture diameter: %f mm"%(aperture_diameter * 1000.0))
lordcrc@384
  2366
            str += "\n   \"float aperture_diameter\" [%f]"%(aperture_diameter*1000.0)
lordcrc@384
  2367
            filmdistance = dofdist.get() * focal / (dofdist.get() - focal)
lordcrc@384
  2368
            print("calculated film distance: %f mm"%(filmdistance * 1000.0))
lordcrc@384
  2369
            str += "\n   \"float filmdistance\" [%f]"%(filmdistance*1000.0)
lordcrc@384
  2370
lordcrc@384
  2371
        # Clipping
lordcrc@384
  2372
        useclip = luxProp(cam, "useclip", "false")
lordcrc@384
  2373
        luxCollapse("useclip", useclip, "Near & Far Clipping", "Enable Camera near and far clipping options", gui, 2.0)
lordcrc@384
  2374
        if(useclip.get() == "true"):
lordcrc@384
  2375
            if gui: gui.newline("  Clipping:")
lordcrc@384
  2376
            str += luxFloat("hither", luxAttr(cam, "clipStart"), 0.0, 100.0, "start", "near clip distance", gui)
lordcrc@384
  2377
            str += luxFloat("yon", luxAttr(cam, "clipEnd"), 1.0, 10000.0, "end", "far clip distance", gui)
lordcrc@384
  2378
lordcrc@384
  2379
        # Depth of Field
lordcrc@384
  2380
        usedof = luxProp(cam, "usedof", "false")
lordcrc@384
  2381
        
lordcrc@384
  2382
        if camtype.get() in ["perspective", "orthographic"]:
lordcrc@384
  2383
            luxCollapse("usedof", usedof, "Depth of Field & Bokeh", "Enable Depth of Field & Aperture options", gui, 2.0)
lordcrc@384
  2384
            
lordcrc@384
  2385
            
lordcrc@384
  2386
            if usedof.get() == "true":
lordcrc@384
  2387
                
lordcrc@384
  2388
                if gui: gui.newline("  DOF:")
lordcrc@384
  2389
                
lordcrc@384
  2390
                lr = luxProp(cam, "camera.lensradius", 0.01)
lordcrc@384
  2391
                fs = luxProp(cam, "camera.fstop", 2.8)
lordcrc@384
  2392
                
lordcrc@384
  2393
                if camtype.get() == "perspective":
lordcrc@384
  2394
                    
lordcrc@384
  2395
                    usefstop = luxProp(cam, "usefstop", "false")
lordcrc@384
  2396
                    luxBool("usefstop", usefstop, "Use f/stop", "Use f/stop to define DOF effect", gui, 1.0)
lordcrc@384
  2397
                    
lordcrc@384
  2398
                    LR_SCALE = 1000.0       # lr in metres -> mm
lordcrc@384
  2399
                    FL_SCALE = 1.0          # fl in mm -> mm
lordcrc@384
  2400
                    
lordcrc@384
  2401
                    def lr_2_fs(fl, lr):
lordcrc@384
  2402
                        lr += 0.00000001
lordcrc@384
  2403
                        return fl / ( 2.0 * lr )
lordcrc@384
  2404
                    
lordcrc@384
  2405
                    def fs_2_lr(fl, fs):
lordcrc@384
  2406
                        return fl / ( 2.0 * fs )
lordcrc@384
  2407
                    
lordcrc@384
  2408
                    if usefstop.get() == 'true':
lordcrc@384
  2409
                        lr.set(fs_2_lr(fl.get() * FL_SCALE, fs.get()) / LR_SCALE)
lordcrc@384
  2410
                        luxFloat("fstop", fs, 0.9, 64.0, "fstop", "Defines the lens aperture.", gui)
lordcrc@384
  2411
                        str += luxFloat("lensradius", lr, 0.0, 1.0, "", "", None)
lordcrc@384
  2412
                    else:
lordcrc@384
  2413
                        fs.set(lr_2_fs(fl.get() * FL_SCALE, lr.get() * LR_SCALE))
lordcrc@384
  2414
                        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)
lordcrc@384
  2415
                else:
lordcrc@384
  2416
                    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)
lordcrc@384
  2417
                
lordcrc@384
  2418
                focustype = luxProp(cam, "camera.focustype", "autofocus")
lordcrc@384
  2419
                luxOption("focustype", focustype, ["autofocus", "manual", "object"], "Focus Type", "Choose the focus behaviour", gui)
lordcrc@384
  2420
                
lordcrc@384
  2421
    
lordcrc@384
  2422
                if focustype.get() == "autofocus":
lordcrc@384
  2423
                    str += luxBool("autofocus",luxProp(cam, "camera.autofocus", "true"), "autofocus", "Enable automatic focus", gui)
lordcrc@384
  2424
                if focustype.get() == "object":
lordcrc@384
  2425
                    objectfocus = luxProp(cam, "camera.objectfocus", "")
lordcrc@384
  2426
                    luxString("objectfocus", objectfocus, "object", "Always focus camera on named object", gui, 1.0)
lordcrc@384
  2427
                    dofdist = luxAttr(cam, "dofDist")
lordcrc@384
  2428
                    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)
lordcrc@384
  2429
                    if objectfocus.get() != "":
jensverwiebe@385
  2430
                        try:
jensverwiebe@385
  2431
                            setFocus(objectfocus.get())
jensverwiebe@385
  2432
                        except:
jensverwiebe@386
  2433
                            luxProp(cam, "camera.objectfocus", "").set("")
jensverwiebe@386
  2434
                            Draw.PupMenu("WARNING: focus-object does not match existing object-name")
jensverwiebe@386
  2435
                            if LuxIsGUI: Draw.Redraw()
jensverwiebe@385
  2436
                                                                  
lordcrc@384
  2437
                if focustype.get() == "manual":
lordcrc@384
  2438
                    dofdist = luxAttr(cam, "dofDist")
lordcrc@384
  2439
                    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)
lordcrc@384
  2440
                    if gui:
lordcrc@384
  2441
                        Draw.Button("S", evtLuxGui, gui.x, gui.y-gui.h, gui.h, gui.h, "focus selected object", lambda e,v:setFocus("S"))
lordcrc@384
  2442
                        Draw.Button("C", evtLuxGui, gui.x+gui.h, gui.y-gui.h, gui.h, gui.h, "focus cursor", lambda e,v:setFocus("C"))
lordcrc@384
  2443
lordcrc@384
  2444
        if camtype.get() == "perspective" and usedof.get() == "true":
lordcrc@384
  2445
            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)
lordcrc@384
  2446
            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)
lordcrc@384
  2447
            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)
lordcrc@384
  2448
lordcrc@384
  2449
        useaspect = luxProp(cam, "useaspectratio", "false")
lordcrc@384
  2450
        aspectratio = luxProp(cam, "ratio", 1.3333)
lordcrc@384
  2451
        if camtype.get() in ["perspective", "orthographic"]:
lordcrc@384
  2452
            useshift = luxProp(cam, "camera.useshift", "false")
lordcrc@384
  2453
            luxCollapse("useshift", useshift, "Architectural (Lens Shift) & Aspect Ratio", "Enable Lens Shift and Aspect Ratio options", gui, 2.0)
lordcrc@384
  2454
            if(useshift.get() == "true"):
lordcrc@384
  2455
                if gui: gui.newline("  Shift:")
lordcrc@384
  2456
                luxFloat("X", luxAttr(cam, "shiftX"), -2.0, 2.0, "X", "horizontal lens shift", gui)
lordcrc@384
  2457
                luxFloat("Y", luxAttr(cam, "shiftY"), -2.0, 2.0, "Y", "vertical lens shift", gui)
lordcrc@384
  2458
lordcrc@384
  2459
                if gui: gui.newline("  AspectRatio:")
lordcrc@384
  2460
                luxBool("useaspectratio", useaspect, "Custom", "Define a custom frame aspect ratio", gui)
lordcrc@384
  2461
                if useaspect.get() == "true":
lordcrc@384
  2462
                    str += luxFloat("frameaspectratio", aspectratio, 0.0001, 3.0, "aspectratio", "Frame aspect ratio", gui)
lordcrc@384
  2463
            if context:
lordcrc@384
  2464
                if useaspect.get() == "true":
lordcrc@384
  2465
                    ratio = 1./aspectratio.get()
lordcrc@384
  2466
                else:
lordcrc@384
  2467
                        ratio = float(context.sizeY)/float(context.sizeX)
lordcrc@384
  2468
                if ratio < 1.0:
lordcrc@384
  2469
                    screenwindow = [(2*cam.shiftX-1)*scale, (2*cam.shiftX+1)*scale, (2*cam.shiftY-ratio)*scale, (2*cam.shiftY+ratio)*scale]
lordcrc@384
  2470
                else:
lordcrc@384
  2471
                    screenwindow = [(2*cam.shiftX-1/ratio)*scale, (2*cam.shiftX+1/ratio)*scale, (2*cam.shiftY-1)*scale, (2*cam.shiftY+1)*scale]
lordcrc@384
  2472
                # render region option
lordcrc@384
  2473
                if context.borderRender:
lordcrc@384
  2474
                    (x1,y1,x2,y2) = context.border
lordcrc@384
  2475
                    screenwindow = [screenwindow[0]*(1-x1)+screenwindow[1]*x1, screenwindow[0]*(1-x2)+screenwindow[1]*x2,\
lordcrc@384
  2476
                            screenwindow[2]*(1-y1)+screenwindow[3]*y1, screenwindow[2]*(1-y2)+screenwindow[3]*y2]
lordcrc@384
  2477
                str += "\n   \"float screenwindow\" [%f %f %f %f]"%(screenwindow[0], screenwindow[1], screenwindow[2], screenwindow[3])
lordcrc@384
  2478
lordcrc@384
  2479
        # Note - radiance - this is a work in progress
lordcrc@384
  2480
        # Flash lamp option for perspective and ortho cams
lordcrc@384
  2481
#        if camtype.get() in ["perspective", "orthographic"]:
lordcrc@384
  2482
#            useflash = luxProp(cam, "useflash", "false")
lordcrc@384
  2483
#            luxBool("useflash", useflash, "Flash Lamp", "Enable Camera mounted flash lamp options", gui, 2.0)
lordcrc@384
  2484
lordcrc@384
  2485
        # Motion Blur Options (common to all cameras)
lordcrc@384
  2486
        usemblur = luxProp(cam, "usemblur", "false")
lordcrc@384
  2487
        luxCollapse("usemblur", usemblur, "Motion Blur", "Enable Motion Blur", gui, 2.0)
lordcrc@384
  2488
        if(usemblur.get() == "true"):    
lordcrc@384
  2489
            if gui: gui.newline("  Shutter:")
lordcrc@384
  2490
            mblurpreset = luxProp(cam, "mblurpreset", "true")
lordcrc@384
  2491
            luxBool("mblurpreset", mblurpreset, "Preset", "Enable use of Shutter Presets", gui, 0.4)
lordcrc@384
  2492
            if(mblurpreset.get() == "true"):
lordcrc@384
  2493
                shutterpresets = ["full frame", "half frame", "quarter frame", "1/25", "1/30", "1/45", "1/60", "1/85", "1/125", "1/250", "1/500"]        
lordcrc@384
  2494
                shutterpreset = luxProp(cam, "camera.shutterspeedpreset", "full frame")
lordcrc@384
  2495
                luxOption("shutterpreset", shutterpreset, shutterpresets, "shutterspeed", "Choose the Shutter speed preset.", gui, 1.0)
lordcrc@384
  2496
lordcrc@384
  2497
                fpspresets = ["10 FPS", "12 FPS", "20 FPS", "25 FPS", "29.99 FPS", "30 FPS", "50 FPS", "60 FPS"]
lordcrc@384
  2498
                shutfps = luxProp(cam, "camera.shutfps", "25 FPS")
lordcrc@384
  2499
                luxOption("shutfps", shutfps, fpspresets, "@", "Choose the number of frames per second as the time base.", gui, 0.6)
lordcrc@384
  2500
lordcrc@384
  2501
                sfps = shutfps.get()
lordcrc@384
  2502
                fps = 25
lordcrc@384
  2503
                if sfps == "10 FPS": fps = 10
lordcrc@384
  2504
                elif sfps == "12 FPS": fps = 12
lordcrc@384
  2505
                elif sfps == "20 FPS": fps = 20
lordcrc@384
  2506
                elif sfps == "25 FPS": fps = 25
lordcrc@384
  2507
                elif sfps == "29.99 FPS": fps = 29.99
lordcrc@384
  2508
                elif sfps == "30 FPS": fps = 30
lordcrc@384
  2509
                elif sfps == "50 FPS": fps = 50
lordcrc@384
  2510
                elif sfps == "60 FPS": fps = 60
lordcrc@384
  2511
lordcrc@384
  2512
                spre = shutterpreset.get()
lordcrc@384
  2513
                open = 0.0
lordcrc@384
  2514
                close = 1.0
lordcrc@384
  2515
                if spre == "full frame": close = 1.0
lordcrc@384
  2516
                elif spre == "half frame": close = 0.5
lordcrc@384
  2517
                elif spre == "quarter frame": close = 0.25
lordcrc@384
  2518
                elif spre == "1/25": close = 1.0 / 25.0 * fps
lordcrc@384
  2519
                elif spre == "1/30": close = 1.0 / 30.0 * fps
lordcrc@384
  2520
                elif spre == "1/45": close = 1.0 / 45.0 * fps
lordcrc@384
  2521
                elif spre == "1/60": close = 1.0 / 60.0 * fps
lordcrc@384
  2522
                elif spre == "1/85": close = 1.0 / 85.0 * fps
lordcrc@384
  2523
                elif spre == "1/125": close = 1.0 / 125.0 * fps
lordcrc@384
  2524
                elif spre == "1/250": close = 1.0 / 250.0 * fps
lordcrc@384
  2525
                elif spre == "1/500": close = 1.0 / 500.0 * fps
lordcrc@384
  2526
lordcrc@384
  2527
                str += "\n   \"float shutteropen\" [%f]\n   \"float shutterclose\" [%f] "%(open,close)
lordcrc@384
  2528
lordcrc@384
  2529
            else:
lordcrc@384
  2530
                str += luxFloat("shutteropen", luxProp(cam, "camera.shutteropen", 0.0), 0.0, 100.0, "open", "time in seconds when shutter opens", gui, 0.8)
lordcrc@384
  2531
                str += luxFloat("shutterclose", luxProp(cam, "camera.shutterclose", 1.0), 0.0, 100.0, "close", "time in seconds when shutter closes", gui, 0.8)
lordcrc@384
  2532
lordcrc@384
  2533
            str += luxOption("shutterdistribution", luxProp(cam, "camera.shutterdistribution", "uniform"), ["uniform", "gaussian"], "distribution", "Choose the shutter sampling distribution.", gui, 2.0)
lordcrc@384
  2534
            objectmblur = luxProp(cam, "objectmblur", "true")
lordcrc@384
  2535
            luxBool("objectmblur", objectmblur, "Object", "Enable Motion Blur for scene object motions", gui, 1.0)
lordcrc@384
  2536
            cammblur = luxProp(cam, "cammblur", "true")
lordcrc@384
  2537
            luxBool("cammblur", cammblur, "Camera", "Enable Motion Blur for Camera motion", gui, 1.0)
lordcrc@384
  2538
    return str
lordcrc@384
  2539
lordcrc@384
  2540
lordcrc@384
  2541
def get_render_resolution(scn, gui = None):
lordcrc@384
  2542
    context = scn.getRenderingContext()
lordcrc@384
  2543
    scale = luxProp(scn, "film.scale", "100 %")
lordcrc@384
  2544
    scale = int(scale.get()[:-1])
lordcrc@384
  2545
    xr = luxAttr(context, "sizeX").get()*scale/100
lordcrc@384
  2546
    yr = luxAttr(context, "sizeY").get()*scale/100
lordcrc@384
  2547
    
lordcrc@384
  2548
    return xr, yr
lordcrc@384
  2549
lordcrc@384
  2550
def luxFilm(scn, gui=None):
lordcrc@384
  2551
    str = ""
lordcrc@384
  2552
    if scn:
lordcrc@384
  2553
        filmtype = luxProp(scn, "film.type", "fleximage")
lordcrc@384
  2554
        str = luxIdentifier("Film", filmtype, ["fleximage"], "FILM", "select film type", gui)
lordcrc@384
  2555
        if filmtype.get() == "fleximage":
lordcrc@384
  2556
            context = scn.getRenderingContext()
lordcrc@384
  2557
            if context:
lordcrc@384
  2558
                if gui: gui.newline("  Resolution:")
lordcrc@384
  2559
                
lordcrc@384
  2560
                xr,yr = get_render_resolution(scn, gui)
lordcrc@384
  2561
                
lordcrc@384
  2562
                luxInt("xresolution", luxAttr(context, "sizeX"), 0, 8192, "X", "width of the render", gui, 0.666)
lordcrc@384
  2563
                luxInt("yresolution", luxAttr(context, "sizeY"), 0, 8192, "Y", "height of the render", gui, 0.666)
lordcrc@384
  2564
                scale = luxProp(scn, "film.scale", "100 %")
lordcrc@384
  2565
                luxOption("", scale, ["400 %", "200 %", "100 %", "75 %", "50 %", "25 %"], "scale", "scale resolution", gui, 0.666)
lordcrc@384
  2566
                
lordcrc@384
  2567
                # render region option
lordcrc@384
  2568
                if context.borderRender:
lordcrc@384
  2569
                    (x1,y1,x2,y2) = context.border
lordcrc@384
  2570
                    if (x1==x2) and (y1==y2): print("WARNING: empty render-region, use SHIFT-B to set render region in Blender.")
lordcrc@384
  2571
                    str += "\n   \"integer xresolution\" [%d] \n   \"integer yresolution\" [%d]"%(xr*(x2-x1), yr*(y2-y1))
lordcrc@384
  2572
                else:
lordcrc@384
  2573
                    str += "\n   \"integer xresolution\" [%d] \n   \"integer yresolution\" [%d]"%(xr, yr)
lordcrc@384
  2574
lordcrc@384
  2575
            if gui: gui.newline("  Halt:")
lordcrc@384
  2576
            str += luxInt("haltspp", luxProp(scn, "haltspp", 0), 0, 32768, "haltspp", "Stop rendering after specified amount of samples per pixel / 0 = never halt", gui)
lordcrc@384
  2577
            palpha = luxProp(scn, "film.premultiplyalpha", "false")
lordcrc@384
  2578
            str += luxBool("premultiplyalpha", palpha, "premultiplyalpha", "Pre multiply film alpha channel during normalization", gui)
lordcrc@384
  2579
    
lordcrc@384
  2580
            if gui: gui.newline("  Tonemap:")
lordcrc@384
  2581
            tonemapkernel =    luxProp(scn, "film.tonemapkernel", "reinhard")
lordcrc@384
  2582
            str += luxOption("tonemapkernel", tonemapkernel, ["reinhard", "linear", "contrast", "maxwhite"], "Tonemapping Kernel", "Select the tonemapping kernel to use", gui, 2.0)
lordcrc@384
  2583
            if tonemapkernel.get() == "reinhard":
lordcrc@384
  2584
                autoywa = luxProp(scn, "film.reinhard.autoywa", "true")
lordcrc@384
  2585
                #str += luxBool("reinhard_autoywa", autoywa, "auto Ywa", "Automatically determine World Adaption Luminance", gui)
lordcrc@384
  2586
                if autoywa.get() == "false":
lordcrc@384
  2587
                    str += luxFloat("reinhard_ywa", luxProp(scn, "film.reinhard.ywa", 0.1), 0.001, 1.0, "Ywa", "Display/World Adaption Luminance", gui)
lordcrc@384
  2588
                str += luxFloat("reinhard_prescale", luxProp(scn, "film.reinhard.prescale", 1.0), 0.0, 10.0, "preScale", "Image scale before tonemap operator", gui)
lordcrc@384
  2589
                str += luxFloat("reinhard_postscale", luxProp(scn, "film.reinhard.postscale", 1.2), 0.0, 10.0, "postScale", "Image scale after tonemap operator", gui)
lordcrc@384
  2590
                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)
lordcrc@384
  2591
            elif tonemapkernel.get() == "linear":
lordcrc@384
  2592
                str += luxFloat("linear_sensitivity", luxProp(scn, "film.linear.sensitivity", 50.0), 0.0, 1000.0, "sensitivity", "Adaption/Sensitivity", gui)
lordcrc@384
  2593
                str += luxFloat("linear_exposure", luxProp(scn, "film.linear.exposure", 1.0), 0.001, 1.0, "exposure", "Exposure duration in seconds", gui)
lordcrc@384
  2594
                str += luxFloat("linear_fstop", luxProp(scn, "film.linear.fstop", 2.8), 0.1, 64.0, "Fstop", "F-Stop", gui)
lordcrc@384
  2595
                str += luxFloat("linear_gamma", luxProp(scn, "film.linear.gamma", 1.0), 0.0, 8.0, "gamma", "Tonemap operator gamma correction", gui)
lordcrc@384
  2596
            elif tonemapkernel.get() == "contrast":
lordcrc@384
  2597
                str += luxFloat("contrast_ywa", luxProp(scn, "film.contrast.ywa", 0.1), 0.001, 1.0, "Ywa", "Display/World Adaption Luminance", gui)
lordcrc@384
  2598
lordcrc@384
  2599
            if gui: gui.newline("  Display:")
lordcrc@384
  2600
            str += luxInt("displayinterval", luxProp(scn, "film.displayinterval", 12), 4, 3600, "interval", "Set display Interval (seconds)", gui)
lordcrc@384
  2601
            
lordcrc@384
  2602
            if gui: gui.newline("  Write:")
lordcrc@384
  2603
            str += luxInt("writeinterval", luxProp(scn, "film.writeinterval", 120), 12, 3600, "interval", "Set display Interval (seconds)", gui)
lordcrc@384
  2604
lordcrc@384
  2605
        # Image File Outputs
lordcrc@384
  2606
lordcrc@384
  2607
        # LDR clamping method
lordcrc@384
  2608
        if gui: gui.newline("  Clamping:")
lordcrc@384
  2609
        ldrclampmethod = luxProp(scn, "film.ldr_clamp_method", "lum")
lordcrc@384
  2610
        str += luxOption("ldr_clamp_method", ldrclampmethod, ["lum", "hue", "cut"], "LDR clamping", "Method to clamp high luminance values for LDR output", gui, 0.5)
lordcrc@384
  2611
        if gui: gui.newline()
lordcrc@384
  2612
lordcrc@384
  2613
        # OpenEXR Output
lordcrc@384
  2614
        saveexr = luxProp(scn, "film.write_exr", "false")
lordcrc@384
  2615
        str += luxCollapse("write_exr", saveexr, "OpenEXR Output", "Enable OpenEXR output", gui, 2.0)
lordcrc@384
  2616
lordcrc@384
  2617
        if saveexr.get() == "true":
lordcrc@384
  2618
            if gui: gui.newline("  OpenEXR:")
lordcrc@384
  2619
lordcrc@384
  2620
            exrchannels = luxProp(scn, "film.write_exr_channels", "RGBA")
lordcrc@384
  2621
            str += luxOption("write_exr_channels", exrchannels, ["Y", "YA", "RGB", "RGBA"], "Channels", "Select channels type to write", gui, 0.5)
lordcrc@384
  2622
            exrres = luxProp(scn, "film.write_exr_halftype", "true")
lordcrc@384
  2623
            str += luxBool("write_exr_halftype", exrres, "16bit Half", "Enable 16bit Half resolution output, otherwise 32bit float", gui, 0.5)
lordcrc@384
  2624
            exrcompression = luxProp(scn, "film.write_exr_compression", "PIZ (lossless)")
lordcrc@384
  2625
            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)
lordcrc@384
  2626
lordcrc@384
  2627
            exrimaging = luxProp(scn, "film.write_exr_imaging", "true")
lordcrc@384
  2628
            str += luxBool("write_exr_applyimaging", exrimaging, "Apply Imaging/Tonemapping", "Apply Imaging and Tonemapping pipeline", gui, 1.2)
lordcrc@384
  2629
        
lordcrc@384
  2630
            if exrimaging.get()=="true":
lordcrc@384
  2631
                exrgamutclamp = luxProp(scn, "film.write_exr_gamutclamp", "true")
lordcrc@384
  2632
                str += luxBool("write_exr_gamutclamp", exrgamutclamp, "Gamut Clamp", "Clamp out of gamut (bright) pixel values", gui, 0.8)
lordcrc@384
  2633
lordcrc@384
  2634
            if gui: gui.newline()
lordcrc@384
  2635
            # Zbuf output
lordcrc@384
  2636
            exrZ = luxProp(scn, "film.write_exr_Z", "true")
lordcrc@384
  2637
            str += luxBool("write_exr_ZBuf", exrZ, "ZBuf", "Enable Z Depth Buffer channel", gui, 0.8)
lordcrc@384
  2638
            if exrZ.get() == "true":
lordcrc@384
  2639
                exrZNormalize = luxProp(scn, "film.write_exr_ZNorm", "None")
lordcrc@384
  2640
                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)
lordcrc@384
  2641
lordcrc@384
  2642
        # PNG Output
lordcrc@384
  2643
        savepng = luxProp(scn, "film.write_png", "true")
lordcrc@384
  2644
        str += luxCollapse("write_png", savepng, "PNG Output", "Enable PNG (Portable Network Graphics) output", gui, 2.0)
lordcrc@384
  2645
lordcrc@384
  2646
        if savepng.get() == "true":
lordcrc@384
  2647
            if gui: gui.newline("  PNG:")
lordcrc@384
  2648
            pngchannels = luxProp(scn, "film.write_png_channels", "RGB")
lordcrc@384
  2649
            str += luxOption("write_png_channels", pngchannels, ["Y", "YA", "RGB", "RGBA"], "Channels", "Select channels type to write", gui, 0.5)
lordcrc@384
  2650
            png16bit = luxProp(scn, "film.write_png_16bit", "false")
lordcrc@384
  2651
            str += luxBool("write_png_16bit", png16bit, "16bit", "Enable 16bits per channel resolution PNG output", gui, 0.5)
lordcrc@384
  2652
            pnggamutclamp = luxProp(scn, "film.write_png_gamutclamp", "true")
lordcrc@384
  2653
            str += luxBool("write_png_gamutclamp", pnggamutclamp, "Gamut Clamp", "Clamp out of gamut (bright) pixel values", gui, 1.0)
lordcrc@384
  2654
lordcrc@384
  2655
        # Zbuf output
lordcrc@384
  2656
        #pngZ = luxProp(scn, "film.write_png_ZBuf", "false")
lordcrc@384
  2657
        #str += luxBool("write_png_ZBuf", pngZ, "ZBuf (Separate)", "Enable Z Depth Buffer channel", gui, 0.8)
lordcrc@384
  2658
        #if pngZ.get() == "true":
lordcrc@384
  2659
        #    pngZNormalize = luxProp(scn, "film.write_png_ZNorm", "Min/Max")
lordcrc@384
  2660
        #    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)
lordcrc@384
  2661
lordcrc@384
  2662
        # TGA Output
lordcrc@384
  2663
        savetga = luxProp(scn, "film.write_tga", "false")
lordcrc@384
  2664
        str += luxCollapse("write_tga", savetga, "TGA Output", "Enable TGA output", gui, 2.0)
lordcrc@384
  2665
lordcrc@384
  2666
        if savetga.get() == "true":
lordcrc@384
  2667
            if gui: gui.newline("  TGA:")
lordcrc@384
  2668
            tgachannels = luxProp(scn, "film.write_tga_channels", "RGB")
lordcrc@384
  2669
            str += luxOption("write_tga_channels", tgachannels, ["Y", "RGB", "RGBA"], "Channels", "Select channels type to write", gui, 0.5)
lordcrc@384
  2670
            tgagamutclamp = luxProp(scn, "film.write_tga_gamutclamp", "true")
lordcrc@384
  2671
            str += luxBool("write_tga_gamutclamp", tgagamutclamp, "Gamut Clamp", "Clamp out of gamut (bright) pixel values", gui, 1.5)
lordcrc@384
  2672
lordcrc@384
  2673
        # Zbuf output
lordcrc@384
  2674
        #tgaZ = luxProp(scn, "film.write_tga_ZBuf", "false")
lordcrc@384
  2675
        #str += luxBool("write_tga_ZBuf", tgaZ, "ZBuf (Separate)", "Enable Z Depth Buffer channel", gui, 0.8)
lordcrc@384
  2676
        #if tgaZ.get() == "true":
lordcrc@384
  2677
        #    tgaZNormalize = luxProp(scn, "film.write_tga_ZNorm", "Min/Max")
lordcrc@384
  2678
        #    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)
lordcrc@384
  2679
lordcrc@384
  2680
lordcrc@384
  2681
        # override output image dir in case of command line batch mode 
lordcrc@384
  2682
        overrideop = luxProp(scn, "overrideoutputpath", "")
lordcrc@384
  2683
        if overrideop.get() != "":
lordcrc@384
  2684
            filebase = os.path.splitext(os.path.basename(Blender.Get('filename')))[0]
lordcrc@384
  2685
            filename = overrideop.get() + "/" + filebase + "-%05d" %  (Blender.Get('curframe'))
lordcrc@384
  2686
            str += "\n   \"string filename\" [\"%s\"]"%(filename)
lordcrc@384
  2687
        else:
lordcrc@384
  2688
            fn = luxProp(scn, "filename", "default-%05d" %  (Blender.Get('curframe')))
lordcrc@384
  2689
            str += luxString("filename", fn, "File name", "save file name", None)
lordcrc@384
  2690
    
lordcrc@384
  2691
        if gui: gui.newline("  Resume:")
lordcrc@384
  2692
        resumeflm = luxProp(scn, "film.write_resume_flm", "false")
lordcrc@384
  2693
        str += luxBool("write_resume_flm", resumeflm, "Write/Use FLM", "Write a resume fleximage .flm file, or resume rendering if it already exists", gui)
lordcrc@384
  2694
        restartflm = luxProp(scn, "film.restart_resume_flm", "true")
lordcrc@384
  2695
        str += luxBool("restart_resume_flm", restartflm, "Restart/Erase", "Restart with a black flm, even it a previous flm exists", gui)
lordcrc@384
  2696
        if gui: gui.newline("  Reject:")
lordcrc@384
  2697
        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)
lordcrc@384
  2698
        debugmode = luxProp(scn, "film.debug", "false")
lordcrc@384
  2699
        str += luxBool("debug", debugmode, "debug", "Turn on debug reporting and switch off reject", gui)
lordcrc@384
  2700
    
lordcrc@384
  2701
        # Colorspace
lordcrc@384
  2702
        if gui: gui.newline("  Colorspace:")
lordcrc@384
  2703
    
lordcrc@384
  2704
        cspaceusepreset = luxProp(scn, "film.colorspaceusepreset", "true")
lordcrc@384
  2705
        luxBool("colorspaceusepreset", cspaceusepreset, "Preset", "Select from a list of predefined presets", gui, 0.4)
lordcrc@384
  2706
    
lordcrc@384
  2707
        # Default values for 'sRGB - HDTV (ITU-R BT.709-5)'
lordcrc@384
  2708
        cspacewhiteX = luxProp(scn, "film.cspacewhiteX", 0.314275)
lordcrc@384
  2709
        cspacewhiteY = luxProp(scn, "film.cspacewhiteY", 0.329411)
lordcrc@384
  2710
        cspaceredX = luxProp(scn, "film.cspaceredX", 0.63)
lordcrc@384
  2711
        cspaceredY = luxProp(scn, "film.cspaceredY", 0.34)
lordcrc@384
  2712
        cspacegreenX = luxProp(scn, "film.cspacegreenX", 0.31)
lordcrc@384
  2713
        cspacegreenY = luxProp(scn, "film.cspacegreenY", 0.595)
lordcrc@384
  2714
        cspaceblueX = luxProp(scn, "film.cspaceblueX", 0.155)
lordcrc@384
  2715
        cspaceblueY = luxProp(scn, "film.cspaceblueY", 0.07)
lordcrc@384
  2716
        gamma = luxProp(scn, "film.gamma", 2.2)
lordcrc@384
  2717
    
lordcrc@384
  2718
        if(cspaceusepreset.get() == "true"):
lordcrc@384
  2719
            # preset controls
lordcrc@384
  2720
            cspace = luxProp(scn, "film.colorspace", "sRGB - HDTV (ITU-R BT.709-5)")
lordcrc@384
  2721
            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"]
lordcrc@384
  2722
            luxOption("colorspace", cspace, cspaces, "Colorspace", "select output working colorspace", gui, 1.6)
lordcrc@384
  2723
    
lordcrc@384
  2724
            if cspace.get()=="ROMM RGB":
lordcrc@384
  2725
                cspacewhiteX.set(0.346); cspacewhiteY.set(0.359) # D50
lordcrc@384
  2726
                cspaceredX.set(0.7347); cspaceredY.set(0.2653)
lordcrc@384
  2727
                cspacegreenX.set(0.1596); cspacegreenY.set(0.8404)
lordcrc@384
  2728
                cspaceblueX.set(0.0366); cspaceblueY.set(0.0001)
lordcrc@384
  2729
            elif cspace.get()=="Adobe RGB 98":
lordcrc@384
  2730
                cspacewhiteX.set(0.313); cspacewhiteY.set(0.329) # D65
lordcrc@384
  2731
                cspaceredX.set(0.64); cspaceredY.set(0.34)
lordcrc@384
  2732
                cspacegreenX.set(0.21); cspacegreenY.set(0.71)
lordcrc@384
  2733
                cspaceblueX.set(0.15); cspaceblueY.set(0.06)
lordcrc@384
  2734
            elif cspace.get()=="Apple RGB":
lordcrc@384
  2735
                cspacewhiteX.set(0.313); cspacewhiteY.set(0.329) # D65
lordcrc@384
  2736
                cspaceredX.set(0.625); cspaceredY.set(0.34)
lordcrc@384
  2737
                cspacegreenX.set(0.28); cspacegreenY.set(0.595)
lordcrc@384
  2738
                cspaceblueX.set(0.155); cspaceblueY.set(0.07)
lordcrc@384
  2739
            elif cspace.get()=="NTSC (FCC 1953, ITU-R BT.470-2 System M)":
lordcrc@384
  2740
                cspacewhiteX.set(0.310); cspacewhiteY.set(0.316) # C
lordcrc@384
  2741
                cspaceredX.set(0.67); cspaceredY.set(0.33)
lordcrc@384
  2742
                cspacegreenX.set(0.21); cspacegreenY.set(0.71)
lordcrc@384
  2743
                cspaceblueX.set(0.14); cspaceblueY.set(0.08)
lordcrc@384
  2744
            elif cspace.get()=="NTSC (1979) (SMPTE C, SMPTE-RP 145)":
lordcrc@384
  2745
                cspacewhiteX.set(0.313); cspacewhiteY.set(0.329) # D65
lordcrc@384
  2746
                cspaceredX.set(0.63); cspaceredY.set(0.34)
lordcrc@384
  2747
                cspacegreenX.set(0.31); cspacegreenY.set(0.595)
lordcrc@384
  2748
                cspaceblueX.set(0.155); cspaceblueY.set(0.07)
lordcrc@384
  2749
            elif cspace.get()=="PAL/SECAM (EBU 3213, ITU-R BT.470-6)":
lordcrc@384
  2750
                cspacewhiteX.set(0.313); cspacewhiteY.set(0.329) # D65
lordcrc@384
  2751
                cspaceredX.set(0.64); cspaceredY.set(0.33)
lordcrc@384
  2752
                cspacegreenX.set(0.29); cspacegreenY.set(0.60)
lordcrc@384
  2753
                cspaceblueX.set(0.15); cspaceblueY.set(0.06)
lordcrc@384
  2754
            elif cspace.get()=="CIE (1931) E":
lordcrc@384
  2755
                cspacewhiteX.set(0.333); cspacewhiteY.set(0.333) # E
lordcrc@384
  2756
                cspaceredX.set(0.7347); cspaceredY.set(0.2653)
lordcrc@384
  2757
                cspacegreenX.set(0.2738); cspacegreenY.set(0.7174)
lordcrc@384
  2758
                cspaceblueX.set(0.1666); cspaceblueY.set(0.0089)
lordcrc@384
  2759
    
lordcrc@384
  2760
            whitepointusecspace = luxProp(scn, "film.whitepointusecolorspace", "true")
lordcrc@384
  2761
            luxBool("whitepointusecolorspace", whitepointusecspace, "Colorspace Whitepoint", "Use default whitepoint for selected colorspace", gui, 1.0)
lordcrc@384
  2762
            gammausecspace = luxProp(scn, "film.gammausecolorspace", "true")
lordcrc@384
  2763
            luxBool("gammausecolorspace", gammausecspace, "Colorspace Gamma", "Use default output gamma for selected colorspace", gui, 1.0)
lordcrc@384
  2764
    
lordcrc@384
  2765
            if(whitepointusecspace.get() == "false"):
lordcrc@384
  2766
                if gui: gui.newline("  Whitepoint:")
lordcrc@384
  2767
                whitepointusepreset = luxProp(scn, "film.whitepointusepreset", "true")
lordcrc@384
  2768
                luxBool("whitepointusepreset", whitepointusepreset, "Preset", "Select from a list of predefined presets", gui, 0.4)
lordcrc@384
  2769
    
lordcrc@384
  2770
                if(whitepointusepreset.get() == "true"):
lordcrc@384
  2771
                    whitepointpresets = ["E", "D50", "D55", "D65", "D75", "A", "B", "C", "9300", "F2", "F7", "F11"]
lordcrc@384
  2772
                    whitepointpreset = luxProp(scn, "film.whitepointpreset", "D65")
lordcrc@384
  2773
                    luxOption("whitepointpreset", whitepointpreset, whitepointpresets, "  PRESET", "select Whitepoint preset", gui, 1.6)
lordcrc@384
  2774
    
lordcrc@384
  2775
                    if whitepointpreset.get()=="E": cspacewhiteX.set(0.333); cspacewhiteY.set(0.333)
lordcrc@384
  2776
                    elif whitepointpreset.get()=="D50": cspacewhiteX.set(0.346); cspacewhiteY.set(0.359)
lordcrc@384
  2777
                    elif whitepointpreset.get()=="D55": cspacewhiteX.set(0.332); cspacewhiteY.set(0.347)
lordcrc@384
  2778
                    elif whitepointpreset.get()=="D65": cspacewhiteX.set(0.313); cspacewhiteY.set(0.329)
lordcrc@384
  2779
                    elif whitepointpreset.get()=="D75": cspacewhiteX.set(0.299); cspacewhiteY.set(0.315)
lordcrc@384
  2780
                    elif whitepointpreset.get()=="A": cspacewhiteX.set(0.448); cspacewhiteY.set(0.407)
lordcrc@384
  2781
                    elif whitepointpreset.get()=="B": cspacewhiteX.set(0.348); cspacewhiteY.set(0.352)
lordcrc@384
  2782
                    elif whitepointpreset.get()=="C": cspacewhiteX.set(0.310); cspacewhiteY.set(0.316)
lordcrc@384
  2783
                    elif whitepointpreset.get()=="9300": cspacewhiteX.set(0.285); cspacewhiteY.set(0.293)
lordcrc@384
  2784
                    elif whitepointpreset.get()=="F2": cspacewhiteX.set(0.372); cspacewhiteY.set(0.375)
lordcrc@384
  2785
                    elif whitepointpreset.get()=="F7": cspacewhiteX.set(0.313); cspacewhiteY.set(0.329)
lordcrc@384
  2786
                    elif whitepointpreset.get()=="F11": cspacewhiteX.set(0.381); cspacewhiteY.set(0.377)
lordcrc@384
  2787
                else:
lordcrc@384
  2788
                    luxFloat("white X", cspacewhiteX, 0.0, 1.0, "white X", "Whitepoint X weight", gui, 0.8)
lordcrc@384
  2789
                    luxFloat("white Y", cspacewhiteY, 0.0, 1.0, "white Y", "Whitepoint Y weight", gui, 0.8)
lordcrc@384
  2790
    
lordcrc@384
  2791
            if(gammausecspace.get() == "false"):
lordcrc@384
  2792
                if gui: gui.newline("  Gamma:")
lordcrc@384
  2793
                luxFloat("gamma", gamma, 0.1, 6.0, "gamma", "Output and RGC Gamma", gui, 2.0)
lordcrc@384
  2794
        else:
lordcrc@384
  2795
            # manual controls
lordcrc@384
  2796
            luxFloat("white X", cspacewhiteX, 0.0, 1.0, "white X", "Whitepoint X weight", gui, 0.8)
lordcrc@384
  2797
            luxFloat("white Y", cspacewhiteY, 0.0, 1.0, "white Y", "Whitepoint Y weight", gui, 0.8)
lordcrc@384
  2798
            luxFloat("red X", cspaceredX, 0.0, 1.0, "red X", "Red component X weight", gui, 1.0)
lordcrc@384
  2799
            luxFloat("red Y", cspaceredY, 0.0, 1.0, "red Y", "Red component Y weight", gui, 1.0)
lordcrc@384
  2800
            luxFloat("green X", cspacegreenX, 0.0, 1.0, "green X", "Green component X weight", gui, 1.0)
lordcrc@384
  2801
            luxFloat("green Y", cspacegreenY, 0.0, 1.0, "green Y", "Green component Y weight", gui, 1.0)
lordcrc@384
  2802
            luxFloat("blue X", cspaceblueX, 0.0, 1.0, "blue X", "Blue component X weight", gui, 1.0)
lordcrc@384
  2803
            luxFloat("blue Y", cspaceblueY, 0.0, 1.0, "blue Y", "Blue component Y weight", gui, 1.0)
lordcrc@384
  2804
            if gui: gui.newline("  Gamma:")
lordcrc@384
  2805
            luxFloat("gamma", gamma, 0.1, 6.0, "gamma", "Output and RGC Gamma", gui, 2.0)
lordcrc@384
  2806
            
lordcrc@384
  2807
        str += "\n   \"float colorspace_white\" [%f %f]"%(cspacewhiteX.get(), cspacewhiteY.get())
lordcrc@384
  2808
        str += "\n   \"float colorspace_red\" [%f %f]"%(cspaceredX.get(), cspaceredY.get())
lordcrc@384
  2809
        str += "\n   \"float colorspace_green\" [%f %f]"%(cspacegreenX.get(), cspacegreenY.get())
lordcrc@384
  2810
        str += "\n   \"float colorspace_blue\" [%f %f]"%(cspaceblueX.get(), cspaceblueY.get())
lordcrc@384
  2811
        str += "\n   \"float gamma\" [%f]"%(gamma.get())
lordcrc@384
  2812
lordcrc@384
  2813
    return str
lordcrc@384
  2814
lordcrc@384
  2815
lordcrc@384
  2816
def luxPixelFilter(scn, gui=None):
lordcrc@384
  2817
    global icon_c_filter
lordcrc@384
  2818
    str = ""
lordcrc@384
  2819
    if scn:
lordcrc@384
  2820
        filtertype = luxProp(scn, "pixelfilter.type", "mitchell")
lordcrc@384
  2821
        str = luxIdentifier("PixelFilter", filtertype, ["box", "gaussian", "mitchell", "sinc", "triangle"], "FILTER", "select pixel filter type", gui, icon_c_filter)
lordcrc@384
  2822
lordcrc@384
  2823
        # Advanced toggle
lordcrc@384
  2824
        parammodeadvanced = luxProp(scn, "parammodeadvanced", "false")
lordcrc@384
  2825
        showadvanced = luxProp(scn, "pixelfilter.showadvanced", parammodeadvanced.get())
lordcrc@384
  2826
        luxBool("advanced", showadvanced, "Advanced", "Show advanced options", gui, 0.6)
lordcrc@384
  2827
        # Help toggle
lordcrc@384
  2828
        showhelp = luxProp(scn, "pixelfilter.showhelp", "false")
lordcrc@384
  2829
        luxHelp("help", showhelp, "Help", "Show Help Information", gui, 0.4)
lordcrc@384
  2830
lordcrc@384
  2831
        if filtertype.get() == "box":
lordcrc@384
  2832
            if showadvanced.get()=="true":
lordcrc@384
  2833
                # Advanced parameters
lordcrc@384
  2834
                if gui: gui.newline()
lordcrc@384
  2835
                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)
lordcrc@384
  2836
                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)
lordcrc@384
  2837
        if filtertype.get() == "gaussian":
lordcrc@384
  2838
            if showadvanced.get()=="true":
lordcrc@384
  2839
                # Advanced parameters
lordcrc@384
  2840
                if gui: gui.newline()
lordcrc@384
  2841
                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)
lordcrc@384
  2842
                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)
lordcrc@384
  2843
                if gui: gui.newline()
lordcrc@384
  2844
                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)
lordcrc@384
  2845
        if filtertype.get() == "mitchell":
lordcrc@384
  2846
            if showadvanced.get()=="false":
lordcrc@384
  2847
                # Default parameters
lordcrc@384
  2848
                if gui: gui.newline("", 8, 0, None, [0.4,0.4,0.4])
lordcrc@384
  2849
                slidval = luxProp(scn, "pixelfilter.mitchell.sharp", 0.25)
lordcrc@384
  2850
                luxFloat("sharpness", slidval, 0.0, 1.0, "sharpness", "Specify amount between blurred (left) and sharp/ringed (right)", gui, 2.0, 1)
lordcrc@384
  2851
                # rule: B + 2*c = 1.0
lordcrc@384
  2852
                C = slidval.getFloat() * 0.5
lordcrc@384
  2853
                B = 1.0 - slidval.getFloat()
lordcrc@384
  2854
                str += "\n   \"float B\" [%f]"%(B)
lordcrc@384
  2855
                str += "\n   \"float C\" [%f]"%(C)
lordcrc@384
  2856
lordcrc@384
  2857
            if showadvanced.get()=="true":
lordcrc@384
  2858
                # Advanced parameters
lordcrc@384
  2859
                if gui: gui.newline()
lordcrc@384
  2860
                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)
lordcrc@384
  2861
                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)
lordcrc@384
  2862
                if gui: gui.newline()
lordcrc@384
  2863
    
lordcrc@384
  2864
                optmode = luxProp(scn, "pixelfilter.mitchell.optmode", "slider")
lordcrc@384
  2865
                luxOption("optmode", optmode, ["slider", "preset", "manual"], "Mode", "Mode of configuration", gui, 0.5)
lordcrc@384
  2866
    
lordcrc@384
  2867
                if(optmode.get() == "slider"):
lordcrc@384
  2868
                    slidval = luxProp(scn, "pixelfilter.mitchell.sharp", 0.33)
lordcrc@384
  2869
                    luxFloat("sharpness", slidval, 0.0, 1.0, "sharpness", "Specify amount between blurred (left) and sharp/ringed (right)", gui, 1.5, 1)
lordcrc@384
  2870
                    # rule: B + 2*c = 1.0
lordcrc@384
  2871
                    C = slidval.getFloat() * 0.5
lordcrc@384
  2872
                    B = 1.0 - slidval.getFloat()
lordcrc@384
  2873
                    str += "\n   \"float B\" [%f]"%(B)
lordcrc@384
  2874
                    str += "\n   \"float C\" [%f]"%(C)
lordcrc@384
  2875
                elif(optmode.get() == "preset"):
lordcrc@384
  2876
                    print("not implemented")
lordcrc@384
  2877
                else:
lordcrc@384
  2878
                    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)
lordcrc@384
  2879
                    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)
lordcrc@384
  2880
lordcrc@384
  2881
        if filtertype.get() == "sinc":
lordcrc@384
  2882
            if showadvanced.get()=="true":
lordcrc@384
  2883
                # Advanced parameters
lordcrc@384
  2884
                if gui: gui.newline()
lordcrc@384
  2885
                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)
lordcrc@384
  2886
                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)
lordcrc@384
  2887
                if gui: gui.newline()
lordcrc@384
  2888
                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)
lordcrc@384
  2889
        if filtertype.get() == "triangle":
lordcrc@384
  2890
            if showadvanced.get()=="true":
lordcrc@384
  2891
                # Advanced parameters
lordcrc@384
  2892
                if gui: gui.newline()
lordcrc@384
  2893
                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)
lordcrc@384
  2894
                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)
lordcrc@384
  2895
    return str            
lordcrc@384
  2896
lordcrc@384
  2897
def luxSampler(scn, gui=None):
lordcrc@384
  2898
    global icon_c_sampler, icon_help
lordcrc@384
  2899
    str = ""
lordcrc@384
  2900
    if scn:
lordcrc@384
  2901
        samplertype = luxProp(scn, "sampler.type", "metropolis")
lordcrc@384
  2902
        str = luxIdentifier("Sampler", samplertype, ["metropolis", "erpt", "lowdiscrepancy", "random"], "SAMPLER", "select sampler type", gui, icon_c_sampler)
lordcrc@384
  2903
lordcrc@384
  2904
        # Advanced toggle
lordcrc@384
  2905
        parammodeadvanced = luxProp(scn, "parammodeadvanced", "false")
lordcrc@384
  2906
        showadvanced = luxProp(scn, "sampler.showadvanced", parammodeadvanced.get())
lordcrc@384
  2907
        luxBool("advanced", showadvanced, "Advanced", "Show advanced options", gui, 0.6)
lordcrc@384
  2908
        # Help toggle
lordcrc@384
  2909
        showhelp = luxProp(scn, "sampler.showhelp", "false")
lordcrc@384
  2910
        luxHelp("help", showhelp, "Help", "Show Help Information", gui, 0.4)
lordcrc@384
  2911
lordcrc@384
  2912
        if samplertype.get() == "metropolis":
lordcrc@384
  2913
            if showadvanced.get()=="false":
lordcrc@384
  2914
                # Default parameters
lordcrc@384
  2915
                if gui: gui.newline("  Mutation:", 8, 0, None, [0.4,0.4,0.4])
lordcrc@384
  2916
                strength = luxProp(scn, "sampler.metro.strength", 0.6)
lordcrc@384
  2917
                luxFloat("strength", strength, 0.0, 1.0, "strength", "Mutation Strength (lmprob = 1.0-strength)", gui, 2.0, 1)
lordcrc@384
  2918
                v = 1.0 - strength.get()
lordcrc@384
  2919
                str += "\n   \"float largemutationprob\" [%f]"%v
lordcrc@384
  2920
            if showadvanced.get()=="true":
lordcrc@384
  2921
                # Advanced parameters
lordcrc@384
  2922
                if gui: gui.newline("  Mutation:")
lordcrc@384
  2923
                str += luxFloat("largemutationprob", luxProp(scn, "sampler.metro.lmprob", 0.4), 0.0, 1.0, "LM.prob.", "Probability of generating a large sample (mutation)", gui)
lordcrc@384
  2924
                str += luxInt("maxconsecrejects", luxProp(scn, "sampler.metro.maxrejects", 512), 0, 32768, "max.rejects", "number of consecutive rejects before a new mutation is forced", gui)
lordcrc@384
  2925
                if gui: gui.newline("  Screen:")
lordcrc@384
  2926
                #str += luxInt("initsamples", luxProp(scn, "sampler.metro.initsamples", 262144), 1, 1000000, "initsamples", "", gui)
lordcrc@384
  2927
                str += luxBool("usevariance",luxProp(scn, "sampler.metro.usevariance", "false"), "usevariance", "Accept based on variance", gui, 1.0)
lordcrc@384
  2928
lordcrc@384
  2929
            if showhelp.get()=="true":
lordcrc@384
  2930
                if gui: gui.newline("  Description:", 8, 0, icon_help, [0.4,0.5,0.56])
lordcrc@384
  2931
                r = gui.getRect(2,1); BGL.glRasterPos2i(r[0],r[1]+5) 
lordcrc@384
  2932
                Draw.Text("A Metropolis-Hastings mutating sampler which implements MLT", 'small')    
lordcrc@384
  2933
lordcrc@384
  2934
        if samplertype.get() == "erpt":
lordcrc@384
  2935
            #str += luxInt("initsamples", luxProp(scn, "sampler.erpt.initsamples", 100000), 1, 1000000, "initsamples", "", gui)
lordcrc@384
  2936
            if gui: gui.newline("  Mutation:")
lordcrc@384
  2937
            str += luxInt("chainlength", luxProp(scn, "sampler.erpt.chainlength", 512), 1, 32768, "chainlength", "The number of mutations from a given seed", gui)
lordcrc@384
  2938
            if gui: gui.newline()
lordcrc@384
  2939
            str += luxInt("stratawidth", luxProp(scn, "sampler.erpt.stratawidth", 256), 1, 32768, "stratawidth", "The number of x/y strata for stratified sampling of seeds", gui)
lordcrc@384
  2940
lordcrc@384
  2941
        if samplertype.get() == "lowdiscrepancy":
lordcrc@384
  2942
            if gui: gui.newline("  PixelSampler:")
lordcrc@384
  2943
            str += luxOption("pixelsampler", luxProp(scn, "sampler.lowdisc.pixelsampler", "lowdiscrepancy"), ["linear", "tile", "random", "vegas","lowdiscrepancy","hilbert"], "pixel-sampler", "select pixel-sampler", gui)
lordcrc@384
  2944
            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)
lordcrc@384
  2945
lordcrc@384
  2946
        if samplertype.get() == "random":
lordcrc@384
  2947
            if gui: gui.newline("  PixelSampler:")
lordcrc@384
  2948
            str += luxOption("pixelsampler", luxProp(scn, "sampler.random.pixelsampler", "vegas"), ["linear", "tile", "random", "vegas","lowdiscrepancy","hilbert"], "pixel-sampler", "select pixel-sampler", gui)
lordcrc@384
  2949
            if gui: gui.newline()
lordcrc@384
  2950
            str += luxInt("pixelsamples", luxProp(scn, "sampler.random.pixelsamples", 4), 1, 512, "pixelsamples", "Allows you to specify how many samples per pixel are computed", gui)
lordcrc@384
  2951
    return str            
lordcrc@384
  2952
lordcrc@384
  2953
def luxSurfaceIntegrator(scn, gui=None):
lordcrc@384
  2954
    global icon_c_integrator
lordcrc@384
  2955
    str = ""
lordcrc@384
  2956
    if scn:
lordcrc@384
  2957
        integratortype = luxProp(scn, "sintegrator.type", "bidirectional")
lordcrc@384
  2958
        
lordcrc@384
  2959
        str = luxIdentifier("SurfaceIntegrator", integratortype, ["directlighting", "path", "bidirectional", "exphotonmap", "distributedpath", "igi" ], "INTEGRATOR", "select surface integrator type", gui, icon_c_integrator)
lordcrc@384
  2960
lordcrc@384
  2961
        # Advanced toggle
lordcrc@384
  2962
        parammodeadvanced = luxProp(scn, "parammodeadvanced", "false")
lordcrc@384
  2963
        showadvanced = luxProp(scn, "sintegrator.showadvanced", parammodeadvanced.get())
lordcrc@384
  2964
        luxBool("advanced", showadvanced, "Advanced", "Show advanced options", gui, 0.6)
lordcrc@384
  2965
        # Help toggle
lordcrc@384
  2966
        showhelp = luxProp(scn, "sintegrator.showhelp", "false")
lordcrc@384
  2967
        luxHelp("help", showhelp, "Help", "Show Help Information", gui, 0.4)
lordcrc@384
  2968
lordcrc@384
  2969
        if integratortype.get() == "directlighting":
lordcrc@384
  2970
            if showadvanced.get()=="false":
lordcrc@384
  2971
                # Default parameters
lordcrc@384
  2972
                if gui: gui.newline("  Depth:", 8, 0, None, [0.4,0.4,0.4])
lordcrc@384
  2973
                str += luxInt("maxdepth", luxProp(scn, "sintegrator.dlighting.maxdepth", 8), 0, 2048, "bounces", "The maximum recursion depth for ray casting", gui, 2.0)
lordcrc@384
  2974
lordcrc@384
  2975
            if showadvanced.get()=="true":
lordcrc@384
  2976
                # Advanced parameters
lordcrc@384
  2977
                str += luxOption("strategy", luxProp(scn, "sintegrator.dlighting.strategy", "auto"), ["one", "all", "auto"], "strategy", "select directlighting strategy", gui)
lordcrc@384
  2978
                if gui: gui.newline("  Depth:")
lordcrc@384
  2979
                str += luxInt("maxdepth", luxProp(scn, "sintegrator.dlighting.maxdepth", 8), 0, 2048, "max-depth", "The maximum recursion depth for ray casting", gui)
lordcrc@384
  2980
                if gui: gui.newline()
lordcrc@384
  2981
lordcrc@384
  2982
        if integratortype.get() == "path":
lordcrc@384
  2983
            if showadvanced.get()=="false":
lordcrc@384
  2984
                # Default parameters
lordcrc@384
  2985
                if gui: gui.newline("  Depth:", 8, 0, None, [0.4,0.4,0.4])
lordcrc@384
  2986
                str += luxInt("maxdepth", luxProp(scn, "sintegrator.path.maxdepth", 10), 0, 2048, "bounces", "The maximum recursion depth for ray casting", gui, 1.0)
lordcrc@384
  2987
                ienv = luxProp(scn, "sintegrator.path.ienvironment", "true")
lordcrc@384
  2988
                str += luxBool("includeenvironment", ienv, "Include Environment", "Enable/Disable rendering of environment lightsources", gui)
lordcrc@384
  2989
lordcrc@384
  2990
            if showadvanced.get()=="true":
lordcrc@384
  2991
                # Advanced parameters
lordcrc@384
  2992
                if gui: gui.newline("  Depth:")
lordcrc@384
  2993
                str += luxInt("maxdepth", luxProp(scn, "sintegrator.path.maxdepth", 10), 0, 2048, "maxdepth", "The maximum recursion depth for ray casting", gui)
lordcrc@384
  2994
                str += luxOption("strategy", luxProp(scn, "sintegrator.path.strategy", "auto"), ["one", "all", "auto"], "strategy", "select directlighting strategy", gui)
lordcrc@384
  2995
                if gui: gui.newline("  RR:")
lordcrc@384
  2996
                rrstrat = luxProp(scn, "sintegrator.path.rrstrategy", "efficiency")
lordcrc@384
  2997
                str += luxOption("rrstrategy", rrstrat, ["efficiency", "probability", "none"], "RR strategy", "select Russian Roulette path termination strategy", gui)
lordcrc@384
  2998
                if rrstrat.get() == "probability":
lordcrc@384
  2999
                    str += luxFloat("rrcontinueprob", luxProp(scn, "sintegrator.path.rrcontinueprob", 0.65), 0.0, 1.0, "rrprob", "Russian roulette continue probability", gui)
lordcrc@384
  3000
                ienv = luxProp(scn, "sintegrator.path.ienvironment", "true")
lordcrc@384
  3001
                str += luxBool("includeenvironment", ienv, "Include Environment", "Enable/Disable rendering of environment lightsources", gui)
lordcrc@384
  3002
lordcrc@384
  3003
        if integratortype.get() == "bidirectional":
lordcrc@384
  3004
            if showadvanced.get()=="false":
lordcrc@384
  3005
                # Default parameters
lordcrc@384
  3006
                if gui: gui.newline("  Depth:", 8, 0, None, [0.4,0.4,0.4])
lordcrc@384
  3007
                bounces = luxProp(scn, "sintegrator.bidir.bounces", 16)
lordcrc@384
  3008
                luxInt("bounces", bounces, 5, 32, "bounces", "The maximum recursion depth for ray casting (in both directions)", gui, 2.0)
lordcrc@384
  3009
                str += "\n   \"integer eyedepth\" [%i]\n"%bounces.get()
lordcrc@384
  3010
                str += "   \"integer lightdepth\" [%i]"%bounces.get()
lordcrc@384
  3011
lordcrc@384
  3012
            if showadvanced.get()=="true":
lordcrc@384
  3013
                # Advanced parameters
lordcrc@384
  3014
                if gui: gui.newline("  Depth:")
lordcrc@384
  3015
                str += luxInt("eyedepth", luxProp(scn, "sintegrator.bidir.eyedepth", 16), 0, 2048, "eyedepth", "The maximum recursion depth for ray casting", gui)
lordcrc@384
  3016
                str += luxInt("lightdepth", luxProp(scn, "sintegrator.bidir.lightdepth", 16), 0, 2048, "lightdepth", "The maximum recursion depth for light ray casting", gui)
lordcrc@384
  3017
                str += luxOption("strategy", luxProp(scn, "sintegrator.bidir.strategy", "auto"), ["one", "all", "auto"], "strategy", "select directlighting strategy", gui)
doug@395
  3018
                
doug@395
  3019
                str += luxFloat('eyerrthreshold', luxProp(scn, "sintegrator.bidir.eyerrthreshold", 0), 0, 1, "eyerrthreshold", "The minimum probability for russian roulette eye subpath termination ", gui)
doug@395
  3020
                str += luxFloat('lightrrthreshold', luxProp(scn, "sintegrator.bidir.lightrrthreshold", 0), 0, 1, "lightrrthreshold", "The minimum probability for russian roulette light subpath termination ", gui)
lordcrc@384
  3021
lordcrc@384
  3022
        if integratortype.get() == "exphotonmap":
lordcrc@384
  3023
            if gui: gui.newline("  Render:")
lordcrc@384
  3024
            str += luxOption("renderingmode", luxProp(scn, "sintegrator.photonmap.renderingmode", "directlighting"), ["directlighting", "path"], "renderingmode", "select rendering mode", gui)
lordcrc@384
  3025
            str += luxOption("strategy", luxProp(scn, "sintegrator.photonmap.strategy", "auto"), ["one", "all", "auto"], "strategy", "select directlighting strategy", gui)
lordcrc@384
  3026
            str += luxInt("maxphotondepth", luxProp(scn, "sintegrator.photonmap.maxphotondepth", 10), 1, 1024, "maxphotondepth", "The maximum recursion depth of photon tracing", gui)
lordcrc@384
  3027
            str += luxInt("maxdepth", luxProp(scn, "sintegrator.photonmap.maxdepth", 6), 1, 1024, "maxdepth", "The maximum recursion depth of specular reflection and refraction", gui)
lordcrc@384
  3028
            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)
lordcrc@384
  3029
            str += luxInt("nused", luxProp(scn, "sintegrator.photonmap.nused", 50), 0, 1000000, "nused", "The number of photons to use in density estimation", gui)
lordcrc@384
  3030
lordcrc@384
  3031
            if gui: gui.newline("  Photons:")
lordcrc@384
  3032
            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)
lordcrc@384
  3033
            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)
lordcrc@384
  3034
            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)
lordcrc@384
  3035
            if gui: gui.newline("  FinalGather:")
lordcrc@384
  3036
            fg = luxProp(scn, "sintegrator.photonmap.fgather", "true")
lordcrc@384
  3037
            str += luxBool("finalgather", fg, "finalgather", "Enable use of final gather during rendering", gui)
lordcrc@384
  3038
            if fg.get() == "true":
lordcrc@384
  3039
                rrstrat = luxProp(scn, "sintegrator.photonmap.gatherrrstrategy", "efficiency")
lordcrc@384
  3040
                str += luxOption("gatherrrstrategy", rrstrat, ["efficiency", "probability", "none"], "RR strategy", "select Russian Roulette gather termination strategy", gui)
lordcrc@384
  3041
                str += luxInt("finalgathersamples", luxProp(scn, "sintegrator.photonmap.fgathers", 32), 1, 1024, "samples", "The number of finalgather samples to take per pixel during rendering", gui)
lordcrc@384
  3042
                str += luxFloat("gatherangle", luxProp(scn, "sintegrator.photonmap.gangle", 10.0), 0.0, 360.0, "gatherangle", "Angle for final gather", gui)
lordcrc@384
  3043
                if rrstrat.get() == "probability":
lordcrc@384
  3044
                    str += luxFloat("gatherrrcontinueprob", luxProp(scn, "sintegrator.photonmap.gatherrrcontinueprob", 0.65), 0.0, 1.0, "rrcontinueprob", "Probability for russian roulette particle tracing termination", gui)
lordcrc@384
  3045
lordcrc@384
  3046
        if integratortype.get() == "distributedpath":
lordcrc@384
  3047
            str += luxOption("strategy", luxProp(scn, "sintegrator.distributedpath.strategy", "auto"), ["one", "all", "auto"], "strategy", "select directlighting strategy", gui)
lordcrc@384
  3048
            if gui: gui.newline("  Direct:")
lordcrc@384
  3049
            str += luxBool("directsampleall",luxProp(scn, "sintegrator.distributedpath.directsampleall", "true"), "Direct ALL", "Include diffuse direct light sample at first vertex", gui, 0.7)
lordcrc@384
  3050
            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.3)
lordcrc@384
  3051
            str += luxBool("indirectsampleall",luxProp(scn, "sintegrator.distributedpath.indirectsampleall", "false"), "Indirect ALL", "Include diffuse direct light sample at first vertex", gui, 0.7)
lordcrc@384
  3052
            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.3)
lordcrc@384
  3053
            if gui: gui.newline("  Diffuse:")
lordcrc@384
  3054
            str += luxInt("diffusereflectdepth", luxProp(scn, "sintegrator.distributedpath.diffusereflectdepth", 3), 0, 2048, "Reflect", "The maximum recursion depth for diffuse reflection ray casting", gui, 0.5)
lordcrc@384
  3055
            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.3)
lordcrc@384
  3056
            str += luxInt("diffuserefractdepth", luxProp(scn, "sintegrator.distributedpath.diffuserefractdepth", 5), 0, 2048, "Refract", "The maximum recursion depth for diffuse refraction ray casting", gui, 0.5)
lordcrc@384
  3057
            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.3)
lordcrc@384
  3058
            str += luxBool("directdiffuse",luxProp(scn, "sintegrator.distributedpath.directdiffuse", "true"), "DL", "Include diffuse direct light sample at first vertex", gui, 0.20)
lordcrc@384
  3059
            str += luxBool("indirectdiffuse",luxProp(scn, "sintegrator.distributedpath.indirectdiffuse", "true"), "IDL", "Include diffuse indirect light sample at first vertex", gui, 0.20)
lordcrc@384
  3060
            if gui: gui.newline("  Glossy:")
lordcrc@384
  3061
            str += luxInt("glossyreflectdepth", luxProp(scn, "sintegrator.distributedpath.glossyreflectdepth", 2), 0, 2048, "Reflect", "The maximum recursion depth for glossy reflection ray casting", gui, 0.50)
lordcrc@384
  3062
            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.3)
lordcrc@384
  3063
            str += luxInt("glossyrefractdepth", luxProp(scn, "sintegrator.distributedpath.glossyrefractdepth", 5), 0, 2048, "Refract", "The maximum recursion depth for glossy refraction ray casting", gui, 0.50)
lordcrc@384
  3064
            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.3)
lordcrc@384
  3065
            str += luxBool("directglossy",luxProp(scn, "sintegrator.distributedpath.directglossy", "true"), "DL", "Include glossy direct light sample at first vertex", gui, 0.20)
lordcrc@384
  3066
            str += luxBool("indirectglossy",luxProp(scn, "sintegrator.distributedpath.indirectglossy", "true"), "IDL", "Include glossy indirect light sample at first vertex", gui, 0.20)
lordcrc@384
  3067
            if gui: gui.newline("  Specular:")
lordcrc@384
  3068
            str += luxInt("specularreflectdepth", luxProp(scn, "sintegrator.distributedpath.specularreflectdepth", 3), 0, 2048, "Reflect", "The maximum recursion depth for specular reflection ray casting", gui, 1.0)
lordcrc@384
  3069
            str += luxInt("specularrefractdepth", luxProp(scn, "sintegrator.distributedpath.specularrefractdepth", 5), 0, 2048, "Refract", "The maximum recursion depth for specular refraction ray casting", gui, 1.0)
lordcrc@384
  3070
            #if gui: gui.newline("  Caustics:")
lordcrc@384
  3071
            #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)
lordcrc@384
  3072
            #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)
lordcrc@384
  3073
lordcrc@384
  3074
            usereject = luxProp(scn, "sintegrator.distributedpath.usereject", "false")
lordcrc@384
  3075
            luxCollapse("usereject", usereject, "Rejection", "Enable Rejection system to eliminate bright contributions", gui, 2.0)
lordcrc@384
  3076
lordcrc@384
  3077
            if usereject.get()=="true":
lordcrc@384
  3078
                if gui: gui.newline("  Diffuse:")
lordcrc@384
  3079
                
lordcrc@384
  3080
                diffusereflectreject = luxProp(scn, "sintegrator.distributedpath.difreflreject", "false")
lordcrc@384
  3081
                str += luxBool("diffusereflectreject", diffusereflectreject, "Reflect", "Enable Rejection for Diffuse Reflection", gui, 0.4)
lordcrc@384
  3082
                if diffusereflectreject.get()=="true":
lordcrc@384
  3083
                    str += luxFloat("diffusereflectreject_threshold", luxProp(scn, "sintegrator.distributedpath.difreflrejectthr", 10.0), 0.01, 10.0, "Thr", "The Average Threshold to reject", gui, 0.6)
lordcrc@384
  3084
            
lordcrc@384
  3085
                diffuserefractreject = luxProp(scn, "sintegrator.distributedpath.difrefrreject", "false")
lordcrc@384
  3086
                str += luxBool("diffuserefractreject", diffuserefractreject, "Refract", "Enable Rejection for Diffuse Refraction", gui, 0.4)
lordcrc@384
  3087
                if diffuserefractreject.get()=="true":
lordcrc@384
  3088
                    str += luxFloat("diffuserefractreject_threshold", luxProp(scn, "sintegrator.distributedpath.difrefrrejectthr", 10.0), 0.01, 10.0, "Thr", "The Average Threshold to reject", gui, 0.6)
lordcrc@384
  3089
            
lordcrc@384
  3090
                if gui: gui.newline("  Glossy:")
lordcrc@384
  3091
                
lordcrc@384
  3092
                glossyreflectreject = luxProp(scn, "sintegrator.distributedpath.glosreflreject", "false")
lordcrc@384
  3093
                str += luxBool("glossyreflectreject", glossyreflectreject, "Reflect", "Enable Rejection for Glossy Reflection", gui, 0.4)
lordcrc@384
  3094
                if glossyreflectreject.get()=="true":
lordcrc@384
  3095
                    str += luxFloat("glossyreflectreject_threshold", luxProp(scn, "sintegrator.distributedpath.glosreflrejectthr", 10.0), 0.01, 10.0, "Thr", "The Average Threshold to reject", gui, 0.6)
lordcrc@384
  3096
            
lordcrc@384
  3097
                glossyrefractreject = luxProp(scn, "sintegrator.distributedpath.glosrefrreject", "false")
lordcrc@384
  3098
                str += luxBool("glossyrefractreject", glossyrefractreject, "Refract", "Enable Rejection for Glossy Refraction", gui, 0.4)
lordcrc@384
  3099
                if glossyrefractreject.get()=="true":
lordcrc@384
  3100
                    str += luxFloat("glossyrefractreject_threshold", luxProp(scn, "sintegrator.distributedpath.glosrefrrejectthr", 10.0), 0.01, 10.0, "Thr", "The Average Threshold to reject", gui, 0.6)
lordcrc@384
  3101
    
lordcrc@384
  3102
        if integratortype.get() == "igi":
lordcrc@384
  3103
            if gui: gui.newline("  Depth:", 8, 0, None, [0.4,0.4,0.4])
lordcrc@384
  3104
            depth = luxProp(scn, "sintegrator.igi.maxdepth", 5)
lordcrc@384
  3105
            luxInt("maxdepth", depth, 1, 32, "maxdepth", "The maximum recursion depth for ray casting", gui, 2.0)
lordcrc@384
  3106
            if showadvanced.get()=="true":
lordcrc@384
  3107
                # Advanced parameters
lordcrc@384
  3108
                if gui: gui.newline("  VLights:")
lordcrc@384
  3109
                str += luxInt("nsets", luxProp(scn, "sintegrator.igi.nsets", 4), 1, 100, "nsets", "The number of virtual lights sets", gui)
lordcrc@384
  3110
                str += luxInt("nlights", luxProp(scn, "sintegrator.igi.nlights", 64), 1, 1000, "nlights", "The number of light paths per light set", gui)
lordcrc@384
  3111
                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)
lordcrc@384
  3112
lordcrc@384
  3113
    
lordcrc@384
  3114
    return str
lordcrc@384
  3115
lordcrc@384
  3116
def luxVolumeIntegrator(scn, gui=None):
lordcrc@384
  3117
    global icon_c_volumeintegrator
lordcrc@384
  3118
    str = ""
lordcrc@384
  3119
    if scn:
lordcrc@384
  3120
        integratortype = luxProp(scn, "vintegrator.type", "single")
lordcrc@384
  3121
        str = luxIdentifier("VolumeIntegrator", integratortype, ["emission", "single"], "VOLUME INT", "select volume integrator type", gui, icon_c_volumeintegrator)
lordcrc@384
  3122
        if integratortype.get() == "emission":
lordcrc@384
  3123
            str += luxFloat("stepsize", luxProp(scn, "vintegrator.emission.stepsize", 1.0), 0.0, 100.0, "stepsize", "Stepsize for volumes", gui)
lordcrc@384
  3124
        if integratortype.get() == "single":
lordcrc@384
  3125
            str += luxFloat("stepsize", luxProp(scn, "vintegrator.emission.stepsize", 1.0), 0.0, 100.0, "stepsize", "Stepsize for volumes", gui)
lordcrc@384
  3126
    return str
lordcrc@384
  3127
lordcrc@384
  3128
def luxEnvironment(scn, gui=None):
lordcrc@384
  3129
    global icon_c_environment
lordcrc@384
  3130
    str = ""
lordcrc@384
  3131
    if scn:
lordcrc@384
  3132
        envtype = luxProp(scn, "env.type", "infinite")
lordcrc@384
  3133
        lsstr = luxIdentifier("LightSource", envtype, ["none", "infinite", "sunsky"], "ENVIRONMENT", "select environment light type", gui, icon_c_environment)
lordcrc@384
  3134
        if gui: gui.newline()
lordcrc@384
  3135
        str = ""
lordcrc@384
  3136
        
lordcrc@384
  3137
        if envtype.get() != "none":
lordcrc@384
  3138
            
lordcrc@384
  3139
            if envtype.get() in ["infinite", "sunsky"]:
lordcrc@384
  3140
                env_lg = luxProp(scn, "env.lightgroup", "default")
lordcrc@384
  3141
                luxString("env.lightgroup", env_lg, "lightgroup", "Environment light group", gui)
lordcrc@384
  3142
                if luxProp(scn, "nolg", "false").get()!="true":
lordcrc@384
  3143
                    lsstr = '\nLightGroup "' + env_lg.get() + '"' + lsstr
lordcrc@384
  3144
                rotZ = luxProp(scn, "env.rotation", 0.0)
lordcrc@384
  3145
                rotY = luxProp(scn, "env.rotationY", 0.0)
lordcrc@384
  3146
                rotX = luxProp(scn, "env.rotationX", 0.0)
lordcrc@384
  3147
                if gui: gui.newline()
lordcrc@384
  3148
                luxFloat("rotation", rotX, 0.0, 360.0, "rot X", "environment rotation X", gui, 0.66)
lordcrc@384
  3149
                luxFloat("rotation", rotY, 0.0, 360.0, "rot Y", "environment rotation Y", gui, 0.66)
lordcrc@384
  3150
                luxFloat("rotation", rotZ, 0.0, 360.0, "rot Z", "environment rotation Z", gui, 0.66)
lordcrc@384
  3151
                if rotZ.get() != 0 or rotY.get() != 0 or rotX.get() != 0:
lordcrc@384
  3152
                    str += "\tRotate %d 1 0 0\n"%(rotX.get())
lordcrc@384
  3153
                    str += "\tRotate %d 0 1 0\n"%(rotY.get())
lordcrc@384
  3154
                    str += "\tRotate %d 0 0 1\n"%(rotZ.get())
lordcrc@384
  3155
            str += "\t"+lsstr
lordcrc@384
  3156
lordcrc@384
  3157
            infinitehassun = 0
lordcrc@384
  3158
            if envtype.get() == "infinite":
lordcrc@384
  3159
                mapping = luxProp(scn, "env.infinite.mapping", "latlong")
lordcrc@384
  3160
                mappings = ["latlong","angular","vcross"]
lordcrc@384
  3161
                mapstr = luxOption("mapping", mapping, mappings, "mapping", "Select mapping type", gui, 0.5)
lordcrc@384
  3162
                map = luxProp(scn, "env.infinite.mapname", "")
lordcrc@384
  3163
                mapstr += luxFile("mapname", map, "map-file", "filename of the environment map", gui, 1.5)
lordcrc@384
  3164
                mapstr += luxFloat("gamma", luxProp(scn, "env.infinite.gamma", 1.0), 0.0, 6.0, "gamma", "", gui, 1.0)
lordcrc@384
  3165
                
lordcrc@384
  3166
                if map.get() != "":
lordcrc@384
  3167
                    str += mapstr
lordcrc@384
  3168
                else:
lordcrc@384
  3169
                    try:
lordcrc@384
  3170
                        worldcolor = Blender.World.Get('World').getHor()
lordcrc@384
  3171
                        str += "\n   \"color L\" [%g %g %g]" %(worldcolor[0], worldcolor[1], worldcolor[2])
lordcrc@384
  3172
                    except: pass
lordcrc@384
  3173
lordcrc@384
  3174
                str += luxFloat("gain", luxProp(scn, "env.infinite.gain", 1.0), 0.0001, 100.0, "gain", "Infinite Env Gain", gui, 1.0)
lordcrc@384
  3175
lordcrc@384
  3176
                infinitesun = luxProp(scn, "env.infinite.hassun", "false")
lordcrc@384
  3177
                luxCollapse("infinitesun", infinitesun, "Sun Component", "Add Sunlight Component", gui, 2.0)
lordcrc@384
  3178
                if(infinitesun.get() == "true"):
lordcrc@384
  3179
                    sun_lg = luxProp(scn, "env.sun_lightgroup", "default")
lordcrc@384
  3180
                    luxString("env.lightgroup", sun_lg, "lightgroup", "Sun component light group", gui)
lordcrc@384
  3181
                    if luxProp(scn, "nolg", "false").get()!="true":
lordcrc@384
  3182
                        str += '\nLightGroup "' + sun_lg.get() + '"'
lordcrc@384
  3183
                    str += "\nLightSource \"sun\" "
lordcrc@384
  3184
                    infinitehassun = 1
lordcrc@384
  3185
lordcrc@384
  3186
lordcrc@384
  3187
            if envtype.get() == "sunsky" or infinitehassun == 1:
lordcrc@384
  3188
                
lordcrc@384
  3189
                
lordcrc@384
  3190
                sun = None
lordcrc@384
  3191
                for obj in scn.objects:
lordcrc@384
  3192
                    if (obj.getType() == "Lamp") and ((obj.Layers & scn.Layers) > 0):
lordcrc@384
  3193
                        if obj.getData(mesh=1).getType() == 1: # sun object # data
lordcrc@384
  3194
                            sun = obj
lordcrc@384
  3195
                if sun:
lordcrc@384
  3196
                    str += luxFloat("gain", luxProp(scn, "env.sunsky.gain", 1.0), 0.0001, 100.0, "gain", "Sky gain", gui)
lordcrc@384
  3197
                    
lordcrc@384
  3198
                    invmatrix = Mathutils.Matrix(sun.getInverseMatrix())
lordcrc@384
  3199
                    str += "\n   \"vector sundir\" [%f %f %f]\n" %(invmatrix[0][2], invmatrix[1][2], invmatrix[2][2])
lordcrc@384
  3200
                    str += luxFloat("relsize", luxProp(scn, "env.sunsky.relsize", 1.0), 0.0, 100.0, "rel.size", "relative sun size", gui)
lordcrc@384
  3201
                    str += luxFloat("turbidity", luxProp(scn, "env.sunsky.turbidity", 2.2), 2.0, 50.0, "turbidity", "Sky turbidity", gui)
lordcrc@384
  3202
                    
lordcrc@384
  3203
                    showGeo = luxProp(sun, 'sc.show', 'false')
lordcrc@384
  3204
                    if gui:
lordcrc@384
  3205
                        luxCollapse("sc.show", showGeo, "Geographic Sun", "Set sun position by world location, date and time", gui, 2.0)
lordcrc@384
  3206
                    if gui and showGeo.get() == 'true':
lordcrc@384
  3207
                        gui.newline("Geographic:")
lordcrc@384
  3208
                        sc = sun_calculator(sun)
lordcrc@384
  3209
                        
lordcrc@384
  3210
                        luxInt("sc.day", luxProp(sun, "sc.day", 1), 1, 31, "day", "Local date: day", gui, 0.66)
lordcrc@384
  3211
                        luxInt("sc.month", luxProp(sun, "sc.month", 1), 1, 12, "month", "Local date: month", gui, 0.67)
lordcrc@384
  3212
                        luxInt("sc.year", luxProp(sun, "sc.year", 2009), 1800, 2100, "year", "Local date: year", gui, 0.66)
lordcrc@384
  3213
                        
lordcrc@384
  3214
                        luxInt("sc.hour", luxProp(sun, "sc.hour", 0), 0, 23, "hour", "Local time: hour", gui, 0.72)
lordcrc@384
  3215
                        luxInt("sc.minute", luxProp(sun, "sc.minute", 0), 0, 59, "minute", "Local time: minute", gui, 0.72)
lordcrc@384
  3216
                        luxBool("sc.dst", luxProp(sun, "sc.dst", 'false'), "DST", "DST", gui, 0.28)
lordcrc@384
  3217
                        r = gui.getRect(0.28,1)
lordcrc@384
  3218
                        Draw.Button("NOW", 0, r[0], r[1], r[2], r[3], "Set to current time", lambda e,v: sc.now())
lordcrc@384
  3219
                        
lordcrc@384
  3220
                        r = gui.getRect(0.3,1)
lordcrc@384
  3221
                        Draw.Button("Preset", 0, r[0], r[1], r[2], r[3], "Choose a preset location", lambda e,v: sc.set_location(
lordcrc@384
  3222
                            Draw.PupTreeMenu(sun_calculator.location_list)
lordcrc@384
  3223
                        ))
lordcrc@384
  3224
                        
lordcrc@384
  3225
                        luxFloat("sc.lat", luxProp(sun, "sc.lat", 0.0), -90.0, 90.0, "lat", "Location: latitude", gui, 0.56)
lordcrc@384
  3226
                        luxFloat("sc.long", luxProp(sun, "sc.long", 0.0), -180.0, 180.0, "long", "Location: longitude", gui, 0.56)
lordcrc@384
  3227
                        luxInt("sc.tz", luxProp(sun, "sc.tz", 0), -12, 12, "timezone", "Local time: timezone offset from GMT", gui, 0.56)
lordcrc@384
  3228
                        
lordcrc@384
  3229
                        r = gui.getRect(2,1)
lordcrc@384
  3230
                        Draw.Button("Calculate", 0, r[0], r[1], r[2], r[3], "Calculate sun's position", lambda e,v: sc.compute())
lordcrc@384
  3231
                    
lordcrc@384
  3232
                else:
lordcrc@384
  3233
                    if gui:
lordcrc@384
  3234
                        gui.newline(); r = gui.getRect(2,1); BGL.glRasterPos2i(r[0],r[1]+5) 
lordcrc@384
  3235
                        Draw.Text("create a blender Sun Lamp")
lordcrc@384
  3236
lordcrc@384
  3237
lordcrc@384
  3238
            str += "\n"
lordcrc@384
  3239
        #if gui: gui.newline("GLOBAL:", 8, 0, None, [0.75,0.5,0.25])
lordcrc@384
  3240
        #luxFloat("scale", luxProp(scn, "global.scale", 1.0), 0.0, 10.0, "scale", "global world scale", gui)
lordcrc@384
  3241
        
lordcrc@384
  3242
    return str
lordcrc@384
  3243
lordcrc@384
  3244
class sun_calculator:
lordcrc@384
  3245
    #Based on SunLight v1.0 by Miguel Kabantsov (miguelkab@gmail.com)
lordcrc@384
  3246
    #Replaces the faulty sun position calculation algorythm with a precise calculation (Source for algorythm: http://de.wikipedia.org/wiki/Sonnenstand),
lordcrc@384
  3247
    #Co-Ordinates: http://www.bcca.org/misc/qiblih/latlong.html
lordcrc@384
  3248
    #Author: Nils-Peter Fischer (Nils-Peter.Fischer@web.de)
lordcrc@384
  3249
    
lordcrc@384
  3250
    sun = None
lordcrc@384
  3251
    
lordcrc@384
  3252
    lat = 0
lordcrc@384
  3253
    long = 0
lordcrc@384
  3254
    
lordcrc@384
  3255
    hour = 0
lordcrc@384
  3256
    min = 0
lordcrc@384
  3257
    tz = 0
lordcrc@384
  3258
    dst = 'false'
lordcrc@384
  3259
    
lordcrc@384
  3260
    day = 0
lordcrc@384
  3261
    month = 0
lordcrc@384
  3262
    year = 0
lordcrc@384
  3263
    
lordcrc@384
  3264
    location_list = [
lordcrc@384
  3265
        ("EUROPE",[
lordcrc@384
  3266
            ("Antwerp, Belgium",          67),
lordcrc@384
  3267
            ("Berlin, Germany",            1),
lordcrc@384
  3268
            ("Bratislava, Slovak Republic", 70),
lordcrc@384
  3269
            ("Brno, Czech Republic",      72),
lordcrc@384
  3270
            ("Brussles, Belgium",         68),
lordcrc@384
  3271
            ("Geneva, Switzerland",       65),
lordcrc@384
  3272
            ("Helsinki, Finland",          7),
lordcrc@384
  3273
            ("Innsbruck, Austria",        62),
lordcrc@384
  3274
            ("Kyiv, Ukraine",             64),
lordcrc@384
  3275
            ("London, England",           10),
lordcrc@384
  3276
            ("Lyon, France",              66),
lordcrc@384
  3277
            ("Nitra, Slovak Republic",    69),
lordcrc@384
  3278
            ("Oslo, Norway",              58),
lordcrc@384
  3279
            ("Paris, France",             15),
lordcrc@384
  3280
            ("Praha, Czech Republic",     71),
lordcrc@384
  3281
            ("Rome, Italy",               18),
lordcrc@384
  3282
            ("Telfs, Austria",            63),
lordcrc@384
  3283
            ("Warsaw, Poland",            74),
lordcrc@384
  3284
            ("Wroclaw, Poland",           73),
lordcrc@384
  3285
            ("Zurich, Switzerland",       21),
lordcrc@384
  3286
        ]),
lordcrc@384
  3287
    
lordcrc@384
  3288
        ("WORLD CITIES", [
lordcrc@384
  3289
            ("Beijing, China",             0),
lordcrc@384
  3290
            ("Bombay, India",              2),
lordcrc@384
  3291
            ("Buenos Aires, Argentina",    3),
lordcrc@384
  3292
            ("Cairo, Egypt",               4),
lordcrc@384
  3293
            ("Cape Town, South Africa",    5),
lordcrc@384
  3294
            ("Caracas, Venezuela",         6),
lordcrc@384
  3295
            ("Curitiba, Brazil",          60),
lordcrc@384
  3296
            ("Hong Kong, China",           8),
lordcrc@384
  3297
            ("Jerusalem, Israel",          9),
lordcrc@384
  3298
            ("Joinville, Brazil",         61),
lordcrc@384
  3299
            ("Mexico City, Mexico",       11),
lordcrc@384
  3300
            ("Moscow, Russia",            12),
lordcrc@384
  3301
            ("New Delhi, India",          13),
lordcrc@384
  3302
            ("Ottawa, Canada",            14),
lordcrc@384
  3303
            ("Rio de Janeiro, Brazil",    16),
lordcrc@384
  3304
            ("Riyadh, Saudi Arabia",      17),
lordcrc@384
  3305
            ("Sao Paulo, Brazil",         59),
lordcrc@384
  3306
            ("Sydney, Australia",         19),
lordcrc@384
  3307
            ("Tokyo, Japan",              20), 
lordcrc@384
  3308
        ]),
lordcrc@384
  3309
        
lordcrc@384
  3310
        ("US CITIES", [
lordcrc@384
  3311
            ("Albuquerque, NM",           22),
lordcrc@384
  3312
            ("Anchorage, AK",             23),
lordcrc@384
  3313
            ("Atlanta, GA",               24),
lordcrc@384
  3314
            ("Austin, TX",                25),
lordcrc@384
  3315
            ("Birmingham, AL",            26),
lordcrc@384
  3316
            ("Bismarck, ND",              27),
lordcrc@384
  3317
            ("Boston, MA",                28),
lordcrc@384
  3318
            ("Boulder, CO",               29),
lordcrc@384
  3319
            ("Chicago, IL",               30),
lordcrc@384
  3320
            ("Dallas, TX",                31),
lordcrc@384
  3321
            ("Denver, CO",                32),
lordcrc@384
  3322
            ("Detroit, MI",               33),
lordcrc@384
  3323
            ("Honolulu, HI",              34),
lordcrc@384
  3324
            ("Houston, TX",               35),
lordcrc@384
  3325
            ("Indianapolis, IN",          36),
lordcrc@384
  3326
            ("Jackson, MS",               37),
lordcrc@384
  3327
            ("Kansas City, MO",           38),
lordcrc@384
  3328
            ("Los Angeles, CA",           39),
lordcrc@384
  3329
            ("Menomonee Falls, WI",       40),
lordcrc@384
  3330
            ("Miami, FL",                 41),
lordcrc@384
  3331
            ("Minneapolis, MN",           42),
lordcrc@384
  3332
            ("New Orleans, LA",           43),
lordcrc@384
  3333
            ("New York City, NY",         44),
lordcrc@384
  3334
            ("Oklahoma City, OK",         45),
lordcrc@384
  3335
            ("Philadelphia, PA",          46),
lordcrc@384
  3336
            ("Phoenix, AZ",               47),
lordcrc@384
  3337
            ("Pittsburgh, PA",            48),
lordcrc@384
  3338
            ("Portland, ME",              49),
lordcrc@384
  3339
            ("Portland, OR",              50),
lordcrc@384
  3340
            ("Raleigh, NC",               51),
lordcrc@384
  3341
            ("Richmond, VA",              52),
lordcrc@384
  3342
            ("Saint Louis, MO",           53),
lordcrc@384
  3343
            ("San Diego, CA",             54),
lordcrc@384
  3344
            ("San Francisco, CA",         55),
lordcrc@384
  3345
            ("Seattle, WA",               56),
lordcrc@384
  3346
            ("Washington DC",             57),
lordcrc@384
  3347
        ])
lordcrc@384
  3348
    ]
lordcrc@384
  3349
lordcrc@384
  3350
    location_data = {
lordcrc@384
  3351
        # Europe
lordcrc@384
  3352
        67:   ( 51.2167, 4.4, 1),
lordcrc@384
  3353
        1:    ( 52.33, 13.30, 1),
lordcrc@384
  3354
        70:   ( 48.17, 17.17, 1),
lordcrc@384
  3355
        72:   ( 49.2, 16.63, 1),
lordcrc@384
  3356
        68:   ( 58.8467, 4.3525, 1),
lordcrc@384
  3357
        65:   ( 46.217, 6.150, 1),
lordcrc@384
  3358
        7:    ( 60.1667, 24.9667,2),
lordcrc@384
  3359
        62:   ( 47.2672, 11.3928, 1),
lordcrc@384
  3360
        64:   ( 50.75, 30.0833, 2),
lordcrc@384
  3361
        10:   ( 51.50, 0.0, 0),
lordcrc@384
  3362
        66:   ( 45.767, 4.833, 1),
lordcrc@384
  3363
        69:   ( 48.32, 18.07, 1),
lordcrc@384
  3364
        58:   ( 59.56, 10.41, 1),
lordcrc@384
  3365
        15:   ( 48.8667, 2.667, 1),
lordcrc@384
  3366
        71:   ( 50.08, 14.46, 1),
lordcrc@384
  3367
        18:   ( 41.90, 12.4833, 1),
lordcrc@384
  3368
        63:   ( 47.3, 11.0667, 1),
lordcrc@384
  3369
        74:   ( 52.232, 21.008, 1),
lordcrc@384
  3370
        73:   ( 51.108, 17.038, 1),
lordcrc@384
  3371
        21:   ( 47.3833, 8.5333, 1),
lordcrc@384
  3372
    
lordcrc@384
  3373
        # World Cities
lordcrc@384
  3374
        0:    ( 39.9167, 116.4167, 8),
lordcrc@384
  3375
        2:    ( 18.9333, 72.8333, 5.5),
lordcrc@384
  3376
        3:    (-34.60, -58.45, -3),
lordcrc@384
  3377
        4:    ( 30.10, 31.3667, 2),
lordcrc@384
  3378
        5:    (-33.9167, 18.3667, 2),
lordcrc@384
  3379
        6:    ( 10.50, -66.9333, -4),
lordcrc@384
  3380
        60:   (-25.4278, -49.2731, -3),
lordcrc@384
  3381
        8:    ( 22.25, 114.1667, 8),
lordcrc@384
  3382
        9:    ( 31.7833, 35.2333, 2),
lordcrc@384
  3383
        61:   (-29.3044, -48.8456, -3),
lordcrc@384
  3384
        11:   ( 19.4, -99.15, -6),
lordcrc@384
  3385
        12:   ( 55.75, 37.5833, 3),
lordcrc@384
  3386
        13:   ( 28.6, 77.2, 5.5),
lordcrc@384
  3387
        14:   ( 45.41667, -75.7, -5),
lordcrc@384
  3388
        16:   (-22.90, -43.2333, -3),
lordcrc@384
  3389
        17:   ( 24.633, 46.71667, 3),
lordcrc@384
  3390
        59:   ( -23.5475, -46.6361, -3),
lordcrc@384
  3391
        19:   (-33.8667,151.2167,10),
lordcrc@384
  3392
        20:   ( 35.70, 139.7667, 9), 
lordcrc@384
  3393
    
lordcrc@384
  3394
        # US Cities
lordcrc@384
  3395
        22:   ( 35.0833, -106.65, -7),
lordcrc@384
  3396
        23:   ( 61.217, -149.90, -9),
lordcrc@384
  3397
        24:   ( 33.733, -84.383, -5),
lordcrc@384
  3398
        25:   ( 30.283, -97.733, -6),
lordcrc@384
  3399
        26:   ( 33.521, -86.8025, -6),
lordcrc@384
  3400
        27:   ( 46.817, -100.783, -6),
lordcrc@384
  3401
        28:   ( 42.35, -71.05, -5),
lordcrc@384
  3402
        29:   ( 40.125, -105.237, -7),
lordcrc@384
  3403
        30:   ( 41.85, -87.65, -6),
lordcrc@384
  3404
        31:   ( 32.46, -96.47, -6),
lordcrc@384
  3405
        32:   ( 39.733, -104.983, -7),
lordcrc@384
  3406
        33:   ( 42.333, -83.05, -5),
lordcrc@384
  3407
        34:   ( 21.30, -157.85, -10),
lordcrc@384
  3408
        35:   ( 29.75, -95.35, -6),
lordcrc@384
  3409
        36:   ( 39.767, -86.15, -5),
lordcrc@384
  3410
        37:   ( 32.283, -90.183, -6),
lordcrc@384
  3411
        38:   ( 39.083, -94.567, -6),
lordcrc@384
  3412
        39:   ( 34.05, -118.233, -8),
lordcrc@384
  3413
        40:   ( 43.11, -88.10, -6),
lordcrc@384
  3414
        41:   ( 25.767, -80.183, -5),
lordcrc@384
  3415
        42:   ( 44.967, -93.25, -6),
lordcrc@384
  3416
        43:   ( 29.95, -90.067, -6),
lordcrc@384
  3417
        44:   ( 40.7167, -74.0167, -5),
lordcrc@384
  3418
        45:   ( 35.483, -97.533, -6),
lordcrc@384
  3419
        46:   ( 39.95, -75.15, -5),
lordcrc@384
  3420
        47:   ( 33.433, -112.067,-7),
lordcrc@384
  3421
        48:   ( 40.433, -79.9833, -5),
lordcrc@384
  3422
        49:   ( 43.666, -70.283, -5),
lordcrc@384
  3423
        50:   ( 45.517, -122.65, -8),
lordcrc@384
  3424
        51:   ( 35.783, -78.65, -5),
lordcrc@384
  3425
        52:   ( 37.5667, -77.450, -5),
lordcrc@384
  3426
        53:   ( 38.6167, -90.1833, -6),
lordcrc@384
  3427
        54:   ( 32.7667, -117.2167, -8),
lordcrc@384
  3428
        55:   ( 37.7667, -122.4167, -8),
lordcrc@384
  3429
        56:   ( 47.60, -122.3167, -8),
lordcrc@384
  3430
        57:   ( 38.8833, -77.0333, -5),
lordcrc@384
  3431
    }
lordcrc@384
  3432
lordcrc@384
  3433
    def __init__(self, sun):
lordcrc@384
  3434
        self.sun = sun
lordcrc@384
  3435
    
lordcrc@384
  3436
    def now(self):
lordcrc@384
  3437
        ct = time.localtime()
lordcrc@384
  3438
        
lordcrc@384
  3439
        if ct[8] == 0:
lordcrc@384
  3440
            dst = 'false'
lordcrc@384
  3441
        else:
lordcrc@384
  3442
            dst = 'true'
lordcrc@384
  3443
        
lordcrc@384
  3444
        luxProp(self.sun, 'sc.day', 0).set(ct[2])
lordcrc@384
  3445
        luxProp(self.sun, 'sc.month', 0).set(ct[1])
lordcrc@384
  3446
        luxProp(self.sun, 'sc.year', 0).set(ct[0])
lordcrc@384
  3447
        luxProp(self.sun, 'sc.hour', 0).set(ct[3])
lordcrc@384
  3448
        luxProp(self.sun, 'sc.minute', 0).set(ct[4])
lordcrc@384
  3449
        luxProp(self.sun, 'sc.dst', 0).set(dst)
lordcrc@384
  3450
        
lordcrc@384
  3451
        self.compute()
lordcrc@384
  3452
        
lordcrc@384
  3453
    def set_location(self, location):
lordcrc@384
  3454
        if location < 0: return
lordcrc@384
  3455
        
lordcrc@384
  3456
        lat, long, tz = self.location_data[location]
lordcrc@384
  3457
        luxProp(self.sun, "sc.lat", 0).set(lat)
lordcrc@384
  3458
        luxProp(self.sun, "sc.long", 0).set(long)
lordcrc@384
  3459
        luxProp(self.sun, "sc.tz", 0).set(tz)
lordcrc@384
  3460
        
lordcrc@384
  3461
        self.compute()
lordcrc@384
  3462
    
lordcrc@384
  3463
    def compute(self):
lordcrc@384
  3464
        
lordcrc@384
  3465
        self.lat  = luxProp(self.sun, "sc.lat", 0).get()
lordcrc@384
  3466
        self.long = luxProp(self.sun, "sc.long", 0).get()
lordcrc@384
  3467
        self.tz   = luxProp(self.sun, "sc.tz", 0).get()
lordcrc@384
  3468
        
lordcrc@384
  3469
        self.hour = luxProp(self.sun, "sc.hour", 0).get()
lordcrc@384
  3470
        self.min  = luxProp(self.sun, "sc.minute", 0).get()
lordcrc@384
  3471
        self.dst  = luxProp(self.sun, "sc.dst", 'false').get()
lordcrc@384
  3472
        if self.dst == 'true':
lordcrc@384
  3473
            self.dst = 1
lordcrc@384
  3474
        else:
lordcrc@384
  3475
            self.dst = 0
lordcrc@384
  3476
        
lordcrc@384
  3477
        self.day   = luxProp(self.sun, "sc.day", 0).get()
lordcrc@384
  3478
        self.month = luxProp(self.sun, "sc.month", 0).get()
lordcrc@384
  3479
        self.year  = luxProp(self.sun, "sc.year", 0).get()
lordcrc@384
  3480
        
lordcrc@384
  3481
        
lordcrc@384
  3482
        az,el = self.geoSunData(
lordcrc@384
  3483
            self.lat,
lordcrc@384
  3484
            self.long,
lordcrc@384
  3485
            self.year,
lordcrc@384
  3486
            self.month,
lordcrc@384
  3487
            self.day,
lordcrc@384
  3488
            self.hour + self.min/60.0,
lordcrc@384
  3489
            -self.tz + self.dst
lordcrc@384
  3490
        )
lordcrc@384
  3491
        
lordcrc@384
  3492
        self.sun.rot = math.radians(90-el), 0, math.radians(-az)
lordcrc@384
  3493
        
lordcrc@384
  3494
        Window.Redraw()
lordcrc@384
  3495
        
lordcrc@384
  3496
        
lordcrc@384
  3497
    # --- THE FOLLOWING METHODS ARE ADAPTED FROM LUXMAYA ---
lordcrc@384
  3498
    
lordcrc@384
  3499
    # mathematical helpers
lordcrc@384
  3500
    def sind(self, deg):
lordcrc@384
  3501
        return math.sin(math.radians(deg))
lordcrc@384
  3502
    
lordcrc@384
  3503
    def cosd(self, deg):
lordcrc@384
  3504
        return math.cos(math.radians(deg))
lordcrc@384
  3505
    
lordcrc@384
  3506
    def tand(self, deg):
lordcrc@384
  3507
        return math.tan(math.radians(deg))
lordcrc@384
  3508
    
lordcrc@384
  3509
    def asind(self, deg):
lordcrc@384
  3510
        return math.degrees(math.asin(deg))
lordcrc@384
  3511
    
lordcrc@384
  3512
    def atand(self, deg):
lordcrc@384
  3513
        return math.degrees(math.atan(deg))
lordcrc@384
  3514
    
lordcrc@384
  3515
    
lordcrc@384
  3516
    def geo_sun_astronomicJulianDate(self, Year, Month, Day, LocalTime, Timezone):
lordcrc@384
  3517
        """
lordcrc@384
  3518
        See quoted source in class header for explanation
lordcrc@384
  3519
        """
lordcrc@384
  3520
        
lordcrc@384
  3521
        if Month > 2.0:
lordcrc@384
  3522
            Y = Year
lordcrc@384
  3523
            M = Month
lordcrc@384
  3524
        else:
lordcrc@384
  3525
            Y = Year - 1.0
lordcrc@384
  3526
            M = Month + 12.0
lordcrc@384
  3527
            
lordcrc@384
  3528
        UT = LocalTime - Timezone
lordcrc@384
  3529
        hour = UT / 24.0
lordcrc@384
  3530
        A = int(Y/100.0)
lordcrc@384
  3531
        B = 2.0 - A+int(A/4.0)
lordcrc@384
  3532
        
lordcrc@384
  3533
        JD = math.floor(365.25*(Y+4716.0)) + math.floor(30.6001*(M+1.0)) + Day + hour + B - 1524.4
lordcrc@384
  3534
        
lordcrc@384
  3535
        return JD
lordcrc@384
  3536
    
lordcrc@384
  3537
    def geoSunData(self, Latitude, Longitude, Year, Month, Day, LocalTime, Timezone):
lordcrc@384
  3538
        """
lordcrc@384
  3539
        See quoted source in class header for explanation
lordcrc@384
  3540
        """
lordcrc@384
  3541
        
lordcrc@384
  3542
        JD = self.geo_sun_astronomicJulianDate(Year, Month, Day, LocalTime, Timezone)
lordcrc@384
  3543
        
lordcrc@384
  3544
        phi = Latitude
lordcrc@384
  3545
        llambda = Longitude
lordcrc@384
  3546
                
lordcrc@384
  3547
        n = JD - 2451545.0
lordcrc@384
  3548
        LDeg = (280.460 + 0.9856474*n) - (math.floor((280.460 + 0.9856474*n)/360.0) * 360.0)
lordcrc@384
  3549
        gDeg = (357.528 + 0.9856003*n) - (math.floor((357.528 + 0.9856003*n)/360.0) * 360.0)
lordcrc@384
  3550
        LambdaDeg = LDeg + 1.915 * self.sind(gDeg) + 0.02 * self.sind(2.0*gDeg)
lordcrc@384
  3551
        
lordcrc@384
  3552
        epsilonDeg = 23.439 - 0.0000004*n
lordcrc@384
  3553
        
lordcrc@384
  3554
        alphaDeg = self.atand( (self.cosd(epsilonDeg) * self.sind(LambdaDeg)) / self.cosd(LambdaDeg) )
lordcrc@384
  3555
        if self.cosd(LambdaDeg) < 0.0:
lordcrc@384
  3556
            alphaDeg += 180.0
lordcrc@384
  3557
            
lordcrc@384
  3558
        deltaDeg = self.asind( self.sind(epsilonDeg) * self.sind(LambdaDeg) )
lordcrc@384
  3559
        
lordcrc@384
  3560
        JDNull = self.geo_sun_astronomicJulianDate(Year, Month, Day, 0.0, 0.0)
lordcrc@384
  3561
        
lordcrc@384
  3562
        TNull = (JDNull - 2451545.0) / 36525.0
lordcrc@384
  3563
        T = LocalTime - Timezone
lordcrc@384
  3564
        
lordcrc@384
  3565
        thetaGh = 6.697376 + 2400.05134*TNull + 1.002738*T
lordcrc@384
  3566
        thetaGh -= math.floor(thetaGh/24.0) * 24.0
lordcrc@384
  3567
        
lordcrc@384
  3568
        thetaG = thetaGh * 15.0
lordcrc@384
  3569
        theta = thetaG + llambda
lordcrc@384
  3570
        
lordcrc@384
  3571
        tau = theta - alphaDeg
lordcrc@384
  3572
        
lordcrc@384
  3573
        a = self.atand( self.sind(tau) / ( self.cosd(tau)*self.sind(phi) - self.tand(deltaDeg)*self.cosd(phi)) )
lordcrc@384
  3574
        if self.cosd(tau)*self.sind(phi) - self.tand(deltaDeg)*self.cosd(phi) < 0.0:
lordcrc@384
  3575
            a += 180.0
lordcrc@384
  3576
        
lordcrc@384
  3577
        h = self.asind( self.cosd(deltaDeg)*self.cosd(tau)*self.cosd(phi) + self.sind(deltaDeg)*self.sind(phi) )
lordcrc@384
  3578
        
lordcrc@384
  3579
        R = 1.02 / (self.tand (h+(10.3/(h+5.11))))
lordcrc@384
  3580
        hR = h + R/60.0
lordcrc@384
  3581
        
lordcrc@384
  3582
        azimuth = a
lordcrc@384
  3583
        elevation = hR
lordcrc@384
  3584
        
lordcrc@384
  3585
        return azimuth, elevation
lordcrc@384
  3586
lordcrc@384
  3587
def luxAccelerator(scn, gui=None):
lordcrc@384
  3588
    str = ""
lordcrc@384
  3589
    if scn:
lordcrc@384
  3590
        acceltype = luxProp(scn, "accelerator.type", "tabreckdtree")
lordcrc@384
  3591
        str = luxIdentifier("Accelerator", acceltype, ["none", "tabreckdtree", "grid", "bvh", "qbvh"], "ACCEL", "select accelerator type", gui)
lordcrc@384
  3592
        if acceltype.get() == "tabreckdtree":
lordcrc@384
  3593
            if gui: gui.newline()
lordcrc@384
  3594
            str += luxInt("intersectcost", luxProp(scn, "accelerator.kdtree.interscost", 80), 0, 1000, "inters.cost", "specifies how expensive ray-object intersections are", gui)
lordcrc@384
  3595
            str += luxInt("traversalcost", luxProp(scn, "accelerator.kdtree.travcost", 1), 0, 1000, "trav.cost", "specifies how expensive traversing a ray through the kdtree is", gui)
lordcrc@384
  3596
            if gui: gui.newline()
lordcrc@384
  3597
            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)
lordcrc@384
  3598
            if gui: gui.newline()
lordcrc@384
  3599
            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)
lordcrc@384
  3600
            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)
lordcrc@384
  3601
        if acceltype.get() == "unsafekdtree":
lordcrc@384
  3602
            if gui: gui.newline()
lordcrc@384
  3603
            str += luxInt("intersectcost", luxProp(scn, "accelerator.kdtree.interscost", 80), 0, 1000, "inters.cost", "specifies how expensive ray-object intersections are", gui)
lordcrc@384
  3604
            str += luxInt("traversalcost", luxProp(scn, "accelerator.kdtree.travcost", 1), 0, 1000, "trav.cost", "specifies how expensive traversing a ray through the kdtree is", gui)
lordcrc@384
  3605
            if gui: gui.newline()
lordcrc@384
  3606
            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)
lordcrc@384
  3607
            if gui: gui.newline()
lordcrc@384
  3608
            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)
lordcrc@384
  3609
            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)
lordcrc@384
  3610
        if acceltype.get() == "grid":
lordcrc@384
  3611
            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)
lordcrc@384
  3612
        if acceltype.get() == "qbvh":
lordcrc@384
  3613
            if gui: gui.newline()
lordcrc@384
  3614
            str += luxInt("maxprimsperleaf", luxProp(scn, "accelerator.qbvh.maxprimsperleaf", 4), 1, 64, "maxprimsperleaf", "Maximum number of primitives to leave in one leaf node", gui)
lordcrc@384
  3615
    return str
lordcrc@384
  3616
lordcrc@384
  3617
def luxSystem(scn, gui=None):
lordcrc@384
  3618
    if scn:
lordcrc@384
  3619
        if gui: gui.newline("PATHS:", 10)
lordcrc@384
  3620
        lp = luxProp(scn, "lux", "")
lordcrc@384
  3621
        lp.set(Blender.sys.dirname(lp.get())+os.sep)
lordcrc@384
  3622
        luxPath("LUX dir", lp, "lux binary dir", "Lux installation path", gui, 2.0)
lordcrc@384
  3623
lordcrc@384
  3624
#        luxFile("GUI filename", luxProp(scn, "lux", ""), "lux-file", "filename and path of the lux GUI executable", gui, 2.0)
lordcrc@384
  3625
#        luxFile("Console filename", luxProp(scn, "luxconsole", ""), "lux-file-console", "filename and path of the lux console executable", gui, 2.0)
lordcrc@384
  3626
        if gui: gui.newline()
lordcrc@384
  3627
        luxFile("datadir", luxProp(scn, "datadir", ""), "default out dir", "default.lxs save path", gui, 2.0)
lordcrc@384
  3628
lordcrc@384
  3629
        if gui: gui.newline()
lordcrc@384
  3630
        pm = ["absolute","relative","flat"]
lordcrc@384
  3631
        luxOption("pathmode", luxProp(scn, "pathmode", "absolute"), pm, "path-mode", "select format for paths on export", gui, 2.0)
lordcrc@384
  3632
lordcrc@384
  3633
        if gui: gui.newline("PRIORITY:", 10)
lordcrc@384
  3634
        luxnice = luxProp(scn, "luxnice", 10)
lordcrc@384
  3635
        if osys.platform=="win32":
lordcrc@384
  3636
            r = gui.getRect(2, 1)
lordcrc@384
  3637
            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))
lordcrc@384
  3638
        else: luxInt("nice", luxnice, -20, 19, "nice", "nice value. Range goes from -20 (highest priority) to 19 (lowest)", gui)
lordcrc@384
  3639
lordcrc@384
  3640
        luxBool("noopengl", luxProp(scn, "noopengl", "false"), "Disable OpenGL", "(workaround for some buggy display drivers)", gui, 1.0)
lordcrc@384
  3641
lordcrc@384
  3642
lordcrc@384
  3643
        if gui: gui.newline("THREADS:", 10)
lordcrc@384
  3644
        autothreads = luxProp(scn, "autothreads", "true")
lordcrc@384
  3645
        luxBool("autothreads", autothreads, "Auto Detect", "Automatically use all available processors", gui, 1.0)
lordcrc@384
  3646
        if autothreads.get()=="false":
lordcrc@384
  3647
            luxInt("threads", luxProp(scn, "threads", 1), 1, 100, "threads", "number of threads used for rendering", gui, 1.0)
doug@404
  3648
#        luxBool('export.threaded', luxProp(scn, 'export.threaded', 'true'), 'Pipe in background', 'When using pipe export, do not block Blender UI', gui, 1.0)
lordcrc@384
  3649
lordcrc@384
  3650
        if gui: gui.newline("ANIM:", 10)
lordcrc@384
  3651
        useparamkeys = luxProp(scn, "useparamkeys", "false")
lordcrc@384
  3652
        luxBool("useparamkeys", useparamkeys, "Enable Parameter IPO Keyframing", "Enables keyframing of luxblend parameters", gui, 2.0)
lordcrc@384
  3653
lordcrc@384
  3654
        if gui: gui.newline("PARAMS:", 10)
lordcrc@384
  3655
        parammodeadvanced = luxProp(scn, "parammodeadvanced", "false")
lordcrc@384
  3656
        luxBool("parammodeadvanced", parammodeadvanced, "Default Advanced Parameters", "Always use advanced parameters by default", gui, 2.0)
lordcrc@384
  3657
lordcrc@384
  3658
        if gui: gui.newline("PREVIEW:", 10)
lordcrc@384
  3659
        qs = ["low","medium","high","very high"]
lordcrc@384
  3660
        defprevmat = luxProp(scn, "defprevmat", "high")
lordcrc@384
  3661
        luxOption("defprevmat", defprevmat, qs, "Materials", "Select default preview quality in material editor for materials", gui, 1.0)
lordcrc@384
  3662
lordcrc@384
  3663
        if gui: gui.newline("GAMMA:", 10)
lordcrc@384
  3664
        luxBool("RGC", luxProp(scn, "RGC", "true"), "RGC", "use reverse gamma correction", gui)
lordcrc@384
  3665
        luxBool("ColClamp", luxProp(scn, "colorclamp", "false"), "ColClamp", "clamp all colors to 0.0-0.9", gui)
lordcrc@384
  3666
        if gui: gui.newline("MESH:", 10)
lordcrc@384
  3667
        luxBool("mesh_optimizing", luxProp(scn, "mesh_optimizing", "true"), "optimize meshes", "Optimize meshes during export", gui, 2.0)
lordcrc@384
  3668
        #luxInt("trianglemesh thr", luxProp(scn, "trianglemesh_thr", 0), 0, 10000000, "trianglemesh threshold", "Vertex threshold for exporting (wald) trianglemesh object(s)", gui, 2.0)
lordcrc@384
  3669
        #if gui: gui.newline()
lordcrc@384
  3670
        #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)
lordcrc@384
  3671
        if gui: gui.newline("INSTANCING:", 10)
lordcrc@384
  3672
        luxInt("instancing_threshold", luxProp(scn, "instancing_threshold", 2), 0, 1000000, "object instancing threshold", "Threshold to created instanced objects", gui, 2.0)
lordcrc@384
  3673
        
lordcrc@384
  3674
        # dougal2 packed images, enable this when implemented in Lux itself
lordcrc@384
  3675
        #if gui: gui.newline('TEXTURES:',10)
lordcrc@384
  3676
        #impack = luxProp(scn, 'packtextures', 'false')
lordcrc@384
  3677
        #luxBool('impack', impack, 'Pack All Images', '', gui, 2.0)
lordcrc@384
  3678
        
lordcrc@384
  3679
        if gui: 
lordcrc@384
  3680
            network=luxProp(scn,"network","false")
lordcrc@384
  3681
            gui.newline("NETWORK:", 10)
lordcrc@384
  3682
            luxCollapse("network",network, "network", "enable network option", gui, 2.0)
lordcrc@384
  3683
            if(network.get() == "true"):
lordcrc@384
  3684
                network_use_file=luxProp(scn,"network_use_file","false")
lordcrc@384
  3685
                luxBool ("use file",network_use_file,"use file", "get list of servers from file; one per line",gui,2.0)
lordcrc@384
  3686
                if (network_use_file.get() == "true"):
lordcrc@384
  3687
                    luxFile("file", luxProp(scn, "network_file_path", ""), "file", "file where servers are defined", gui, 1.0)         
lordcrc@384
  3688
                else :     
lordcrc@384
  3689
                    #gui.newline("")
lordcrc@384
  3690
                    luxString("Servers",luxProp(scn,"network_servers",""),"servers","coma separated list of servers",gui,1.0)
lordcrc@384
  3691
                #gui.newline("")
lordcrc@384
  3692
                luxInt("network_interval",luxProp(scn,"newtork_interval",180),0,300,"update interval","interval between network refresh",gui)
lordcrc@384
  3693
lordcrc@384
  3694
lordcrc@384
  3695
def scalelist(list, factor):
lordcrc@384
  3696
    for i in range(len(list)): list[i] = list[i] * factor
lordcrc@384
  3697
    return list
lordcrc@384
  3698
lordcrc@384
  3699
lordcrc@384
  3700
def luxMapping(key, mat, gui, level=0):
lordcrc@384
  3701
    global icon_map2d, icon_map2dparam
lordcrc@384
  3702
    if gui: gui.newline("2Dmap:", -2, level, icon_map2d)
lordcrc@384
  3703
    mapping = luxProp(mat, key+".mapping", "uv")
lordcrc@384
  3704
    mappings = ["uv","spherical","cylindrical","planar"]
lordcrc@384
  3705
    str = luxOption("mapping", mapping, mappings, "mapping", "", gui, 0.5)
lordcrc@384
  3706
    if mapping.get() == "uv":
lordcrc@384
  3707
    	if gui: gui.newline()
lordcrc@384
  3708
        str += luxFloat("uscale", luxProp(mat, key+".uscale", 1.0), -100.0, 100.0, "Us", "u-scale", gui, 0.5)
lordcrc@384
  3709
        str += luxFloat("vscale", luxProp(mat, key+".vscale", -1.0), -100.0, 100.0, "Vs", "v-scale", gui, 0.5)
lordcrc@384
  3710
        str += luxFloat("udelta", luxProp(mat, key+".udelta", 0.0), -100.0, 100.0, "Ud", "u-delta", gui, 0.5)
lordcrc@384
  3711
        str += luxFloat("vdelta", luxProp(mat, key+".vdelta", 0.0), -100.0, 100.0, "Vd", "v-delta", gui, 0.5)
lordcrc@384
  3712
    if mapping.get() == "planar":
lordcrc@384
  3713
        str += luxFloat("udelta", luxProp(mat, key+".udelta", 0.0), -100.0, 100.0, "Ud", "u-delta", gui, 0.75)
lordcrc@384
  3714
        str += luxFloat("vdelta", luxProp(mat, key+".vdelta", 0.0), -100.0, 100.0, "Vd", "v-delta", gui, 0.75)
lordcrc@384
  3715
        if gui: gui.newline("v1:", -2, level+1, icon_map2dparam)
lordcrc@384
  3716
        str += luxVector("v1", luxProp(mat, key+".v1", "1 0 0"), -100.0, 100.0, "v1", "v1-vector", gui, 2.0)
lordcrc@384
  3717
        if gui: gui.newline("v2:", -2, level+1, icon_map2dparam)
lordcrc@384
  3718
        str += luxVector("v2", luxProp(mat, key+".v2", "0 1 0"), -100.0, 100.0, "v2", "v2-vector", gui, 2.0)
lordcrc@384
  3719
    return str
lordcrc@384
  3720
lordcrc@384
  3721
def lux3DMapping(key, mat, gui, level=0):
lordcrc@384
  3722
    global icon_map3dparam
lordcrc@384
  3723
    str = ""
lordcrc@384
  3724
    if gui: gui.newline("scale:", -2, level, icon_map3dparam)
lordcrc@384
  3725
    str += luxVectorUniform("scale", luxProp(mat, key+".3dscale", 1.0), 0.001, 1000.0, "scale", "scale-vector", gui, 2.0)
lordcrc@384
  3726
    if gui: gui.newline("rot:", -2, level, icon_map3dparam)
lordcrc@384
  3727
    str += luxVector("rotate", luxProp(mat, key+".3drotate", "0 0 0"), -360.0, 360.0, "rotate", "rotate-vector", gui, 2.0)
lordcrc@384
  3728
    if gui: gui.newline("move:", -2, level, icon_map3dparam)
lordcrc@384
  3729
    str += luxVector("translate", luxProp(mat, key+".3dtranslate", "0 0 0"), -1000.0, 1000.0, "move", "translate-vector", gui, 2.0)
lordcrc@384
  3730
    return str
lordcrc@384
  3731
    
lordcrc@384
  3732
def getTreeNameById(tree, i): # helper function to retrive name of the selected treemenu-item
lordcrc@384
  3733
    for t in tree:
lordcrc@384
  3734
        if type(t)==types.TupleType:
lordcrc@384
  3735
            if type(t[1])==types.ListType: 
lordcrc@384
  3736
                n=getTreeNameById(t[1], i)
lordcrc@384
  3737
                if n: return n
lordcrc@384
  3738
            elif t[1]==i: return t[0]
lordcrc@384
  3739
    return None    
lordcrc@384
  3740
lordcrc@384
  3741
def luxTexture(name, parentkey, type, default, min, max, caption, hint, mat, gui, matlevel, texlevel=0, lightsource=0, overrideicon=""):
lordcrc@384
  3742
    global icon_tex, icon_texcol, icon_texmix, icon_texmixcol, icon_texparam, icon_spectex
lordcrc@384
  3743
    def c(t1, t2):
lordcrc@384
  3744
        return (t1[0]+t2[0], t1[1]+t2[1])
lordcrc@384
  3745
    def alternativedefault(type, default):
lordcrc@384
  3746
        if type=="float": return 0.0
lordcrc@384
  3747
        else: return "0.0 0.0 0.0"
lordcrc@384
  3748
    level = matlevel + texlevel
lordcrc@384
  3749
    keyname = "%s:%s"%(parentkey, name)
lordcrc@384
  3750
    texname = "%s:%s"%(mat.getName(), keyname)
lordcrc@384
  3751
#    if gui: gui.newline(caption+":", 0, level)
lordcrc@384
  3752
    if(lightsource == 0):
lordcrc@384
  3753
        if texlevel == 0: texture = luxProp(mat, keyname+".texture", "imagemap")
lordcrc@384
  3754
        else: texture = luxProp(mat, keyname+".texture", "constant")
lordcrc@384
  3755
    else:
lordcrc@384
  3756
        texture = luxProp(mat, keyname+".texture", "blackbody")
lordcrc@384
  3757
lordcrc@384
  3758
    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"]
lordcrc@384
  3759
lordcrc@384
  3760
    if gui:
lordcrc@384
  3761
        if(overrideicon != ""):
lordcrc@384
  3762
            icon = overrideicon
lordcrc@384
  3763
        else:
lordcrc@384
  3764
            icon = icon_tex
lordcrc@384
  3765
            if texture.get() in ["mix", "scale", "checkerboard", "dots"]:
lordcrc@384
  3766
                if type=="color": icon = icon_texmixcol
lordcrc@384
  3767
                else: icon = icon_texmix
lordcrc@384
  3768
            elif texture.get() in ["constant", "blackbody", "equalenergy", "frequency", "gaussian", "regulardata", "irregulardata"]:
lordcrc@384
  3769
                icon = icon_spectex
lordcrc@384
  3770
            else:
lordcrc@384
  3771
                if type=="color": icon = icon_texcol
lordcrc@384
  3772
                else: icon = icon_tex
lordcrc@384
  3773
        if (texlevel > 0): gui.newline(caption+":", -2, level, icon, scalelist([0.5,0.5,0.5],2.0/(level+2)))
lordcrc@384
  3774
        else: gui.newline("texture:", -2, level, icon, scalelist([0.5,0.5,0.5],2.0/(level+2)))
lordcrc@384
  3775
    luxOption("texture", texture, textures, "texture", "", gui, 2)
lordcrc@384
  3776
    str = "Texture \"%s\" \"%s\" \"%s\""%(texname, type, texture.get())
lordcrc@384
  3777
lordcrc@384
  3778
    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))
lordcrc@384
  3779
    if gui: # Draw Texture level Material preview
lordcrc@384
  3780
        luxPreview(mat, parentkey, 1, False, False, name, gui, texlevel, [0.5, 0.5, 0.5])
lordcrc@384
  3781
        # Add an offset for next controls
lordcrc@384
  3782
        #r = gui.getRect(1.0, 1)
lordcrc@384
  3783
        #gui.x += 140
lordcrc@384
  3784
lordcrc@384
  3785
    if texture.get() == "constant":
lordcrc@384
  3786
        value = luxProp(mat, keyname+".value", default)
lordcrc@384
  3787
        if type == "float": luxFloat("value", value, min, max, "", "", gui, 1.1)
lordcrc@384
  3788
        elif type == "color": luxRGB("value", value, max, "", "", gui, 2)
lordcrc@384
  3789
# direct version
lordcrc@384
  3790
        if type == "color": return ("", " \"%s %s\" [%s]"%(type, name, value.getRGC()))
lordcrc@384
  3791
        return ("", " \"%s %s\" [%s]"%(type, name, value.get()))
lordcrc@384
  3792
# indirect version
lordcrc@384
  3793
#        if type == "color": str += " \"%s value\" [%s]"%(type, value.getRGC())
lordcrc@384
  3794
#        else: str += " \"%s value\" [%s]"%(type, value.get())
lordcrc@384
  3795
lordcrc@384
  3796
    if texture.get() == "blackbody":
lordcrc@384
  3797
        if gui:
lordcrc@384
  3798
            if gui.xmax-gui.x < gui.w: gui.newline()
lordcrc@384
  3799
            r = gui.getRect(1.0, 1)
lordcrc@384
  3800
            gui.newline()
lordcrc@384
  3801
            drawBar(bar_blackbody, gui.xmax-gui.w-7, r[1])
lordcrc@384
  3802
        str += luxFloat("temperature", luxProp(mat, keyname+".bbtemp", 6500.0), 1000.0, 10000.0, "temperature", "Black Body temperature in degrees Kelvin", gui, 2.0, 1)
lordcrc@384
  3803
lordcrc@384
  3804
    if texture.get() == "lampspectrum":
lordcrc@384
  3805
        lampstring = luxProp(mat, keyname+".lampstring", "Incandescent2")
lordcrc@384
  3806
        lamppreset = luxProp(mat, keyname+".lampspectrum", "PHILIPS [Argenta] 200W Incandescent Lamp")
lordcrc@384
  3807
        if gui:
lordcrc@384
  3808
            def setLamp(i, value, preset, tree, dict): # callback function to set ior value after selection
lordcrc@384
  3809
                if i >= 0:
lordcrc@384
  3810
                    value.set(dict[i])
lordcrc@384
  3811
                    preset.set(getTreeNameById(tree, i))
lordcrc@384
  3812
lordcrc@384
  3813
            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) ] ) ] 
lordcrc@384
  3814
lordcrc@384
  3815
            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" }
lordcrc@384
  3816
lordcrc@384
  3817
            r = gui.getRect(2.0, 1)
lordcrc@384
  3818
            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))
lordcrc@384
  3819
        str += luxString("name", lampstring, "Lamp", "Choose measured Lamp Spectrum", None, 2.0)
lordcrc@384
  3820
lordcrc@384
  3821
    if texture.get() == "equalenergy":
lordcrc@384
  3822
        if gui:
lordcrc@384
  3823
            if gui.xmax-gui.x < gui.w: gui.newline()
lordcrc@384
  3824
            r = gui.getRect(1.0, 1)
lordcrc@384
  3825
            gui.newline()
lordcrc@384
  3826
            drawBar(bar_equalenergy, gui.xmax-gui.w-7, r[1])
lordcrc@384
  3827
        str += luxFloat("energy", luxProp(mat, keyname+".energy", 1.0), 0.0, 1.0, "energy", "Energy of each spectral band", gui, 2.0, 1)
lordcrc@384
  3828
lordcrc@384
  3829
    if texture.get() == "frequency":
lordcrc@384
  3830
        str += luxFloat("freq", luxProp(mat, keyname+".freq", 0.01), 0.01, 100.0, "frequency", "Frequency in nm", gui, 2.0, 1)
lordcrc@384
  3831
        str += luxFloat("phase", luxProp(mat, keyname+".phase", 0.5), 0.0, 1.0, "phase", "Phase", gui, 1.1, 1)
lordcrc@384
  3832
        str += luxFloat("energy", luxProp(mat, keyname+".energy", 1.0), 0.0, 1.0, "energy", "Amount of mean energy", gui, 0.9, 1)
lordcrc@384
  3833
lordcrc@384
  3834
    if texture.get() == "gaussian":
lordcrc@384
  3835
        if gui:
lordcrc@384
  3836
            if gui.xmax-gui.x < gui.w: gui.newline()
lordcrc@384
  3837
            r = gui.getRect(1.0, 1)
lordcrc@384
  3838
            gui.newline()
lordcrc@384
  3839
            drawBar(bar_spectrum, gui.xmax-gui.w-7, r[1])
lordcrc@384
  3840
        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)
lordcrc@384
  3841
        str += luxFloat("width", luxProp(mat, keyname+".width", 50.0), 20.0, 300.0, "width", "Width of gaussian distribution in nm", gui, 1.1, 1)
lordcrc@384
  3842
        str += luxFloat("energy", luxProp(mat, keyname+".energy", 1.0), 0.0, 1.0, "energy", "Amount of mean energy", gui, 0.9, 1)
lordcrc@384
  3843
lordcrc@384
  3844
    if texture.get() == "imagemap":
jensverwiebe@389
  3845
        if gui: gui.newline("IM-clip:", -2, level)
doug@387
  3846
        str += luxOption("wrap", luxProp(mat, keyname+".wrap", "repeat"), ["repeat","black","clamp"], "repeat", "", gui, 1.0)
lordcrc@384
  3847
jensverwiebe@389
  3848
        if gui: gui.newline("IM-source:", -2, level)
jensverwiebe@389
  3849
lordcrc@384
  3850
        # ZANQDO
lordcrc@384
  3851
        texturefilename = luxProp(mat, keyname+".filename", "")
doug@387
  3852
        extimage = luxProp(mat, keyname+'.externalimage', "true")
doug@387
  3853
        luxBool("External Image", extimage, "External Image", "External Image", gui, 1.0)
jensverwiebe@388
  3854
        if gui: gui.newline("IM-path:", -2, level)
doug@387
  3855
        if extimage.get() == "true":
doug@387
  3856
            luxFile("filename", texturefilename, "file", "texture file path", gui, 2.0)
doug@387
  3857
        else:
jensverwiebe@388
  3858
            bil = [i.filename for i in Image.Get() if '.' in i.filename]
jensverwiebe@388
  3859
            try:
jensverwiebe@388
  3860
                uti = [i.filename for i in Image.Get() if '.' not in i.filename]
jensverwiebe@388
  3861
                if len(uti) > 0:
jensverwiebe@388
  3862
                    luxLabel("INFO: Images not listed here must be saved first", gui)
jensverwiebe@388
  3863
            except: pass    
doug@387
  3864
            if len(bil) > 0:
doug@387
  3865
                luxOption("Image", texturefilename, bil, "Blender Images", "Blender Image", gui, 2.0)
doug@387
  3866
            else:
doug@387
  3867
                luxLabel("No Blender Images - Load Image in the Image Editor", gui)
lordcrc@384
  3868
        # dougal2 image file packing
lordcrc@384
  3869
        impack = luxProp(Scene.GetCurrent(), 'packtextures', 'false')
lordcrc@384
  3870
        
lordcrc@384
  3871
        if impack.get() == 'false':
lordcrc@384
  3872
            str += luxFile("filename", texturefilename, "file", "texture file path", None, 2.0)
lordcrc@384
  3873
        else:
lordcrc@384
  3874
            import zlib, base64
lordcrc@384
  3875
            def get_image_data(filename):
lordcrc@384
  3876
                try:
lordcrc@384
  3877
                    f=open(filename,'rb')
lordcrc@384
  3878
                    d=f.read()
lordcrc@384
  3879
                    f.close()
lordcrc@384
  3880
                except:
lordcrc@384
  3881
                    print('Error reading image data from %s' % filename)
lordcrc@384
  3882
                    d = ''
lordcrc@384
  3883
                return base64.b64encode(zlib.compress(d))
lordcrc@384
  3884
            imdata = get_image_data(texturefilename.get())
lordcrc@384
  3885
            str += '\r\n   "string imagedata" ["%s"]' % imdata
lordcrc@384
  3886
        
lordcrc@384
  3887
        useseq = luxProp(mat, keyname+".useseq", "false")
lordcrc@384
  3888
        luxCollapse("usesew", useseq, "Sequence", "", gui, 2.0)
lordcrc@384
  3889
    
lordcrc@384
  3890
        if useseq.get() == "true":
lordcrc@384
  3891
            seqframes = luxProp(mat, keyname+".seqframes", 100)
lordcrc@384
  3892
            luxInt("frames", seqframes, 1, 100000, "Frames", "", gui, 0.5)
lordcrc@384
  3893
            seqoffset = luxProp(mat, keyname+".seqoffset", 0)
lordcrc@384
  3894
            luxInt("offset", seqoffset, 0, 100000, "Offset", "", gui, 0.5)
lordcrc@384
  3895
            seqstartframe = luxProp(mat, keyname+".seqsframe", 1)
lordcrc@384
  3896
            luxInt("startframe", seqstartframe, 1, 100000, "StartFr", "", gui, 0.5)
lordcrc@384
  3897
            seqcyclic = luxProp(mat, keyname+".seqcycl", "false")
lordcrc@384
  3898
            luxBool("cyclic", seqcyclic, "Cyclic", "", gui, 0.5)
lordcrc@384
  3899
    
lordcrc@384
  3900
            
lordcrc@384
  3901
            totalframes = seqframes.get()
lordcrc@384
  3902
            currentframe = Blender.Get('curframe')
lordcrc@384
  3903
    
lordcrc@384
  3904
            if(currentframe < seqstartframe.get()):
lordcrc@384
  3905
                fnumber = 1 + seqoffset.get()
lordcrc@384
  3906
            else:
lordcrc@384
  3907
                fnumber = (currentframe - (seqstartframe.get()-1)) + seqoffset.get()
lordcrc@384
  3908
    
lordcrc@384
  3909
            if(fnumber > seqframes.get()):
lordcrc@384
  3910
                if(seqcyclic.get() == "false"):
lordcrc@384
  3911
                    fnumber = seqframes.get()
lordcrc@384
  3912
                else:
lordcrc@384
  3913
                    fnumber = currentframe % seqframes.get()
lordcrc@384
  3914
    
lordcrc@384
  3915
            import re
lordcrc@384
  3916
            def get_seq_filename(number, filename):
lordcrc@384
  3917
                m = re.findall(r'(\d+)', filename)
lordcrc@384
  3918
                if len(m) == 0:
lordcrc@384
  3919
                    return "ERR: Can't find pattern"
lordcrc@384
  3920
    
lordcrc@384
  3921
                rightmost_number = m[len(m)-1]
lordcrc@384
  3922
                seq_length = len(rightmost_number)
lordcrc@384
  3923
    
lordcrc@384
  3924
                nstr = "%i" %number
lordcrc@384
  3925
                new_seq_number = nstr.zfill(seq_length)
lordcrc@384
  3926
     
lordcrc@384
  3927
                return filename.replace(rightmost_number, new_seq_number)
lordcrc@384
  3928
     
lordcrc@384
  3929
            texturefilename.set(get_seq_filename(fnumber, texturefilename.get()))
lordcrc@384
  3930
            if gui: gui.newline()
lordcrc@384
  3931
    
lordcrc@384
  3932
        str += luxFloat("gamma", luxProp(mat, keyname+".gamma", texturegamma()), 0.0, 6.0, "gamma", "", gui, 0.75)
lordcrc@384
  3933
        str += luxFloat("gain", luxProp(mat, keyname+".gain", 1.0), 0.0, 10.0, "gain", "", gui, 0.5)
lordcrc@384
  3934
        filttype = luxProp(mat, keyname+".filtertype", "bilinear")
lordcrc@384
  3935
        filttypes = ["mipmap_ewa","mipmap_trilinear","bilinear","nearest"]
lordcrc@384
  3936
        str += luxOption("filtertype", filttype, filttypes, "filtertype", "Choose the filtering method to use for the image texture", gui, 0.75)
lordcrc@384
  3937
        
lordcrc@384
  3938
        if filttype.get() == "mipmap_ewa" or filttype.get() == "mipmap_trilinear":    
lordcrc@384
  3939
            str += luxFloat("maxanisotropy", luxProp(mat, keyname+".maxanisotropy", 8.0), 1.0, 512.0, "maxaniso", "", gui, 1.0)
lordcrc@384
  3940
            str += luxInt("discardmipmaps", luxProp(mat, keyname+".discardmipmaps", 0), 0, 1, "discardmips", "", gui, 1.0)
lordcrc@384
  3941
    
lordcrc@384
  3942
        str += luxMapping(keyname, mat, gui, level+1)
lordcrc@384
  3943
lordcrc@384
  3944
    if texture.get() == "mix":
lordcrc@384
  3945
        (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))
lordcrc@384
  3946
        (s, l) = c((s, l), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  3947
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  3948
        str = s + str + l
lordcrc@384
  3949
lordcrc@384
  3950
    if texture.get() == "scale":
lordcrc@384
  3951
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  3952
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  3953
        str = s + str + l
lordcrc@384
  3954
lordcrc@384
  3955
    if texture.get() == "bilerp":
lordcrc@384
  3956
        if type == "float":
lordcrc@384
  3957
            str += luxFloat("v00", luxProp(mat, keyname+".v00", 0.0), min, max, "v00", "", gui, 1.0)
lordcrc@384
  3958
            str += luxFloat("v01", luxProp(mat, keyname+".v01", 1.0), min, max, "v01", "", gui, 1.0)
lordcrc@384
  3959
            if gui: gui.newline("", -2)
lordcrc@384
  3960
            str += luxFloat("v10", luxProp(mat, keyname+".v10", 0.0), min, max, "v10", "", gui, 1.0)
lordcrc@384
  3961
            str += luxFloat("v11", luxProp(mat, keyname+".v11", 1.0), min, max, "v11", "", gui, 1.0)
lordcrc@384
  3962
        elif type == "color":
lordcrc@384
  3963
            if gui: gui.newline("          v00:", -2)
lordcrc@384
  3964
            str += luxRGB("v00", luxProp(mat, keyname+".v00", "0.0 0.0 0.0"), max, "v00", "", gui, 2.0)
lordcrc@384
  3965
            if gui: gui.newline("          v01:", -2)
lordcrc@384
  3966
            str += luxRGB("v01", luxProp(mat, keyname+".v01", "1.0 1.0 1.0"), max, "v01", "", gui, 2.0)
lordcrc@384
  3967
            if gui: gui.newline("          v10:", -2)
lordcrc@384
  3968
            str += luxRGB("v10", luxProp(mat, keyname+".v10", "0.0 0.0 0.0"), max, "v10", "", gui, 2.0)
lordcrc@384
  3969
            if gui: gui.newline("          v11:", -2)
lordcrc@384
  3970
            str += luxRGB("v11", luxProp(mat, keyname+".v11", "1.0 1.0 1.0"), max, "v11", "", gui, 2.0)
lordcrc@384
  3971
        str += luxMapping(keyname, mat, gui, level+1)
lordcrc@384
  3972
lordcrc@384
  3973
    if texture.get() == "windy":
lordcrc@384
  3974
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  3975
        # this texture has no options 
lordcrc@384
  3976
lordcrc@384
  3977
    if texture.get() == "checkerboard":
lordcrc@384
  3978
        dim = luxProp(mat, keyname+".dim", 2)
lordcrc@384
  3979
        str += luxInt("dimension", dim, 2, 3, "dim", "", gui, 1)
lordcrc@384
  3980
        if dim.get() == 2: str += luxOption("aamode", luxProp(mat, keyname+".aamode", "closedform"), ["closedform","supersample","none"], "aamode", "antialiasing mode", gui, 0.6)
lordcrc@384
  3981
        if gui: gui.newline("", -2)
lordcrc@384
  3982
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  3983
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  3984
        str = s + str + l
lordcrc@384
  3985
        if dim.get() == 2: str += luxMapping(keyname, mat, gui, level+1) 
lordcrc@384
  3986
        if dim.get() == 3: str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  3987
lordcrc@384
  3988
    if texture.get() == "dots":
lordcrc@384
  3989
        (s, l) = c(("", ""), luxTexture("inside", keyname, type, default, min, max, "inside", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  3990
        (s, l) = c((s, l), luxTexture("outside", keyname, type, alternativedefault(type, default), min, max, "outside", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  3991
        str = s + str + l
lordcrc@384
  3992
        str += luxMapping(keyname, mat, gui, level+1)
lordcrc@384
  3993
lordcrc@384
  3994
    if texture.get() == "fbm":
lordcrc@384
  3995
        str += luxInt("octaves", luxProp(mat, keyname+".octaves", 8), 1, 100, "octaves", "", gui, 1)
lordcrc@384
  3996
        # if gui: gui.newline("", -2)
lordcrc@384
  3997
        str += luxFloat("roughness", luxProp(mat, keyname+".roughness", 0.5), 0.0, 1.0, "roughness", "", gui, 1, 1)
lordcrc@384
  3998
        if gui: gui.newline("", -2)
lordcrc@384
  3999
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4000
lordcrc@384
  4001
    if texture.get() == "marble":
lordcrc@384
  4002
        str += luxInt("octaves", luxProp(mat, keyname+".octaves", 8), 1, 100, "octaves", "", gui, 1)
lordcrc@384
  4003
        # if gui: gui.newline("", -2)
lordcrc@384
  4004
        str += luxFloat("roughness", luxProp(mat, keyname+".roughness", 0.5), 0.0, 1.0, "roughness", "", gui, 1, 1)
lordcrc@384
  4005
        if gui: gui.newline("", -2)
lordcrc@384
  4006
        str += luxFloat("nscale", luxProp(mat, keyname+".nscale", 1.0), 0.0, 100.0, "nscale", "Scaling factor for the noise input", gui, 1.0)
lordcrc@384
  4007
        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)
lordcrc@384
  4008
        if gui: gui.newline("", -2)
lordcrc@384
  4009
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4010
lordcrc@384
  4011
    if texture.get() == "wrinkled":
lordcrc@384
  4012
        str += luxInt("octaves", luxProp(mat, keyname+".octaves", 8), 1, 100, "octaves", "", gui, 1)
lordcrc@384
  4013
        # if gui: gui.newline("", -2)
lordcrc@384
  4014
        str += luxFloat("roughness", luxProp(mat, keyname+".roughness", 0.5), 0.0, 1.0, "roughness", "", gui, 1, 1)
lordcrc@384
  4015
        if gui: gui.newline("", -2)
lordcrc@384
  4016
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4017
lordcrc@384
  4018
    if texture.get() == "brick":
lordcrc@384
  4019
        if gui: gui.newline("brick:", -2, level+1, icon_texparam)
lordcrc@384
  4020
lordcrc@384
  4021
        str += luxFloat("brickwidth", luxProp(mat, keyname+".brickwidth", 0.3), 0.0, 10.0, "brickwidth (X)", "", gui, 1.0)
lordcrc@384
  4022
        str += luxFloat("brickheight", luxProp(mat, keyname+".brickheight", 0.1), 0.0, 10.0, "brickheight (Z)", "", gui, 1.0)
lordcrc@384
  4023
        str += luxFloat("brickdepth", luxProp(mat, keyname+".brickdepth", 0.15), 0.0, 10.0, "brickdepth (Y)", "", gui, 1.0)
lordcrc@384
  4024
lordcrc@384
  4025
        if gui: gui.newline("mortar:", -2, level+1, icon_texparam)
lordcrc@384
  4026
lordcrc@384
  4027
        str += luxFloat("mortarsize", luxProp(mat, keyname+".mortarsize", 0.01), 0.0, 1.0, "mortarsize", "", gui, 1.0)
lordcrc@384
  4028
lordcrc@384
  4029
        (s, l) = c(("", ""), luxTexture("bricktex", keyname, type, default, min, max, "bricktex", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4030
        (s, l) = c((s, l), luxTexture("mortartex", keyname, type, alternativedefault(type, default), min, max, "mortartex", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4031
        str = s + str + l
lordcrc@384
  4032
lordcrc@384
  4033
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4034
lordcrc@384
  4035
    if texture.get() == "blender_marble":
lordcrc@384
  4036
        if gui: gui.newline("noise:", -2, level+1, icon_texparam)
lordcrc@384
  4037
lordcrc@384
  4038
        mtype = luxProp(mat, keyname+".mtype", "soft")
lordcrc@384
  4039
        mtypes = ["soft","sharp","sharper"]
lordcrc@384
  4040
        str += luxOption("type", mtype, mtypes, "type", "", gui, 0.5)
lordcrc@384
  4041
lordcrc@384
  4042
        noisetype = luxProp(mat, keyname+".noisetype", "hard_noise")
lordcrc@384
  4043
        noisetypes = ["soft_noise","hard_noise"]
lordcrc@384
  4044
        str += luxOption("noisetype", noisetype, noisetypes, "noisetypes", "", gui, 0.75)
lordcrc@384
  4045
lordcrc@384
  4046
        str += luxInt("noisedepth", luxProp(mat, keyname+".noisedepth", 2), 0, 6, "noisedepth", "", gui, 0.75)
lordcrc@384
  4047
lordcrc@384
  4048
        str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 2.0, "noisesize", "", gui, 1.0)
lordcrc@384
  4049
        str += luxFloat("turbulance", luxProp(mat, keyname+".turbulance", 5.0), 0.0, 200.0, "turbulance", "", gui, 1.0)
lordcrc@384
  4050
lordcrc@384
  4051
        if gui: gui.newline("basis:", -2, level+1, icon_texparam)
lordcrc@384
  4052
        noisebasis2 = luxProp(mat, keyname+".noisebasis2", "sin")
lordcrc@384
  4053
        noisebasises2 = ["sin","saw","tri"]
lordcrc@384
  4054
        str += luxOption("noisebasis2", noisebasis2, noisebasises2, "noisebasis2", "", gui, 0.7)
lordcrc@384
  4055
lordcrc@384
  4056
        noisebasis = luxProp(mat, keyname+".noisebasis", "blender_original")
lordcrc@384
  4057
        noisebasises = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
lordcrc@384
  4058
        str += luxOption("noisebasis", noisebasis, noisebasises, "noisebasis", "", gui, 1.3)
lordcrc@384
  4059
lordcrc@384
  4060
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
lordcrc@384
  4061
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
lordcrc@384
  4062
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
lordcrc@384
  4063
lordcrc@384
  4064
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4065
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4066
        str = s + str + l
lordcrc@384
  4067
lordcrc@384
  4068
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4069
lordcrc@384
  4070
    if texture.get() == "blender_musgrave":
lordcrc@384
  4071
        if gui: gui.newline("type:", -2, level+1, icon_texparam)
lordcrc@384
  4072
        mtype = luxProp(mat, keyname+".mtype", "multifractal")
lordcrc@384
  4073
        mtypes = ["multifractal","ridged_multifractal", "hybrid_multifractal", "hetero_terrain", "fbm"]
lordcrc@384
  4074
        str += luxOption("type", mtype, mtypes, "type", "", gui, 2.0)
lordcrc@384
  4075
lordcrc@384
  4076
        str += luxFloat("h", luxProp(mat, keyname+".h", 1.0), 0.0, 2.0, "h", "", gui, 0.5)
lordcrc@384
  4077
        str += luxFloat("lacu", luxProp(mat, keyname+".lacu", 2.0), 0.0, 6.0, "lacu", "", gui, 0.75)
lordcrc@384
  4078
        str += luxFloat("octs", luxProp(mat, keyname+".octs", 2.0), 0.0, 8.0, "octs", "", gui, 0.75)
lordcrc@384
  4079
lordcrc@384
  4080
        if mtype.get() == "hetero_terrain":
lordcrc@384
  4081
            str += luxFloat("offset", luxProp(mat, keyname+".offset", 2.0), 0.0, 6.0, "offset", "", gui, 2.0)
lordcrc@384
  4082
        if mtype.get() == "ridged_multifractal":
lordcrc@384
  4083
            str += luxFloat("offset", luxProp(mat, keyname+".offset", 2.0), 0.0, 6.0, "offset", "", gui, 1.25)
lordcrc@384
  4084
            str += luxFloat("gain", luxProp(mat, keyname+".gain", 2.0), 0.0, 6.0, "gain", "", gui, 0.75)
lordcrc@384
  4085
        if mtype.get() == "hybrid_multifractal":
lordcrc@384
  4086
            str += luxFloat("offset", luxProp(mat, keyname+".offset", 2.0), 0.0, 6.0, "offset", "", gui, 1.25)
lordcrc@384
  4087
            str += luxFloat("gain", luxProp(mat, keyname+".gain", 2.0), 0.0, 6.0, "gain", "", gui, 0.75)
lordcrc@384
  4088
lordcrc@384
  4089
        str += luxFloat("outscale", luxProp(mat, keyname+".outscale", 1.0), 0.0, 10.0, "iscale", "", gui, 1.0)
lordcrc@384
  4090
        str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 2.0, "noisesize", "", gui, 1.0)
lordcrc@384
  4091
lordcrc@384
  4092
        if gui: gui.newline("basis:", -2, level+1, icon_texparam)
lordcrc@384
  4093
        noisebasis = luxProp(mat, keyname+".noisebasis", "blender_original")
lordcrc@384
  4094
        noisebasises = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
lordcrc@384
  4095
        str += luxOption("noisebasis", noisebasis, noisebasises, "noisebasis", "", gui, 2.0)
lordcrc@384
  4096
lordcrc@384
  4097
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
lordcrc@384
  4098
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
lordcrc@384
  4099
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
lordcrc@384
  4100
lordcrc@384
  4101
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4102
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4103
        str = s + str + l
lordcrc@384
  4104
lordcrc@384
  4105
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4106
lordcrc@384
  4107
    if texture.get() == "blender_wood":
lordcrc@384
  4108
        if gui: gui.newline("noise:", -2, level+1, icon_texparam)
lordcrc@384
  4109
lordcrc@384
  4110
        mtype = luxProp(mat, keyname+".mtype", "bands")
lordcrc@384
  4111
        mtypes = ["bands","rings","bandnoise", "ringnoise"]
lordcrc@384
  4112
        str += luxOption("type", mtype, mtypes, "type", "", gui, 0.5)
lordcrc@384
  4113
lordcrc@384
  4114
        noisetype = luxProp(mat, keyname+".noisetype", "hard_noise")
lordcrc@384
  4115
        noisetypes = ["soft_noise","hard_noise"]
lordcrc@384
  4116
        str += luxOption("noisetype", noisetype, noisetypes, "noisetypes", "", gui, 0.75)
lordcrc@384
  4117
lordcrc@384
  4118
        str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 2.0, "noisesize", "", gui, 1.0)
lordcrc@384
  4119
        str += luxFloat("turbulance", luxProp(mat, keyname+".turbulance", 5.0), 0.0, 200.0, "turbulance", "", gui, 1.0)
lordcrc@384
  4120
lordcrc@384
  4121
        if gui: gui.newline("basis:", -2, level+1, icon_texparam)
lordcrc@384
  4122
        noisebasis2 = luxProp(mat, keyname+".noisebasis2", "sin")
lordcrc@384
  4123
        noisebasises2 = ["sin","saw","tri"]
lordcrc@384
  4124
        str += luxOption("noisebasis2", noisebasis2, noisebasises2, "noisebasis2", "", gui, 0.7)
lordcrc@384
  4125
lordcrc@384
  4126
        noisebasis = luxProp(mat, keyname+".noisebasis", "blender_original")
lordcrc@384
  4127
        noisebasises = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
lordcrc@384
  4128
        str += luxOption("noisebasis", noisebasis, noisebasises, "noisebasis", "", gui, 1.3)
lordcrc@384
  4129
lordcrc@384
  4130
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
lordcrc@384
  4131
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
lordcrc@384
  4132
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
lordcrc@384
  4133
lordcrc@384
  4134
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4135
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4136
        str = s + str + l
lordcrc@384
  4137
    
lordcrc@384
  4138
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4139
lordcrc@384
  4140
    if texture.get() == "blender_clouds":
lordcrc@384
  4141
        if gui: gui.newline("noise:", -2, level+1, icon_texparam)
lordcrc@384
  4142
lordcrc@384
  4143
        mtype = luxProp(mat, keyname+".mtype", "default")
lordcrc@384
  4144
        mtypes = ["default","color"]
lordcrc@384
  4145
        str += luxOption("type", mtype, mtypes, "type", "", gui, 0.5)
lordcrc@384
  4146
lordcrc@384
  4147
        noisetype = luxProp(mat, keyname+".noisetype", "hard_noise")
lordcrc@384
  4148
        noisetypes = ["soft_noise","hard_noise"]
lordcrc@384
  4149
        str += luxOption("noisetype", noisetype, noisetypes, "noisetypes", "", gui, 0.75)
lordcrc@384
  4150
lordcrc@384
  4151
        str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 2.0, "noisesize", "", gui, 1.0)
lordcrc@384
  4152
        str += luxInt("noisedepth", luxProp(mat, keyname+".noisedepth", 2), 0, 6, "noisedepth", "", gui, 1.0)
lordcrc@384
  4153
lordcrc@384
  4154
        if gui: gui.newline("basis:", -2, level+1, icon_texparam)
lordcrc@384
  4155
        noisebasis = luxProp(mat, keyname+".noisebasis", "blender_original")
lordcrc@384
  4156
        noisebasises = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
lordcrc@384
  4157
        str += luxOption("noisebasis", noisebasis, noisebasises, "noisebasis", "", gui, 1.3)
lordcrc@384
  4158
lordcrc@384
  4159
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
lordcrc@384
  4160
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
lordcrc@384
  4161
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
lordcrc@384
  4162
lordcrc@384
  4163
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4164
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4165
        str = s + str + l
lordcrc@384
  4166
    
lordcrc@384
  4167
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4168
lordcrc@384
  4169
    if texture.get() == "blender_blend":
lordcrc@384
  4170
        if gui: gui.newline("type:", -2, level+1, icon_texparam)
lordcrc@384
  4171
lordcrc@384
  4172
        mtype = luxProp(mat, keyname+".mtype", "lin")
lordcrc@384
  4173
        mtypes = ["lin","quad","ease","diag","sphere","halo","radial"]
lordcrc@384
  4174
        str += luxOption("type", mtype, mtypes, "type", "", gui, 0.5)
lordcrc@384
  4175
        
lordcrc@384
  4176
        mflag = luxProp(mat, keyname+".flag", "false")
lordcrc@384
  4177
        str += luxBool("flipxy", mflag, "flipXY", "", gui, 0.5)
lordcrc@384
  4178
lordcrc@384
  4179
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
lordcrc@384
  4180
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
lordcrc@384
  4181
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
lordcrc@384
  4182
lordcrc@384
  4183
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4184
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4185
        str = s + str + l
lordcrc@384
  4186
        
lordcrc@384
  4187
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4188
lordcrc@384
  4189
    if texture.get() == "blender_distortednoise":
lordcrc@384
  4190
        if gui: gui.newline("noise:", -2, level+1, icon_texparam)
lordcrc@384
  4191
        
lordcrc@384
  4192
        str += luxFloat("distamount", luxProp(mat, keyname+".distamount", 1.0), 0.0, 10.0, "distamount", "", gui, 1.0)
lordcrc@384
  4193
        str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 2.0, "noisesize", "", gui, 1.0)
lordcrc@384
  4194
        str += luxFloat("nabla", luxProp(mat, keyname+".nabla", 0.025), 0.000, 2.0, "nabla", "", gui, 1.0)
lordcrc@384
  4195
        
lordcrc@384
  4196
        if gui: gui.newline("distortion:", -2, level+1, icon_texparam)
lordcrc@384
  4197
        ntype = luxProp(mat, keyname+".type", "blender_original")
lordcrc@384
  4198
        ntypes = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
lordcrc@384
  4199
        str += luxOption("type", ntype, ntypes, "type", "", gui, 1.3)
lordcrc@384
  4200
        
lordcrc@384
  4201
        if gui: gui.newline("basis:", -2, level+1, icon_texparam)
lordcrc@384
  4202
        noisebasis = luxProp(mat, keyname+".noisebasis", "blender_original")
lordcrc@384
  4203
        noisebasises = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
lordcrc@384
  4204
        str += luxOption("noisebasis", noisebasis, noisebasises, "noisebasis", "", gui, 1.3)
lordcrc@384
  4205
lordcrc@384
  4206
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
lordcrc@384
  4207
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
lordcrc@384
  4208
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
lordcrc@384
  4209
lordcrc@384
  4210
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4211
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4212
        str = s + str + l
lordcrc@384
  4213
        
lordcrc@384
  4214
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4215
lordcrc@384
  4216
    if texture.get() == "blender_noise":        
lordcrc@384
  4217
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
lordcrc@384
  4218
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
lordcrc@384
  4219
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
lordcrc@384
  4220
lordcrc@384
  4221
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4222
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4223
        str = s + str + l
lordcrc@384
  4224
        
lordcrc@384
  4225
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4226
        
lordcrc@384
  4227
    if texture.get() == "blender_magic":
lordcrc@384
  4228
        if gui: gui.newline("noise:", -2, level+1, icon_texparam)
lordcrc@384
  4229
        
lordcrc@384
  4230
        str += luxInt("noisedepth", luxProp(mat, keyname+".noisedepth", 2), 0.0, 10.0, "noisedepth", "", gui, 1.0)
lordcrc@384
  4231
        str += luxFloat("turbulance", luxProp(mat, keyname+".turbulance", 5.0), 0.0, 2.0, "turbulance", "", gui, 1.0)
lordcrc@384
  4232
lordcrc@384
  4233
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
lordcrc@384
  4234
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
lordcrc@384
  4235
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
lordcrc@384
  4236
lordcrc@384
  4237
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4238
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4239
        str = s + str + l
lordcrc@384
  4240
        
lordcrc@384
  4241
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4242
        
lordcrc@384
  4243
    if texture.get() == "blender_stucci":
lordcrc@384
  4244
        if gui: gui.newline("noise:", -2, level+1, icon_texparam)
lordcrc@384
  4245
        mtype = luxProp(mat, keyname+".mtype", "Plastic")
lordcrc@384
  4246
        mtypes = ["Plastic","Wall In","Wall Out"]
lordcrc@384
  4247
        str += luxOption("type", mtype, mtypes, "type", "", gui, 0.5)
lordcrc@384
  4248
lordcrc@384
  4249
        noisetype = luxProp(mat, keyname+".noisetype", "soft_noise")
lordcrc@384
  4250
        noisetypes = ["soft_noise","hard_noise"]
lordcrc@384
  4251
        str += luxOption("noisetype", noisetype, noisetypes, "noisetypes", "", gui, 0.75)
lordcrc@384
  4252
        
lordcrc@384
  4253
        str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 10.0, "noisesize", "", gui, 1.0)
lordcrc@384
  4254
        str += luxFloat("turbulance", luxProp(mat, keyname+".turbulance", 5.0), 0.0, 200.0, "turbulance", "", gui, 1.0)
lordcrc@384
  4255
lordcrc@384
  4256
        noisebasis = luxProp(mat, keyname+".noisebasis", "blender_original")
lordcrc@384
  4257
        noisebasises = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
lordcrc@384
  4258
        str += luxOption("noisebasis", noisebasis, noisebasises, "noisebasis", "", gui, 1.3)
lordcrc@384
  4259
lordcrc@384
  4260
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
lordcrc@384
  4261
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
lordcrc@384
  4262
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
lordcrc@384
  4263
lordcrc@384
  4264
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4265
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4266
        str = s + str + l
lordcrc@384
  4267
lordcrc@384
  4268
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4269
lordcrc@384
  4270
    if texture.get() == "blender_voronoi":
lordcrc@384
  4271
        #if gui: gui.newline("distmetric:", -2, level+1, icon_texparam)
lordcrc@384
  4272
        mtype = luxProp(mat, keyname+".distmetric", "actual_distance")
lordcrc@384
  4273
        mtypes = ["actual_distance","distance_squared","manhattan", "chebychev", "minkovsky_half", "minkovsky_four", "minkovsky"]
lordcrc@384
  4274
        str += luxOption("distmetric", mtype, mtypes, "distmetric", "", gui, 1.1)
lordcrc@384
  4275
lordcrc@384
  4276
        if gui: gui.newline("param:", -2, level+1, icon_texparam)
lordcrc@384
  4277
        str += luxFloat("minkovsky_exp", luxProp(mat, keyname+".minkovsky_exp", 2.5), 0.001, 10.0, "minkovsky_exp", "", gui, 1.0)
lordcrc@384
  4278
        str += luxFloat("outscale", luxProp(mat, keyname+".outscale", 1.0), 0.01, 10.0, "outscale", "", gui, 1.0)
lordcrc@384
  4279
        str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 2.0, "noisesize", "", gui, 1.0)
lordcrc@384
  4280
        str += luxFloat("nabla", luxProp(mat, keyname+".nabla", 0.025), 0.001, 0.1, "nabla", "", gui, 1.0)
lordcrc@384
  4281
        if gui: gui.newline("wparam:", -2, level+1, icon_texparam)
lordcrc@384
  4282
        str += luxFloat("w1", luxProp(mat, keyname+".w1", 1.0), -2.0, 2.0, "w1", "", gui, 1.0)
lordcrc@384
  4283
        str += luxFloat("w2", luxProp(mat, keyname+".w2", 0.0), -2.0, 2.0, "w2", "", gui, 1.0)
lordcrc@384
  4284
        str += luxFloat("w3", luxProp(mat, keyname+".w3", 0.0), -2.0, 2.0, "w3", "", gui, 1.0)
lordcrc@384
  4285
        str += luxFloat("w4", luxProp(mat, keyname+".w4", 0.0), -2.0, 2.0, "w4", "", gui, 1.0)
lordcrc@384
  4286
lordcrc@384
  4287
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
lordcrc@384
  4288
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
lordcrc@384
  4289
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
lordcrc@384
  4290
lordcrc@384
  4291
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4292
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4293
        str = s + str + l
lordcrc@384
  4294
lordcrc@384
  4295
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4296
lordcrc@384
  4297
lordcrc@384
  4298
lordcrc@384
  4299
    return (str+"\n", " \"texture %s\" [\"%s\"]"%(name, texname))
lordcrc@384
  4300
lordcrc@384
  4301
lordcrc@384
  4302
def luxSpectrumTexture(name, key, default, max, caption, hint, mat, gui, level=0):
lordcrc@384
  4303
    global icon_col
lordcrc@384
  4304
    if gui: gui.newline(caption, 4, level, icon_col, scalelist([0.5,0.6,0.5],2.0/(level+2)))
lordcrc@384
  4305
    str = ""
lordcrc@384
  4306
    keyname = "%s:%s"%(key, name)
lordcrc@384
  4307
    texname = "%s:%s"%(mat.getName(), keyname)
lordcrc@384
  4308
    value = luxProp(mat, keyname, default)
lordcrc@384
  4309
    link = luxRGB(name, value, max, "", hint, gui, 2.0)
lordcrc@384
  4310
    tex = luxProp(mat, keyname+".textured", False)
lordcrc@384
  4311
    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)]))
lordcrc@384
  4312
    if tex.get()=="true":
lordcrc@384
  4313
        if gui: gui.newline("", -2)
lordcrc@384
  4314
        (str, link) = luxTexture(name, key, "color", default, 0, max, caption, hint, mat, gui, level+1)
lordcrc@384
  4315
        if value.getRGB() != (1.0, 1.0, 1.0):
lordcrc@384
  4316
            if str == "": # handle special case if texture is a just a constant
lordcrc@384
  4317
                str += "Texture \"%s\" \"color\" \"scale\" \"color tex1\" [%s] \"color tex2\" [%s]\n"%(texname+".scale", (link.rpartition("[")[2])[0:-1], value.get())
lordcrc@384
  4318
            else: str += "Texture \"%s\" \"color\" \"scale\" \"texture tex1\" [\"%s\"] \"color tex2\" [%s]\n"%(texname+".scale", texname, value.get())
lordcrc@384
  4319
            link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
lordcrc@384
  4320
    return (str, link)
lordcrc@384
  4321
lordcrc@384
  4322
def luxLightSpectrumTexture(name, key, default, max, caption, hint, mat, gui, level=0):
lordcrc@384
  4323
    #if gui: gui.newline(caption, 4, level, icon_emission, scalelist([0.6,0.5,0.5],2.0/(level+2)))
lordcrc@384
  4324
    str = ""
lordcrc@384
  4325
    keyname = "%s:%s"%(key, name)
lordcrc@384
  4326
    texname = "%s:%s"%(mat.getName(), keyname)
lordcrc@384
  4327
    (str, link) = luxTexture(name, key, "color", default, 0, max, caption, hint, mat, gui, level+1, 0, 1)
lordcrc@384
  4328
    return (str, link)
lordcrc@384
  4329
lordcrc@384
  4330
def luxFloatTexture(name, key, default, min, max, caption, hint, mat, gui, level=0):
lordcrc@384
  4331
    global icon_float
lordcrc@384
  4332
    if gui: gui.newline(caption, 4, level, icon_float, scalelist([0.5,0.5,0.6],2.0/(level+2)))
lordcrc@384
  4333
    str = ""
lordcrc@384
  4334
    keyname = "%s:%s"%(key, name)
lordcrc@384
  4335
    texname = "%s:%s"%(mat.getName(), keyname)
lordcrc@384
  4336
    value = luxProp(mat, keyname, default)
lordcrc@384
  4337
    link = luxFloat(name, value, min, max, "", hint, gui, 2.0)
lordcrc@384
  4338
    tex = luxProp(mat, keyname+".textured", False)
lordcrc@384
  4339
    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)]))
lordcrc@384
  4340
    if tex.get()=="true":
lordcrc@384
  4341
        if gui: gui.newline("", -2)
lordcrc@384
  4342
        (str, link) = luxTexture(name, key, "float", default, min, max, caption, hint, mat, gui, level+1)
lordcrc@384
  4343
        if value.get() != 1.0:
lordcrc@384
  4344
            if str == "": # handle special case if texture is a just a constant
lordcrc@384
  4345
                str += "Texture \"%s\" \"float\" \"scale\" \"float tex1\" [%s] \"float tex2\" [%s]\n"%(texname+".scale", (link.rpartition("[")[2])[0:-1], value.get())
lordcrc@384
  4346
            else: str += "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" [\"%s\"] \"float tex2\" [%s]\n"%(texname+".scale", texname, value.get())
lordcrc@384
  4347
            link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
lordcrc@384
  4348
    return (str, link)
lordcrc@384
  4349
lordcrc@384
  4350
def luxFloatSliderTexture(name, key, default, min, max, caption, hint, mat, gui, level=0):
lordcrc@384
  4351
        global icon_float
lordcrc@384
  4352
        if gui: gui.newline(caption, 4, level, icon_float, scalelist([0.5,0.5,0.6],2.0/(level+2)))
lordcrc@384
  4353
        str = ""
lordcrc@384
  4354
        keyname = "%s:%s"%(key, name)
lordcrc@384
  4355
        texname = "%s:%s"%(mat.getName(), keyname)
lordcrc@384
  4356
        value = luxProp(mat, keyname, default)
lordcrc@384
  4357
        link = luxFloat(name, value, min, max, caption, hint, gui, 2.0, 1)
lordcrc@384
  4358
        tex = luxProp(mat, keyname+".textured", False)
lordcrc@384
  4359
        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)]))
lordcrc@384
  4360
        if tex.get()=="true":
lordcrc@384
  4361
                if gui: gui.newline("", -2)
lordcrc@384
  4362
                (str, link) = luxTexture(name, key, "float", default, min, max, caption, hint, mat, gui, level+1)
lordcrc@384
  4363
                if value.get() != 1.0:
lordcrc@384
  4364
                        if str == "": # handle special case if texture is a just a constant
lordcrc@384
  4365
                                str += "Texture \"%s\" \"float\" \"scale\" \"float tex1\" [%s] \"float tex2\" [%s]\n"%(texname+".scale", (link.rpartition("[")[2])[0:-1], value.get())
lordcrc@384
  4366
                        else: str += "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" [\"%s\"] \"float tex2\" [%s]\n"%(texname+".scale", texname, value.get())
lordcrc@384
  4367
                        link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
lordcrc@384
  4368
        return (str, link)
lordcrc@384
  4369
lordcrc@384
  4370
lordcrc@384
  4371
def luxExponentTexture(name, key, default, min, max, caption, hint, mat, gui, level=0):
lordcrc@384
  4372
    global icon_float
lordcrc@384
  4373
    if gui: gui.newline(caption, 4, level, icon_float, scalelist([0.5,0.5,0.6],2.0/(level+2)))
lordcrc@384
  4374
    str = ""
lordcrc@384
  4375
    keyname = "%s:%s"%(key, name)
lordcrc@384
  4376
    texname = "%s:%s"%(mat.getName(), keyname)
lordcrc@384
  4377
    value = luxProp(mat, keyname, default)
lordcrc@384
  4378
lordcrc@384
  4379
    if(value.get() == None): value.set(0.002)
lordcrc@384
  4380
lordcrc@384
  4381
#    link = luxFloat(name, value, min, max, "", hint, gui, 2.0)
lordcrc@384
  4382
    if gui:
lordcrc@384
  4383
        r = gui.getRect(2.0, 1)
lordcrc@384
  4384
        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))
lordcrc@384
  4385
    link = " \"float %s\" [%f]"%(name, value.getFloat())
lordcrc@384
  4386
lordcrc@384
  4387
    tex = luxProp(mat, keyname+".textured", False)
lordcrc@384
  4388
    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)]))
lordcrc@384
  4389
    if tex.get()=="true":
lordcrc@384
  4390
        if gui: gui.newline("", -2)
lordcrc@384
  4391
        (str, link) = luxTexture(name, key, "float", default, min, max, caption, hint, mat, gui, level+1)
lordcrc@384
  4392
        if value.get() != 1.0:
lordcrc@384
  4393
            if str == "": # handle special case if texture is a just a constant
lordcrc@384
  4394
                str += "Texture \"%s\" \"float\" \"scale\" \"float tex1\" [%s] \"float tex2\" [%s]\n"%(texname+".scale", (link.rpartition("[")[2])[0:-1], value.get())
lordcrc@384
  4395
            else: str += "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" [\"%s\"] \"float tex2\" [%s]\n"%(texname+".scale", texname, value.get())
lordcrc@384
  4396
            link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
lordcrc@384
  4397
    return (str, link)
lordcrc@384
  4398
lordcrc@384
  4399
lordcrc@384
  4400
def luxDispFloatTexture(name, key, default, min, max, caption, hint, mat, gui, level=0):
lordcrc@384
  4401
    global icon_float
lordcrc@384
  4402
    if gui: gui.newline(caption, 4, level, icon_float, scalelist([0.5,0.5,0.6],2.0/(level+2)))
lordcrc@384
  4403
    str = ""
lordcrc@384
  4404
    keyname = "%s:%s"%(key, name)
lordcrc@384
  4405
    texname = "%s:%s"%(mat.getName(), keyname)
lordcrc@384
  4406
    value = luxProp(mat, keyname, default)
lordcrc@384
  4407
    link = luxFloat(name, value, min, max, "", hint, gui, 2.0)
lordcrc@384
  4408
    tex = luxProp(mat, keyname+".textured", False)
lordcrc@384
  4409
    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)]))
lordcrc@384
  4410
    if tex.get()=="true":
lordcrc@384
  4411
        if gui: gui.newline("", -2)
lordcrc@384
  4412
        (str, link) = luxTexture(name, key, "float", default, min, max, caption, hint, mat, gui, level+1)
lordcrc@384
  4413
        str += "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" [\"%s\"] \"float tex2\" [%s]\n"%(texname+".scale", texname, value.get())
lordcrc@384
  4414
        link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
lordcrc@384
  4415
    return (str, link)
lordcrc@384
  4416
lordcrc@384
  4417
def luxIORFloatTexture(name, key, default, min, max, caption, hint, mat, gui, level=0):
lordcrc@384
  4418
    # IOR preset data
lordcrc@384
  4419
    iornames = ["0Z *** Gases @ 0 C ***", "01 - Vacuum", "02 - Air @ STP", "03 - Air", "04 - Helium", "05 - Hydrogen", "06 - Carbon dioxide",
lordcrc@384
  4420
    "1Z *** LIQUIDS @ 20 C ***", "11 - Benzene", "12 - Water", "13 - Ethyl alcohol", "14 - Carbon tetrachloride", "15 - Carbon disulfide", 
lordcrc@384
  4421
    "2Z *** SOLIDS at room temperature ***", "21 - Diamond", "22 - Strontium titanate", "23 - Amber", "24 - Fused silica glass", "25 - sodium chloride", 
lordcrc@384
  4422
    "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"]
lordcrc@384
  4423
    iorvals = [1.0, 1.0, 1.0002926, 1.000293, 1.000036, 1.000132, 1.00045,
lordcrc@384
  4424
    1.501, 1.501, 1.333, 1.361, 1.461, 1.628,
lordcrc@384
  4425
    2.419, 2.419, 2.41, 1.55, 1.458, 1.50,
lordcrc@384
  4426
    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]
lordcrc@384
  4427
lordcrc@384
  4428
    global icon_float
lordcrc@384
  4429
    if gui: gui.newline(caption, 4, level, icon_float, scalelist([0.5,0.5,0.6],2.0/(level+2)))
lordcrc@384
  4430
    str = ""
lordcrc@384
  4431
    keyname = "%s:%s"%(key, name)
lordcrc@384
  4432
    texname = "%s:%s"%(mat.getName(), keyname)
lordcrc@384
  4433
    value = luxProp(mat, keyname, default)
lordcrc@384
  4434
lordcrc@384
  4435
    iorusepreset = luxProp(mat, keyname+".iorusepreset", "true")
lordcrc@384
  4436
    luxBool("iorusepreset", iorusepreset, "Preset", "Select from a list of predefined presets", gui, 0.4)
lordcrc@384
  4437
lordcrc@384
  4438
    if(iorusepreset.get() == "true"):
lordcrc@384
  4439
        iorpreset = luxProp(mat, keyname+".iorpreset", "24 - Fused silica glass")
lordcrc@384
  4440
        if gui:
lordcrc@384
  4441
            def setIor(i, value, preset, tree, dict): # callback function to set ior value after selection                
lordcrc@384
  4442
                if i >= 0:
lordcrc@384
  4443
                    value.set(dict[i])
lordcrc@384
  4444
                    preset.set(getTreeNameById(tree, i))
tom@398
  4445
            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", [("Vacuum", 101), ("Air @ STP", 102), ("Air", 103), ("Helium", 104), ("Hydrogen", 105), ("Carbon dioxide", 106) ]), ("Transparent\x20", [("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) ] ) ]
lordcrc@384
  4446
            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}
lordcrc@384
  4447
            r = gui.getRect(1.6, 1)
lordcrc@384
  4448
            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))
lordcrc@384
  4449
        link = luxFloat(name, value, min, max, "IOR", hint, None, 1.6)
lordcrc@384
  4450
    else:
lordcrc@384
  4451
        link = luxFloat(name, value, min, max, "IOR", hint, gui, 1.6, 1)
lordcrc@384
  4452
lordcrc@384
  4453
    tex = luxProp(mat, keyname+".textured", False)
lordcrc@384
  4454
    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)]))
lordcrc@384
  4455
    if tex.get()=="true":
lordcrc@384
  4456
        if gui: gui.newline("", -2)
lordcrc@384
  4457
        (str, link) = luxTexture(name, key, "float", default, min, max, caption, hint, mat, gui, level+1)
lordcrc@384
  4458
        if value.get() != 1.0:
lordcrc@384
  4459
            str += "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" [\"%s\"] \"float tex2\" [%s]\n"%(texname+".scale", texname, value.get())
lordcrc@384
  4460
            link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
lordcrc@384
  4461
    return (str, link)
lordcrc@384
  4462
lordcrc@384
  4463
def luxCauchyBFloatTexture(name, key, default, min, max, caption, hint, mat, gui, level=0):
lordcrc@384
  4464
    # IOR preset data
lordcrc@384
  4465
    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" ]
lordcrc@384
  4466
    cauchybvals = [ 0.00354, 0.00420, 0.00459, 0.00531, 0.00743, 0.01342 ]
lordcrc@384
  4467
lordcrc@384
  4468
    global icon_float
lordcrc@384
  4469
    if gui: gui.newline(caption, 4, level, icon_float, scalelist([0.5,0.5,0.6],2.0/(level+2)))
lordcrc@384
  4470
    str = ""
lordcrc@384
  4471
    keyname = "%s:%s"%(key, name)
lordcrc@384
  4472
    texname = "%s:%s"%(mat.getName(), keyname)
lordcrc@384
  4473
    value = luxProp(mat, keyname, default)
lordcrc@384
  4474
lordcrc@384
  4475
    cauchybusepreset = luxProp(mat, keyname+".cauchybusepreset", "true")
lordcrc@384
  4476
    luxBool("cauchybusepreset", cauchybusepreset, "Preset", "Select from a list of predefined presets", gui, 0.4)
lordcrc@384
  4477
lordcrc@384
  4478
    if(cauchybusepreset.get() == "true"):
lordcrc@384
  4479
        cauchybpreset = luxProp(mat, keyname+".cauchybpreset", "01 - Fused silica glass")
lordcrc@384
  4480
        luxOption("cauchybpreset", cauchybpreset, cauchybnames, "  PRESET", "select CauchyB preset", gui, 1.6)
lordcrc@384
  4481
        idx = cauchybnames.index(cauchybpreset.get())
lordcrc@384
  4482
        value.set(cauchybvals[idx])
lordcrc@384
  4483
        link = luxFloat(name, value, min, max, "cauchyb", hint, None, 1.6)
lordcrc@384
  4484
    else:
lordcrc@384
  4485
        link = luxFloat(name, value, min, max, "cauchyb", hint, gui, 1.6, 1)
lordcrc@384
  4486
lordcrc@384
  4487
    tex = luxProp(mat, keyname+".textured", False)
lordcrc@384
  4488
    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)]))
lordcrc@384
  4489
    if tex.get()=="true":
lordcrc@384
  4490
        if gui: gui.newline("", -2)
lordcrc@384
  4491
        (str, link) = luxTexture(name, key, "float", default, min, max, caption, hint, mat, gui, level+1)
lordcrc@384
  4492
        if value.get() != 1.0:
lordcrc@384
  4493
            str += "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" [\"%s\"] \"float tex2\" [%s]\n"%(texname+".scale", texname, value.get())
lordcrc@384
  4494
            link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
lordcrc@384
  4495
    return (str, link)
lordcrc@384
  4496
lordcrc@384
  4497
def luxLight(name, kn, mat, gui, level):
lordcrc@384
  4498
    if gui:
lordcrc@384
  4499
        if name != "": gui.newline(name+":", 10, level)
lordcrc@384
  4500
        else: gui.newline("color:", 0, level+1)
lordcrc@384
  4501
    (str,link) = luxLightSpectrumTexture("L", kn+"light", "1.0 1.0 1.0", 1.0, "Spectrum", "", mat, gui, level+1)
lordcrc@384
  4502
    if gui: gui.newline("")
lordcrc@384
  4503
    link += luxFloat("power", luxProp(mat, kn+"light.power", 100.0), 0.0, 10000.0, "Power(W)", "AreaLight Power in Watts", gui)
lordcrc@384
  4504
    link += luxFloat("efficacy", luxProp(mat, kn+"light.efficacy", 17.0), 0.0, 100.0, "Efficacy(lm/W)", "Efficacy Luminous flux/watt", gui)
lordcrc@384
  4505
    if gui: gui.newline("")
lordcrc@384
  4506
    link += luxFloat("gain", luxProp(mat, kn+"light.gain", 1.0), 0.0, 100.0, "gain", "Gain/scale multiplier", gui)
lordcrc@384
  4507
    lightgroup = luxProp(mat, kn+"light.lightgroup", "default")
lordcrc@384
  4508
    luxString("lightgroup", lightgroup, "group", "assign light to a named light-group", gui, 1.0)
lordcrc@384
  4509
lordcrc@384
  4510
    if gui: gui.newline("Photometric")
lordcrc@384
  4511
    pm = luxProp(mat, kn+"light.usepm", "false")
lordcrc@384
  4512
    luxCollapse("photometric", pm, "Photometric Diagram", "Enable Photometric Diagram options", gui, 2.0)
lordcrc@384
  4513
lordcrc@384
  4514
    if(pm.get()=="true"):
lordcrc@384
  4515
        pmtype = luxProp(mat, kn+"light.pmtype", "IESna")
lordcrc@384
  4516
        pmtypes = ["IESna", "imagemap"]
lordcrc@384
  4517
        luxOption("type", pmtype, pmtypes, "type", "Choose Photometric data type to use", gui, 0.6)
lordcrc@384
  4518
        if(pmtype.get() == "imagemap"):
lordcrc@384
  4519
            map = luxProp(mat, kn+"light.pmmapname", "")
lordcrc@384
  4520
            link += luxFile("mapname", map, "map-file", "filename of the photometric map", gui, 1.4)
lordcrc@384
  4521
        if(pmtype.get() == "IESna"):
lordcrc@384
  4522
            map = luxProp(mat, kn+"light.pmiesname", "")
lordcrc@384
  4523
            link += luxFile("iesname", map, "ies-file", "filename of the IES photometric data file", gui, 1.4)
lordcrc@384
  4524
lordcrc@384
  4525
    has_bump_options = 0
lordcrc@384
  4526
    has_object_options = 1
lordcrc@384
  4527
    return (str, link)
lordcrc@384
  4528
lordcrc@384
  4529
def luxLamp(name, kn, mat, gui, level):
lordcrc@384
  4530
    if gui:
lordcrc@384
  4531
        if name != "": gui.newline(name+":", 10, level)
lordcrc@384
  4532
        else: gui.newline("color:", 0, level+1)
lordcrc@384
  4533
#    if gui: gui.newline("", 10, level)
lordcrc@384
  4534
    (str,link) = luxLightSpectrumTexture("L", kn+"light", "1.0 1.0 1.0", 1.0, "Spectrum", "", mat, gui, level+1)
lordcrc@384
  4535
    if gui: gui.newline("")
lordcrc@384
  4536
    link += luxFloat("gain", luxProp(mat, kn+"light.gain", 1.0), 0.0, 100.0, "gain", "Gain/scale multiplier", gui)
lordcrc@384
  4537
    lightgroup = luxProp(mat, kn+"light.lightgroup", "default")
lordcrc@384
  4538
    luxString("lightgroup", lightgroup, "group", "assign light to a named light-group", gui, 1.0)
lordcrc@384
  4539
lordcrc@384
  4540
    if gui: gui.newline("Photometric")
lordcrc@384
  4541
    pm = luxProp(mat, kn+"light.usepm", "false")
lordcrc@384
  4542
    luxBool("photometric", pm, "Photometric Diagram", "Enable Photometric Diagram options", gui, 2.0)
lordcrc@384
  4543
lordcrc@384
  4544
    if(pm.get()=="true"):
lordcrc@384
  4545
        pmtype = luxProp(mat, kn+"light.pmtype", "IESna")
lordcrc@384
  4546
        pmtypes = ["IESna", "imagemap"]
lordcrc@384
  4547
        luxOption("type", pmtype, pmtypes, "type", "Choose Photometric data type to use", gui, 0.6)
lordcrc@384
  4548
        if(pmtype.get() == "imagemap"):
lordcrc@384
  4549
            map = luxProp(mat, kn+"light.pmmapname", "")
lordcrc@384
  4550
            link += luxFile("mapname", map, "map-file", "filename of the photometric map", gui, 1.4)
lordcrc@384
  4551
        if(pmtype.get() == "IESna"):
lordcrc@384
  4552
            map = luxProp(mat, kn+"light.pmiesname", "")
lordcrc@384
  4553
            link += luxFile("iesname", map, "ies-file", "filename of the IES photometric data file", gui, 1.4)
lordcrc@384
  4554
lordcrc@384
  4555
        link += luxBool("flipz", luxProp(mat, kn+"light.flipZ", "true"), "Flip Z", "Flip Z direction in mapping", gui, 2.0)
lordcrc@384
  4556
lordcrc@384
  4557
    return (str, link)
lordcrc@384
  4558
lordcrc@384
  4559
def luxSpot(name, kn, mat, gui, level):
lordcrc@384
  4560
    if gui:
lordcrc@384
  4561
        if name != "": gui.newline(name+":", 10, level)
lordcrc@384
  4562
        else: gui.newline("color:", 0, level+1)
lordcrc@384
  4563
#    if gui: gui.newline("", 10, level)
lordcrc@384
  4564
    (str,link) = luxLightSpectrumTexture("L", kn+"light", "1.0 1.0 1.0", 1.0, "Spectrum", "", mat, gui, level+1)
lordcrc@384
  4565
    if gui: gui.newline("")
lordcrc@384
  4566
    link += luxFloat("gain", luxProp(mat, kn+"light.gain", 1.0), 0.0, 100.0, "gain", "Gain/scale multiplier", gui)
lordcrc@384
  4567
    lightgroup = luxProp(mat, kn+"light.lightgroup", "default")
lordcrc@384
  4568
    luxString("lightgroup", lightgroup, "group", "assign light to a named light-group", gui, 1.0)
lordcrc@384
  4569
lordcrc@384
  4570
    if gui: gui.newline("Projection")
lordcrc@384
  4571
    proj = luxProp(mat, kn+"light.usetexproj", "false")
lordcrc@384
  4572
    luxBool("projection", proj, "Texture Projection", "Enable imagemap texture projection", gui, 2.0)
lordcrc@384
  4573
lordcrc@384
  4574
    if(proj.get() == "true"):
lordcrc@384
  4575
        map = luxProp(mat, kn+"light.pmmapname", "")
lordcrc@384
  4576
        link += luxFile("mapname", map, "map-file", "filename of the photometric map", gui, 2.0)
lordcrc@384
  4577
lordcrc@384
  4578
    return (str, link)
lordcrc@384
  4579
lordcrc@384
  4580
lordcrc@384
  4581
def Preview_Sphereset(mat, kn, state):
lordcrc@384
  4582
    if state=="true":
lordcrc@384
  4583
        luxProp(mat, kn+"prev_sphere", "true").set("true")
lordcrc@384
  4584
        luxProp(mat, kn+"prev_plane", "false").set("false")
lordcrc@384
  4585
        luxProp(mat, kn+"prev_torus", "false").set("false")
lordcrc@384
  4586
def Preview_Planeset(mat, kn, state):
lordcrc@384
  4587
    if state=="true":
lordcrc@384
  4588
        luxProp(mat, kn+"prev_sphere", "true").set("false")
lordcrc@384
  4589
        luxProp(mat, kn+"prev_plane", "false").set("true")
lordcrc@384
  4590
        luxProp(mat, kn+"prev_torus", "false").set("false")
lordcrc@384
  4591
def Preview_Torusset(mat, kn, state):
lordcrc@384
  4592
    if state=="true":
lordcrc@384
  4593
        luxProp(mat, kn+"prev_sphere", "true").set("false")
lordcrc@384
  4594
        luxProp(mat, kn+"prev_plane", "false").set("false")
lordcrc@384
  4595
        luxProp(mat, kn+"prev_torus", "false").set("true")
lordcrc@384
  4596
lordcrc@384
  4597
lordcrc@384
  4598
    
lordcrc@384
  4599
lordcrc@384
  4600
def Preview_Update(mat, kn, defLarge, defType, texName, name, level):
lordcrc@384
  4601
    #print("%s %s %s %s %s %s %s" % (mat, kn, defLarge, defType, texName, name, level))
lordcrc@384
  4602
lordcrc@384
  4603
    global previewing
lordcrc@384
  4604
    previewing = True
lordcrc@384
  4605
    
lordcrc@384
  4606
    Blender.Window.WaitCursor(True)
lordcrc@384
  4607
    scn = Scene.GetCurrent()
lordcrc@384
  4608
    
lordcrc@384
  4609
    # set path mode to absolute for preview
lordcrc@384
  4610
    pm_prop = luxProp(scn, "pathmode", "absolute")
lordcrc@384
  4611
    pm = pm_prop.get()
lordcrc@384
  4612
    pm_prop.set('absolute')
lordcrc@384
  4613
    
lordcrc@384
  4614
lordcrc@384
  4615
    # Size of preview thumbnail
lordcrc@384
  4616
    thumbres = 110 # default 110x110
lordcrc@384
  4617
    if(defLarge):
lordcrc@384
  4618
        large = luxProp(mat, kn+"prev_large", "true")
lordcrc@384
  4619
    else:
lordcrc@384
  4620
        large = luxProp(mat, kn+"prev_large", "false")
lordcrc@384
  4621
    if(large.get() == "true"):
lordcrc@384
  4622
        thumbres = 140 # small 140x140
lordcrc@384
  4623
lordcrc@384
  4624
    thumbbuf = thumbres*thumbres*3
lordcrc@384
  4625
lordcrc@384
  4626
#        consolebin = luxProp(scn, "luxconsole", "").get()
lordcrc@384
  4627
    
lordcrc@384
  4628
    p = get_lux_pipe(scn, buf=thumbbuf, type="luxconsole")
lordcrc@384
  4629
lordcrc@384
  4630
    # Unremark to write debugging output to file
lordcrc@384
  4631
    # p.stdin = open('c:\preview.lxs', 'w')
lordcrc@384
  4632
lordcrc@384
  4633
    if defType == 0:    
lordcrc@384
  4634
        prev_sphere = luxProp(mat, kn+"prev_sphere", "true")
lordcrc@384
  4635
        prev_plane = luxProp(mat, kn+"prev_plane", "false")
lordcrc@384
  4636
        prev_torus = luxProp(mat, kn+"prev_torus", "false")
lordcrc@384
  4637
    elif defType == 1:
lordcrc@384
  4638
        prev_sphere = luxProp(mat, kn+"prev_sphere", "false")
lordcrc@384
  4639
        prev_plane = luxProp(mat, kn+"prev_plane", "true")
lordcrc@384
  4640
        prev_torus = luxProp(mat, kn+"prev_torus", "false")
lordcrc@384
  4641
    else:
lordcrc@384
  4642
        prev_sphere = luxProp(mat, kn+"prev_sphere", "false")
lordcrc@384
  4643
        prev_plane = luxProp(mat, kn+"prev_plane", "false")
lordcrc@384
  4644
        prev_torus = luxProp(mat, kn+"prev_torus", "true")
lordcrc@384
  4645
lordcrc@384
  4646
    # Zoom
lordcrc@384
  4647
    if luxProp(mat, kn+"prev_zoom", "false").get() == "true":
lordcrc@384
  4648
        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')
lordcrc@384
  4649
    else:
lordcrc@384
  4650
        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')
lordcrc@384
  4651
    # Fleximage
lordcrc@384
  4652
    p.stdin.write('Film "fleximage" "integer xresolution" [%i] "integer yresolution" [%i] "integer displayinterval" [3] "integer ldr_writeinterval" [3600] "string tonemapkernel" ["linear"] "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))
lordcrc@384
  4653
    p.stdin.write('PixelFilter "sinc"\n')
lordcrc@384
  4654
    # Quality
lordcrc@384
  4655
    scn = Scene.GetCurrent()
lordcrc@384
  4656
    defprevmat = luxProp(scn, "defprevmat", "high")
lordcrc@384
  4657
    quality = luxProp(mat, kn+"prev_quality", defprevmat.get())
lordcrc@384
  4658
    if quality.get()=="low":
lordcrc@384
  4659
        p.stdin.write('Sampler "lowdiscrepancy" "string pixelsampler" ["hilbert"] "integer pixelsamples" [2]\n')
lordcrc@384
  4660
    elif quality.get()=="medium":
lordcrc@384
  4661
        p.stdin.write('Sampler "lowdiscrepancy" "string pixelsampler" ["hilbert"] "integer pixelsamples" [4]\n')
lordcrc@384
  4662
    elif quality.get()=="high":
lordcrc@384
  4663
        p.stdin.write('Sampler "lowdiscrepancy" "string pixelsampler" ["hilbert"] "integer pixelsamples" [8]\n')
lordcrc@384
  4664
    else: 
lordcrc@384
  4665
        p.stdin.write('Sampler "lowdiscrepancy" "string pixelsampler" ["hilbert"] "integer pixelsamples" [32]\n')
lordcrc@384
  4666
    # SurfaceIntegrator
lordcrc@384
  4667
    if(prev_plane.get()=="false"):
lordcrc@384
  4668
        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')
lordcrc@384
  4669
    else:
lordcrc@384
  4670
        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')
lordcrc@384
  4671
    # World
lordcrc@384
  4672
    p.stdin.write('WorldBegin\n')
lordcrc@384
  4673
    if(prev_sphere.get()=="true"):
lordcrc@384
  4674
        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')
lordcrc@384
  4675
    elif (prev_plane.get()=="true"):
lordcrc@384
  4676
        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')
lordcrc@384
  4677
    else:
lordcrc@384
  4678
        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')
lordcrc@384
  4679
    obwidth = luxProp(mat, kn+"prev_obwidth", 1.0)
lordcrc@384
  4680
    obw = obwidth.get()
lordcrc@384
  4681
    p.stdin.write('TransformBegin\n')
lordcrc@384
  4682
    p.stdin.write('Scale %f %f %f\n'%(obw,obw,obw))
lordcrc@384
  4683
    if texName:
lordcrc@384
  4684
        print("texture "+texName+"  "+name)
lordcrc@384
  4685
        (str, link) = luxTexture(texName, name, "color", "1.0 1.0 1.0", None, None, "", "", mat, None, 0, level)
lordcrc@384
  4686
        link = link.replace(" "+texName+"\"", " Kd\"") # swap texture name to "Kd"
lordcrc@384
  4687
        p.stdin.write(str+"\n")
lordcrc@384
  4688
        p.stdin.write("Material \"matte\" "+link+"\n") 
lordcrc@384
  4689
    else:
lordcrc@384
  4690
        # Material
lordcrc@384
  4691
        p.stdin.write(luxMaterial(mat))
lordcrc@384
  4692
        link = luxProp(mat,"link","").get()
lordcrc@384
  4693
        if kn!="": link = link.rstrip("\"")+":"+kn.strip(".:")+"\""
lordcrc@384
  4694
        p.stdin.write(link+'\n')
lordcrc@384
  4695
    p.stdin.write('TransformEnd\n')
lordcrc@384
  4696
    # Shape
lordcrc@384
  4697
    if(prev_sphere.get()=="true"):
lordcrc@384
  4698
        p.stdin.write('Shape "sphere" "float radius" [1.0]\n')
lordcrc@384
  4699
    elif (prev_plane.get()=="true"):
lordcrc@384
  4700
        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')
lordcrc@384
  4701
    elif (prev_torus.get()=="true"):
lordcrc@384
  4702
        p.stdin.write('Shape "torus" "float radius" [1.0]\n')
lordcrc@384
  4703
    p.stdin.write('AttributeEnd\n')
lordcrc@384
  4704
    # Checkerboard floor
lordcrc@384
  4705
    if(prev_plane.get()=="false"):
lordcrc@384
  4706
        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')
lordcrc@384
  4707
        p.stdin.write('Texture "checks" "color" "checkerboard"')
lordcrc@384
  4708
        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]')
lordcrc@384
  4709
        p.stdin.write('"string mapping" ["uv"] "float uscale" [36.8] "float vscale" [36.0]\n')
lordcrc@384
  4710
        p.stdin.write('Material "matte" "texture Kd" ["checks"]\n')
lordcrc@384
  4711
        p.stdin.write('Shape "loopsubdiv" "integer nlevels" [3] "bool dmnormalsmooth" ["true"] "bool dmsharpboundary" ["false"] ')
lordcrc@384
  4712
        p.stdin.write('"integer indices" [ 0 1 2 0 2 3 1 0 4 1 4 5 5 4 6 5 6 7 ]')
lordcrc@384
  4713
        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')
lordcrc@384
  4714
        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')
lordcrc@384
  4715
        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')
lordcrc@384
  4716
        p.stdin.write('AttributeEnd\n')
lordcrc@384
  4717
    # Lightsource
lordcrc@384
  4718
    if(prev_plane.get()=="false"):
lordcrc@384
  4719
        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')
lordcrc@384
  4720
    else:
lordcrc@384
  4721
        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')
lordcrc@384
  4722
    area = luxProp(mat, kn+"prev_arealight", "false")
lordcrc@384
  4723
    if(area.get() == "false"):
lordcrc@384
  4724
        p.stdin.write('Texture "pL" "color" "blackbody" "float temperature" [6500.0]\n')
lordcrc@384
  4725
        p.stdin.write('LightSource "point" "texture L" ["pL"] "float gain" [0.002]')
lordcrc@384
  4726
    else:
lordcrc@384
  4727
        p.stdin.write('ReverseOrientation\n')
lordcrc@384
  4728
        p.stdin.write('AreaLightSource "area" "color L" [1.0 1.0 1.0]\n')
lordcrc@384
  4729
        if(prev_plane.get()=="false"):
lordcrc@384
  4730
            p.stdin.write(' "float gain" [0.3]\n')
lordcrc@384
  4731
        p.stdin.write('Shape "disk" "float radius" [1.0]\nAttributeEnd\n')
lordcrc@384
  4732
    p.stdin.write('WorldEnd\n')
lordcrc@384
  4733
    
lordcrc@384
  4734
    previewing = False
lordcrc@384
  4735
lordcrc@384
  4736
    data = p.communicate()[0]
lordcrc@384
  4737
    p.stdin.close()
lordcrc@384
  4738
    
lordcrc@384
  4739
    # restore path mode
lordcrc@384
  4740
    pm_prop.set(pm)    
lordcrc@384
  4741
    
lordcrc@384
  4742
    datalen = len(data)
lordcrc@384
  4743
    if(datalen < thumbbuf): 
lordcrc@384
  4744
        print("error on preview: got %i bytes, expected %i" % (datalen, thumbbuf))
lordcrc@384
  4745
        return
lordcrc@384
  4746
    global previewCache
lordcrc@384
  4747
    image = luxImage()
lordcrc@384
  4748
    image.decodeLuxConsole(thumbres, thumbres, data)
lordcrc@384
  4749
    previewCache[(mat.name+":"+kn).__hash__()] = image
lordcrc@384
  4750
    Draw.Redraw()
lordcrc@384
  4751
    Blender.Window.WaitCursor(False)
lordcrc@384
  4752
lordcrc@384
  4753
def luxPreview(mat, name, defType=0, defEnabled=False, defLarge=False, texName=None, gui=None, level=0, color=None):
lordcrc@384
  4754
    
lordcrc@384
  4755
lordcrc@384
  4756
    if gui:
lordcrc@384
  4757
        kn = name
lordcrc@384
  4758
        if texName: kn += ":"+texName
lordcrc@384
  4759
        if kn != "": kn += "."
lordcrc@384
  4760
        if(defEnabled == True):
lordcrc@384
  4761
            showpreview = luxProp(mat, kn+"prev_show", "true")
lordcrc@384
  4762
        else:
lordcrc@384
  4763
            showpreview = luxProp(mat, kn+"prev_show", "false")
lordcrc@384
  4764
        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)]))
lordcrc@384
  4765
        if showpreview.get()=="true": 
lordcrc@384
  4766
            if(defLarge):
lordcrc@384
  4767
                large = luxProp(mat, kn+"prev_large", "true")
lordcrc@384
  4768
            else:
lordcrc@384
  4769
                large = luxProp(mat, kn+"prev_large", "false")
lordcrc@384
  4770
            voffset = -8
lordcrc@384
  4771
            rr = 5.65 
lordcrc@384
  4772
            if(large.get() == "true"):
lordcrc@384
  4773
                rr = 7
lordcrc@384
  4774
                voffset = 22
lordcrc@384
  4775
            gui.newline()
lordcrc@384
  4776
            r = gui.getRect(1.1, rr)
lordcrc@384
  4777
            if(color != None):
lordcrc@384
  4778
                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)
lordcrc@384
  4779
            try: previewCache[(mat.name+":"+kn).__hash__()].draw(r[0]-82, r[1]+4)
lordcrc@384
  4780
            except: pass
lordcrc@384
  4781
lordcrc@384
  4782
            prev_sphere = luxProp(mat, kn+"prev_sphere", "true")
lordcrc@384
  4783
            prev_plane = luxProp(mat, kn+"prev_plane", "false")
lordcrc@384
  4784
            prev_torus = luxProp(mat, kn+"prev_torus", "false")
lordcrc@384
  4785
            if defType == 1:
lordcrc@384
  4786
                prev_sphere = luxProp(mat, kn+"prev_sphere", "false")
lordcrc@384
  4787
                prev_plane = luxProp(mat, kn+"prev_plane", "true")
lordcrc@384
  4788
                prev_torus = luxProp(mat, kn+"prev_torus", "false")
lordcrc@384
  4789
            elif defType == 2:
lordcrc@384
  4790
                prev_sphere = luxProp(mat, kn+"prev_sphere", "false")
lordcrc@384
  4791
                prev_plane = luxProp(mat, kn+"prev_plane", "false")
lordcrc@384
  4792
                prev_torus = luxProp(mat, kn+"prev_torus", "true")
lordcrc@384
  4793
lordcrc@384
  4794
            # preview mode toggle buttons
lordcrc@384
  4795
            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)]))
lordcrc@384
  4796
            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)]))
lordcrc@384
  4797
            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)]))
lordcrc@384
  4798
lordcrc@384
  4799
            # Zoom toggle
lordcrc@384
  4800
            zoom = luxProp(mat, kn+"prev_zoom", "false")
lordcrc@384
  4801
            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)]))
lordcrc@384
  4802
lordcrc@384
  4803
            area = luxProp(mat, kn+"prev_arealight", "false")
lordcrc@384
  4804
            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)]))
lordcrc@384
  4805
lordcrc@384
  4806
            # Object width
lordcrc@384
  4807
            obwidth = luxProp(mat, kn+"prev_obwidth", 1.0)
lordcrc@384
  4808
            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))
lordcrc@384
  4809
lordcrc@384
  4810
            # large/small size
lordcrc@384
  4811
            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)]))
lordcrc@384
  4812
lordcrc@384
  4813
            # Preview Quality
lordcrc@384
  4814
            qs = ["low","medium","high","very high"]
lordcrc@384
  4815
            scn = Scene.GetCurrent()
lordcrc@384
  4816
            defprevmat = luxProp(scn, "defprevmat", "high")
lordcrc@384
  4817
            quality = luxProp(mat, kn+"prev_quality", defprevmat.get())
lordcrc@384
  4818
            luxOptionRect("quality", quality, qs, "  Quality", "select preview quality", gui, r[0]+200, r[1]+100+voffset, 88, 18)
lordcrc@384
  4819
lordcrc@384
  4820
            # Update preview
lordcrc@384
  4821
            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))
lordcrc@384
  4822
lordcrc@384
  4823
            # Reset depths after getRect()
lordcrc@384
  4824
            gui.y -= 92+voffset
lordcrc@384
  4825
            gui.y -= gui.h
lordcrc@384
  4826
            gui.hmax = 18 + 4
lordcrc@384
  4827
lordcrc@384
  4828
def luxMaterialBlock(name, luxname, key, mat, gui=None, level=0, str_opt=""):
lordcrc@384
  4829
    global icon_mat, icon_matmix, icon_map3dparam
lordcrc@384
  4830
    def c(t1, t2):
lordcrc@384
  4831
        return (t1[0]+t2[0], t1[1]+t2[1])
lordcrc@384
  4832
    str = ""
lordcrc@384
  4833
    if key == "": keyname = kn = name
lordcrc@384
  4834
    else: keyname = kn = "%s:%s"%(key, name)
lordcrc@384
  4835
    if kn != "": kn += "."
lordcrc@384
  4836
    if keyname == "": matname = mat.getName()
lordcrc@384
  4837
    else: matname = "%s:%s"%(mat.getName(), keyname)
lordcrc@384
  4838
lordcrc@384
  4839
    if mat:
lordcrc@384
  4840
        mattype = luxProp(mat, kn+"type", "matte")
lordcrc@384
  4841
        # Set backwards compatibility of glossy material from plastic and substrate
lordcrc@384
  4842
        if(mattype.get() == "substrate" or mattype.get() == "plastic"):
lordcrc@384
  4843
            mattype.set("glossy")
lordcrc@384
  4844
lordcrc@384
  4845
        # this is reverse order than in shown in the dropdown list
lordcrc@384
  4846
        materials = ["null","mix","mirror","shinymetal","metal","mattetranslucent","matte","glossy","roughglass","glass","carpaint"]
lordcrc@384
  4847
        
lordcrc@384
  4848
        if level == 0: materials = ["portal","light","boundvolume"]+materials
lordcrc@384
  4849
        if gui:
lordcrc@384
  4850
            icon = icon_mat
lordcrc@384
  4851
            if mattype.get() == "mix": icon = icon_matmix
lordcrc@384
  4852
            if level == 0: gui.newline("Material type:", 12, level, icon, [0.75,0.5,0.25])
lordcrc@384
  4853
            else: gui.newline(name+":", 12, level, icon, scalelist([0.75,0.6,0.25],2.0/(level+2)))
lordcrc@384
  4854
lordcrc@384
  4855
lordcrc@384
  4856
        link = luxOption("type", mattype, materials, "  TYPE", "select material type", gui)
lordcrc@384
  4857
        showadvanced = luxProp(mat, kn+"showadvanced", "false")
lordcrc@384
  4858
        luxBool("advanced", showadvanced, "Advanced", "Show advanced options", gui, 0.6)
lordcrc@384
  4859
        showhelp = luxProp(mat, kn+"showhelp", "false")
lordcrc@384
  4860
        luxHelp("help", showhelp, "Help", "Show Help Information", gui, 0.4)
lordcrc@384
  4861
lordcrc@384
  4862
        # show copy/paste menu button
lordcrc@384
  4863
        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))
lordcrc@384
  4864
lordcrc@384
  4865
        # Draw Material preview option
lordcrc@384
  4866
        showmatprev = False
lordcrc@384
  4867
        if level == 0:
lordcrc@384
  4868
            showmatprev = True
lordcrc@384
  4869
        if gui: luxPreview(mat, keyname, 0, showmatprev, True, None, gui, level, [0.746, 0.625, 0.5])
lordcrc@384
  4870
lordcrc@384
  4871
lordcrc@384
  4872
        if gui: gui.newline()
lordcrc@384
  4873
        has_object_options   = 0 # disable object options by default
lordcrc@384
  4874
        has_bump_options     = 0 # disable bump mapping options by default
lordcrc@384
  4875
        has_emission_options = 0 # disable emission options by default
lordcrc@384
  4876
        has_compositing_options = 0 # disable compositing options by default
lordcrc@384
  4877
lordcrc@384
  4878
        if mattype.get() == "mix":
lordcrc@384
  4879
            (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))
lordcrc@384
  4880
            (str,link) = c((str,link), luxMaterialBlock("mat1", "namedmaterial1", keyname, mat, gui, level+1))
lordcrc@384
  4881
            (str,link) = c((str,link), luxMaterialBlock("mat2", "namedmaterial2", keyname, mat, gui, level+1))
lordcrc@384
  4882
            has_bump_options = 0
lordcrc@384
  4883
            has_object_options = 1
lordcrc@384
  4884
            has_emission_options = 1
lordcrc@384
  4885
            has_compositing_options = 0
lordcrc@384
  4886
lordcrc@384
  4887
        if mattype.get() == "light":
lordcrc@384
  4888
            if luxProp(Scene.GetCurrent(), "nolg", "false").get()!="true":
lordcrc@384
  4889
                lightgroup = luxProp(mat, kn+"light.lightgroup", "default")
lordcrc@384
  4890
                link = "LightGroup \"%s\"\n"%lightgroup.get()
lordcrc@384
  4891
            else:
lordcrc@384
  4892
                link = ''
lordcrc@384
  4893
            link += "AreaLightSource \"area\""
lordcrc@384
  4894
            (str,link) = c((str,link), luxLight("", kn, mat, gui, level))
lordcrc@384
  4895
            has_bump_options = 0
lordcrc@384
  4896
            has_object_options = 1
lordcrc@384
  4897
            has_emission_options = 0
lordcrc@384
  4898
            has_compositing_options = 1
lordcrc@384
  4899
lordcrc@384
  4900
        if mattype.get() == "boundvolume":
lordcrc@384
  4901
            link = ""
lordcrc@384
  4902
            voltype = luxProp(mat, kn+"vol.type", "homogeneous")
lordcrc@384
  4903
            vols = ["homogeneous", "exponential", "cloud"]
lordcrc@384
  4904
            vollink = luxOption("type", voltype, vols, "type", "", gui)
lordcrc@384
  4905
            if voltype.get() == "homogeneous":
lordcrc@384
  4906
                link = "Volume \"homogeneous\""
lordcrc@384
  4907
            if voltype.get() == "exponential":
lordcrc@384
  4908
                link = "Volume \"exponential\""
lordcrc@384
  4909
            if voltype.get() == "cloud":
lordcrc@384
  4910
                link = "Volume \"cloud\""
lordcrc@384
  4911
lordcrc@384
  4912
            if gui: gui.newline("absorption:", 0, level+1)
lordcrc@384
  4913
            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)
lordcrc@384
  4914
            if gui: gui.newline("scattering:", 0, level+1)
lordcrc@384
  4915
            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)
lordcrc@384
  4916
            if gui: gui.newline("emission:", 0, level+1)
lordcrc@384
  4917
            link += luxRGB("Le", luxProp(mat, kn+"vol.le", "0.0 0.0 0.0"), 1.0, "Le", "The volume's emission spectrum", gui)
lordcrc@384
  4918
            if gui: gui.newline("assymetry:", 0, level+1)
lordcrc@384
  4919
            link += luxFloat("g", luxProp(mat, kn+"vol.g", 0.0), 0.0, 100.0, "g", "The phase function asymmetry parameter", gui)
lordcrc@384
  4920
lordcrc@384
  4921
            if voltype.get() == "exponential":
lordcrc@384
  4922
                if gui: gui.newline("form:", 0, level+1)
lordcrc@384
  4923
                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)
lordcrc@384
  4924
                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)
lordcrc@384
  4925
                if gui: gui.newline("updir:", 0, level+1)
lordcrc@384
  4926
                link += luxVector("updir", luxProp(mat, kn+"vol.updir", "0 0 1"), -1.0, 1.0, "updir", "Up direction vector", gui, 2.0)
lordcrc@384
  4927
lordcrc@384
  4928
            if voltype.get() == "cloud":
lordcrc@384
  4929
                if gui: gui.newline("cloud:", 0, level+1)
lordcrc@384
  4930
                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)
lordcrc@384
  4931
                link += luxFloat("noisescale", luxProp(mat, kn+"vol.noisescale", 0.3), 0.1, 2.0, "noisesize", "Size of cloud noise", gui)
lordcrc@384
  4932
                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)
lordcrc@384
  4933
                link += luxFloat("noiseoffset", luxProp(mat, kn+"vol.noiseoffset", 0.0), 0.0, 1000.0, "noiseoffset", "Useful for creating unique clouds", gui )
lordcrc@384
  4934
                link += luxInt("octaves", luxProp(mat, kn+"vol.octaves", 3), 1, 8, "octaves", "Sets the amount of detail for the noise", gui )
lordcrc@384
  4935
                link += luxFloat("omega", luxProp(mat, kn+"vol.omega", 0.75), 0.1, 1.0, "omega", "Sets the scale difference of each successive octave", gui )
lordcrc@384
  4936
                link += luxFloat("sharpness", luxProp(mat, kn+"vol.sharpness", 6.0), 0.2, 10.0, "sharpness", "Sets the sharpness of the noise", gui)
lordcrc@384
  4937
                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)
lordcrc@384
  4938
                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)
lordcrc@384
  4939
                link += luxInt("spheres", luxProp(mat, kn+"vol.spheres", 2000), 0, 10000, "spheres", "Number of small spheres for cumulus shape. 0 is non-cumulus.", gui )
lordcrc@384
  4940
                link += luxFloat("spheresize", luxProp(mat, kn+"vol.spheresize", 0.15), 0.05, 0.55, "spheresize", "Size of cumulus spheres", gui)
lordcrc@384
  4941
 
lordcrc@384
  4942
            link += str_opt
lordcrc@384
  4943
lordcrc@384
  4944
            has_bump_options = 0
lordcrc@384
  4945
            has_object_options = 0
lordcrc@384
  4946
            has_emission_options = 0
lordcrc@384
  4947
lordcrc@384
  4948
            return (str, link)
lordcrc@384
  4949
lordcrc@384
  4950
        if mattype.get() == "carpaint":
lordcrc@384
  4951
            if gui: gui.newline("Preset:", 0, level+1)
lordcrc@384
  4952
            carname = luxProp(mat, kn+"carpaint.name", "Custom")
lordcrc@384
  4953
            cars = ["Custom","ford f8","polaris silber","opel titan","bmw339","2k acrylack","white","blue","blue matte"]
lordcrc@384
  4954
            carlink = luxOption("name", carname, cars, "name", "", gui)
lordcrc@384
  4955
            if carname.get() == "Custom":
lordcrc@384
  4956
                (str,link) = c((str,link), luxSpectrumTexture("Kd", keyname, "1.0 1.0 1.0", 1.0, "diffuse", "", mat, gui, level+1))
lordcrc@384
  4957
                (str,link) = c((str,link), luxSpectrumTexture("Ks1", keyname, "1.0 1.0 1.0", 1.0, "specular1", "", mat, gui, level+1))
lordcrc@384
  4958
                (str,link) = c((str,link), luxSpectrumTexture("Ks2", keyname, "1.0 1.0 1.0", 1.0, "specular2", "", mat, gui, level+1))
lordcrc@384
  4959
                (str,link) = c((str,link), luxSpectrumTexture("Ks3", keyname, "1.0 1.0 1.0", 1.0, "specular3", "", mat, gui, level+1))
lordcrc@384
  4960
                (str,link) = c((str,link), luxFloatTexture("R1", keyname, 1.0, 0.0, 1.0, "R1", "", mat, gui, level+1))
lordcrc@384
  4961
                (str,link) = c((str,link), luxFloatTexture("R2", keyname, 1.0, 0.0, 1.0, "R2", "", mat, gui, level+1))
lordcrc@384
  4962
                (str,link) = c((str,link), luxFloatTexture("R3", keyname, 1.0, 0.0, 1.0, "R3", "", mat, gui, level+1))
lordcrc@384
  4963
                (str,link) = c((str,link), luxFloatTexture("M1", keyname, 1.0, 0.0, 1.0, "M1", "", mat, gui, level+1))
lordcrc@384
  4964
                (str,link) = c((str,link), luxFloatTexture("M2", keyname, 1.0, 0.0, 1.0, "M2", "", mat, gui, level+1))
lordcrc@384
  4965
                (str,link) = c((str,link), luxFloatTexture("M3", keyname, 1.0, 0.0, 1.0, "M3", "", mat, gui, level+1))
lordcrc@384
  4966
            else: link += carlink
lordcrc@384
  4967
            absorption = luxProp(mat, keyname+".useabsorption", "false")
lordcrc@384
  4968
            luxCollapse("absorption", absorption, "Absorption", "Enable Coating Absorption", gui, 2.0)
lordcrc@384
  4969
            if absorption.get() == "true":
lordcrc@384
  4970
                (str,link) = c((str,link), luxSpectrumTexture("Ka", keyname, "0.2 0.2 0.2", 1.0, "absorption", "", mat, gui, level+1))
lordcrc@384
  4971
                (str,link) = c((str,link), luxFloatTexture("d", keyname, 5.0, 0.0, 15.0, "depth", "", mat, gui, level+1))
lordcrc@384
  4972
            has_bump_options = 1
lordcrc@384
  4973
            has_object_options = 1
lordcrc@384
  4974
            has_emission_options = 1
lordcrc@384
  4975
            has_compositing_options = 1
lordcrc@384
  4976
        
lordcrc@384
  4977
        if mattype.get() == "glass":
lordcrc@384
  4978
            (str,link) = c((str,link), luxSpectrumTexture("Kr", keyname, "1.0 1.0 1.0", 1.0, "reflection", "", mat, gui, level+1))
lordcrc@384
  4979
            (str,link) = c((str,link), luxSpectrumTexture("Kt", keyname, "1.0 1.0 1.0", 1.0, "transmission", "", mat, gui, level+1))
lordcrc@384
  4980
            (str,link) = c((str,link), luxIORFloatTexture("index", keyname, 1.5, 1.0, 6.0, "IOR", "", mat, gui, level+1))
lordcrc@384
  4981
            architectural = luxProp(mat, keyname+".architectural", "false")
lordcrc@384
  4982
            link += luxBool("architectural", architectural, "architectural", "Enable architectural glass", gui, 2.0)
lordcrc@384
  4983
            if architectural.get() == "false":
lordcrc@384
  4984
                chromadisp = luxProp(mat, keyname+".chromadisp", "false")
lordcrc@384
  4985
                luxCollapse("chromadisp", chromadisp, "Dispersive Refraction", "Enable Chromatic Dispersion", gui, 2.0)
lordcrc@384
  4986
                if chromadisp.get() == "true":
lordcrc@384
  4987
                    (str,link) = c((str,link), luxCauchyBFloatTexture("cauchyb", keyname, 0.0, 0.0, 1.0, "cauchyb", "", mat, gui, level+1))
lordcrc@384
  4988
                thinfilm = luxProp(mat, keyname+".thinfilm", "false")
lordcrc@384
  4989
                luxCollapse("thinfilm", thinfilm, "Thin Film Coating", "Enable Thin Film Coating", gui, 2.0)
lordcrc@384
  4990
                if thinfilm.get() == "true":
lordcrc@384
  4991
                    (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))
lordcrc@384
  4992
                    (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))
lordcrc@384
  4993
            has_bump_options = 1
lordcrc@384
  4994
            has_object_options = 1
lordcrc@384
  4995
            has_emission_options = 1
lordcrc@384
  4996
            has_compositing_options = 1
lordcrc@384
  4997
            
lordcrc@384
  4998
        if mattype.get() == "matte":
lordcrc@384
  4999
            orennayar = luxProp(mat, keyname+".orennayar", "false")
lordcrc@384
  5000
            (str,link) = c((str,link), luxSpectrumTexture("Kd", keyname, "1.0 1.0 1.0", 1.0, "diffuse", "", mat, gui, level+1))
lordcrc@384
  5001
            luxCollapse("orennayar", orennayar, "Oren-Nayar", "Enable Oren-Nayar BRDF", gui, 2.0)
lordcrc@384
  5002
            if orennayar.get() == "true":
lordcrc@384
  5003
                (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))
lordcrc@384
  5004
            has_bump_options = 1
lordcrc@384
  5005
            has_object_options = 1
lordcrc@384
  5006
            has_emission_options = 1
lordcrc@384
  5007
            has_compositing_options = 1
lordcrc@384
  5008
        
lordcrc@384
  5009
        if mattype.get() == "mattetranslucent":
lordcrc@384
  5010
            orennayar = luxProp(mat, keyname+".orennayar", "false")
lordcrc@384
  5011
            (str,link) = c((str,link), luxSpectrumTexture("Kr", keyname, "1.0 1.0 1.0", 1.0, "reflection", "", mat, gui, level+1))
lordcrc@384
  5012
            (str,link) = c((str,link), luxSpectrumTexture("Kt", keyname, "1.0 1.0 1.0", 1.0, "transmission", "", mat, gui, level+1))
lordcrc@384
  5013
            luxCollapse("orennayar", orennayar, "Oren-Nayar", "Enable Oren-Nayar BRDF", gui, 2.0)
lordcrc@384
  5014
            if orennayar.get() == "true":
lordcrc@384
  5015
                (str,link) = c((str,link), luxFloatTexture("sigma", keyname, 0.0, 0.0, 100.0, "sigma", "", mat, gui, level+1))
lordcrc@384
  5016
            has_bump_options = 1
lordcrc@384
  5017
            has_object_options = 1
lordcrc@384
  5018
            has_emission_options = 1
lordcrc@384
  5019
            has_compositing_options = 1
lordcrc@384
  5020
        
lordcrc@384
  5021
        if mattype.get() == "metal":
lordcrc@384
  5022
            if gui: gui.newline("name:", 0, level+1)
lordcrc@384
  5023
            metalname = luxProp(mat, kn+"metal.name", "")
lordcrc@384
  5024
            metals = ["aluminium","amorphous carbon","silver","gold","copper"]
lordcrc@384
  5025
lordcrc@384
  5026
            if not(metalname.get() in metals):
lordcrc@384
  5027
                metals.append(metalname.get())
lordcrc@384
  5028
            metallink = luxOption("name", metalname, metals, "name", "", gui, 1.88)
lordcrc@384
  5029
            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"))
lordcrc@384
  5030
            link += luxstr(metallink)
lordcrc@384
  5031
            anisotropic = luxProp(mat, kn+"metal.anisotropic", "false")
lordcrc@384
  5032
            if gui:
lordcrc@384
  5033
                gui.newline("")
lordcrc@384
  5034
                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)]))
lordcrc@384
  5035
            if anisotropic.get()=="true":
lordcrc@384
  5036
                (str,link) = c((str,link), luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "u-exponent", "", mat, gui, level+1))
lordcrc@384
  5037
                (str,link) = c((str,link), luxExponentTexture("vroughness", keyname, 0.002, 0.0, 1.0, "v-exponent", "", mat, gui, level+1))
lordcrc@384
  5038
            else:
lordcrc@384
  5039
                (s, l) = luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "exponent", "", mat, gui, level+1)
lordcrc@384
  5040
                (str,link) = c((str,link), (s, l))
lordcrc@384
  5041
                link += l.replace("uroughness", "vroughness", 1)
lordcrc@384
  5042
                
lordcrc@384
  5043
            has_bump_options = 1
lordcrc@384
  5044
            has_object_options = 1
lordcrc@384
  5045
            has_emission_options = 1
lordcrc@384
  5046
            has_compositing_options = 1
lordcrc@384
  5047
            
lordcrc@384
  5048
        if mattype.get() == "mirror":
lordcrc@384
  5049
            (str,link) = c((str,link), luxSpectrumTexture("Kr", keyname, "1.0 1.0 1.0", 1.0, "reflection", "", mat, gui, level+1))
lordcrc@384
  5050
            thinfilm = luxProp(mat, keyname+".thinfilm", "false")
lordcrc@384
  5051
            luxCollapse("thinfilm", thinfilm, "Thin Film Coating", "Enable Thin Film Coating", gui, 2.0)
lordcrc@384
  5052
            if thinfilm.get() == "true":
lordcrc@384
  5053
                (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))
lordcrc@384
  5054
                (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))
lordcrc@384
  5055
lordcrc@384
  5056
            has_bump_options = 1
lordcrc@384
  5057
            has_object_options = 1
lordcrc@384
  5058
            has_emission_options = 1
lordcrc@384
  5059
            has_compositing_options = 1
lordcrc@384
  5060
            
lordcrc@384
  5061
        if mattype.get() == "roughglass":
lordcrc@384
  5062
            (str,link) = c((str,link), luxSpectrumTexture("Kr", keyname, "1.0 1.0 1.0", 1.0, "reflection", "", mat, gui, level+1))
lordcrc@384
  5063
            (str,link) = c((str,link), luxSpectrumTexture("Kt", keyname, "1.0 1.0 1.0", 1.0, "transmission", "", mat, gui, level+1))
lordcrc@384
  5064
            anisotropic = luxProp(mat, kn+"roughglass.anisotropic", "false")
lordcrc@384
  5065
            if gui:
lordcrc@384
  5066
                gui.newline("")
lordcrc@384
  5067
                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)]))
lordcrc@384
  5068
            if anisotropic.get()=="true":
lordcrc@384
  5069
                (str,link) = c((str,link), luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "u-exponent", "", mat, gui, level+1))
lordcrc@384
  5070
                (str,link) = c((str,link), luxExponentTexture("vroughness", keyname, 0.002, 0.0, 1.0, "v-exponent", "", mat, gui, level+1))
lordcrc@384
  5071
            else:
lordcrc@384
  5072
                (s, l) = luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "exponent", "", mat, gui, level+1)
lordcrc@384
  5073
                (str,link) = c((str,link), (s, l))
lordcrc@384
  5074
                link += l.replace("uroughness", "vroughness", 1)
lordcrc@384
  5075
            (str,link) = c((str,link), luxIORFloatTexture("index", keyname, 1.5, 1.0, 6.0, "IOR", "", mat, gui, level+1))
lordcrc@384
  5076
            chromadisp = luxProp(mat, keyname+".chromadisp", "false")
lordcrc@384
  5077
            luxCollapse("chromadisp", chromadisp, "Dispersive Refraction", "Enable Chromatic Dispersion", gui, 2.0)
lordcrc@384
  5078
            if chromadisp.get() == "true":
lordcrc@384
  5079
                (str,link) = c((str,link), luxCauchyBFloatTexture("cauchyb", keyname, 0.0, 0.0, 1.0, "cauchyb", "", mat, gui, level+1))
lordcrc@384
  5080
            has_bump_options = 1
lordcrc@384
  5081
            has_object_options = 1
lordcrc@384
  5082
            has_emission_options = 1
lordcrc@384
  5083
            has_compositing_options = 1
lordcrc@384
  5084
            
lordcrc@384
  5085
        if mattype.get() == "shinymetal":
lordcrc@384
  5086
            (str,link) = c((str,link), luxSpectrumTexture("Kr", keyname, "1.0 1.0 1.0", 1.0, "reflection", "", mat, gui, level+1))
lordcrc@384
  5087
            (str,link) = c((str,link), luxSpectrumTexture("Ks", keyname, "1.0 1.0 1.0", 1.0, "specular", "", mat, gui, level+1))
lordcrc@384
  5088
            anisotropic = luxProp(mat, kn+"shinymetal.anisotropic", "false")
lordcrc@384
  5089
            if gui:
lordcrc@384
  5090
                gui.newline("")
lordcrc@384
  5091
                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)]))
lordcrc@384
  5092
            if anisotropic.get()=="true":
lordcrc@384
  5093
                (str,link) = c((str,link), luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "u-exponent", "", mat, gui, level+1))
lordcrc@384
  5094
                (str,link) = c((str,link), luxExponentTexture("vroughness", keyname, 0.002, 0.0, 1.0, "v-exponent", "", mat, gui, level+1))
lordcrc@384
  5095
            else:
lordcrc@384
  5096
                (s, l) = luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "exponent", "", mat, gui, level+1)
lordcrc@384
  5097
                (str,link) = c((str,link), (s, l))
lordcrc@384
  5098
                link += l.replace("uroughness", "vroughness", 1)
lordcrc@384
  5099
lordcrc@384
  5100
            thinfilm = luxProp(mat, keyname+".thinfilm", "false")
lordcrc@384
  5101
            luxCollapse("thinfilm", thinfilm, "Thin Film Coating", "Enable Thin Film Coating", gui, 2.0)
lordcrc@384
  5102
            if thinfilm.get() == "true":
lordcrc@384
  5103
                (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))
lordcrc@384
  5104
                (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))
lordcrc@384
  5105
lordcrc@384
  5106
            has_bump_options = 1
lordcrc@384
  5107
            has_object_options = 1
lordcrc@384
  5108
            has_emission_options = 1
lordcrc@384
  5109
            has_compositing_options = 1
lordcrc@384
  5110
            
lordcrc@384
  5111
        if mattype.get() == "glossy":
lordcrc@384
  5112
            (str,link) = c((str,link), luxSpectrumTexture("Kd", keyname, "1.0 1.0 1.0", 1.0, "diffuse", "", mat, gui, level+1))
lordcrc@384
  5113
            useior = luxProp(mat, keyname+".useior", "false")
lordcrc@384
  5114
            if gui:
lordcrc@384
  5115
                gui.newline("")
lordcrc@384
  5116
                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)]))
lordcrc@384
  5117
            if useior.get() == "true":
lordcrc@384
  5118
                (str,link) = c((str,link), luxIORFloatTexture("index", keyname, 1.5, 1.0, 50.0, "IOR", "", mat, gui, level+1))
lordcrc@384
  5119
                link += " \"color Ks\" [1.0 1.0 1.0]"    
lordcrc@384
  5120
            else:
lordcrc@384
  5121
                (str,link) = c((str,link), luxSpectrumTexture("Ks", keyname, "1.0 1.0 1.0", 1.0, "specular", "", mat, gui, level+1))
lordcrc@384
  5122
                link += " \"float index\" [0.0]"    
lordcrc@384
  5123
            anisotropic = luxProp(mat, kn+"glossy.anisotropic", "false")
lordcrc@384
  5124
            if gui:
lordcrc@384
  5125
                gui.newline("")
lordcrc@384
  5126
                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)]))
lordcrc@384
  5127
            if anisotropic.get()=="true":
lordcrc@384
  5128
                (str,link) = c((str,link), luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "u-exponent", "", mat, gui, level+1))
lordcrc@384
  5129
                (str,link) = c((str,link), luxExponentTexture("vroughness", keyname, 0.002, 0.0, 1.0, "v-exponent", "", mat, gui, level+1))
lordcrc@384
  5130
            else:
lordcrc@384
  5131
                (s, l) = luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "exponent", "", mat, gui, level+1)
lordcrc@384
  5132
                (str,link) = c((str,link), (s, l))
lordcrc@384
  5133
                link += l.replace("uroughness", "vroughness", 1)
lordcrc@384
  5134
lordcrc@384
  5135
            absorption = luxProp(mat, keyname+".useabsorption", "false")
lordcrc@384
  5136
            luxCollapse("absorption", absorption, "Absorption", "Enable Coating Absorption", gui, 2.0)
lordcrc@384
  5137
            if absorption.get() == "true":
lordcrc@384
  5138
                (str,link) = c((str,link), luxSpectrumTexture("Ka", keyname, "0.2 0.2 0.2", 1.0, "absorption", "", mat, gui, level+1))
lordcrc@384
  5139
                (str,link) = c((str,link), luxFloatTexture("d", keyname, 0.15, 0.0, 15.0, "depth", "", mat, gui, level+1))
lordcrc@384
  5140
            has_bump_options = 1
lordcrc@384
  5141
            has_object_options = 1
lordcrc@384
  5142
            has_emission_options = 1
lordcrc@384
  5143
            has_compositing_options = 1
lordcrc@384
  5144
            
lordcrc@384
  5145
        if mattype.get() == 'null':
lordcrc@384
  5146
            has_emission_options = 1
lordcrc@384
  5147
lordcrc@384
  5148
        # Bump mapping options (common)
lordcrc@384
  5149
        if (has_bump_options == 1):
lordcrc@384
  5150
            usebump = luxProp(mat, keyname+".usebump", "false")
lordcrc@384
  5151
            luxCollapse("usebump", usebump, "Bump Map", "Enable Bump Mapping options", gui, 2.0)
lordcrc@384
  5152
            if usebump.get() == "true":
tom@408
  5153
                (str,link) = c((str,link), luxFloatTexture("bumpmap", keyname, 0.0, -1.0, 1.0, "bumpmap", "bumpmap scale in meters - i.e. 0.01 = 1 cm", mat, gui, level+1))
lordcrc@384
  5154
lordcrc@384
  5155
        # emission options (common)
lordcrc@384
  5156
        if (level == 0):
lordcrc@384
  5157
            if (has_emission_options == 1):
lordcrc@384
  5158
                if gui: gui.newline("", 2, level, None, [0.6,0.6,0.4])
lordcrc@384
  5159
                useemission = luxProp(mat, "emission", "false")
lordcrc@384
  5160
                luxCollapse("useemission", useemission, "Emission", "Enable emission options", gui, 2.0)
lordcrc@384
  5161
                if useemission.get() == "true":
lordcrc@384
  5162
                    # emission GUI is here but lux export will be done later 
lordcrc@384
  5163
                    luxLight("", "", mat, gui, level)
lordcrc@384
  5164
            else: luxProp(mat, "emission", "false").set("false") # prevent from exporting later
lordcrc@384
  5165
lordcrc@384
  5166
lordcrc@384
  5167
        # Compositing options (common)
lordcrc@384
  5168
        # Note - currently only display options when using distributedpath integrator
lordcrc@384
  5169
        integratortype = luxProp(Scene.GetCurrent(), "sintegrator.type", "bidirectional")
lordcrc@384
  5170
        if (integratortype.get() == "distributedpath" and level == 0):
lordcrc@384
  5171
            if (has_compositing_options == 1):
lordcrc@384
  5172
                if gui: gui.newline("", 2, level, None, [0.4,0.4,0.6])
lordcrc@384
  5173
                usecompo = luxProp(mat, "compo", "false")
lordcrc@384
  5174
                luxCollapse("compo", usecompo, "Compositing", "Enable Compositing options", gui, 2.0)
lordcrc@384
  5175
                if usecompo.get() == "true":
lordcrc@384
  5176
                    if gui: gui.newline("", 2, level, None, [0.35,0.35,0.55])
lordcrc@384
  5177
                    usecompoviz = luxProp(mat, "compo_viz", "false")
lordcrc@384
  5178
                    luxCollapse("compo_viz", usecompoviz, "Visibility", "Enable Visibility Compositing options", gui, 2.0)
lordcrc@384
  5179
                    if usecompoviz.get() == "true":
lordcrc@384
  5180
                        if gui: gui.newline("View", 2, level, None, [0.35,0.35,0.55])
lordcrc@384
  5181
                        compovizmat = luxProp(mat, "compo_viz_mat", "true")
lordcrc@384
  5182
                        link += luxBool("compo_visible_material", compovizmat, "Material", "Enable View Visibility of Material", gui, 1.0)
lordcrc@384
  5183
                        compovizemi = luxProp(mat, "compo_viz_emi", "true")
lordcrc@384
  5184
                        link += luxBool("compo_visible_emission", compovizemi, "Emission", "Enable View Visibility of Emission", gui, 1.0)
lordcrc@384
  5185
                        
lordcrc@384
  5186
                        if gui: gui.newline("Indirect", 2, level, None, [0.35,0.35,0.55])
lordcrc@384
  5187
                        compovizmati = luxProp(mat, "compo_viz_mati", "true")
lordcrc@384
  5188
                        link += luxBool("compo_visible_indirect_material", compovizmati, "Material", "Enable InDirect Visibility of Material", gui, 1.0)
lordcrc@384
  5189
                        compovizemii = luxProp(mat, "compo_viz_emii", "true")
lordcrc@384
  5190
                        link += luxBool("compo_visible_indirect_emission", compovizemii, "Emission", "Enable InDirect Visibility of Emission", gui, 1.0)
lordcrc@384
  5191
                    
lordcrc@384
  5192
                    if gui: gui.newline("", 2, level, None, [0.4,0.4,0.6])
lordcrc@384
  5193
                    overridealpha = luxProp(mat, "compo_o_alpha", "false")
lordcrc@384
  5194
                    link += luxCollapse("compo_override_alpha", overridealpha, "Override Alpha", "Enable Manual control of alpha value", gui, 2.0)
lordcrc@384
  5195
                    if overridealpha.get() == "true":
lordcrc@384
  5196
                        if gui: gui.newline("Alpha", 2, level, None, [0.4,0.4,0.6])
lordcrc@384
  5197
                        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)
lordcrc@384
  5198
                    usecolorkey = luxProp(mat, "compo_usekey", "false")
lordcrc@384
  5199
                    if gui: gui.newline("", 2, level, None, [0.35,0.35,0.55])
lordcrc@384
  5200
                    link += luxCollapse("compo_use_key", usecolorkey, "Chroma Key", "Enable Chroma Object key", gui, 2.0)
lordcrc@384
  5201
                    if usecolorkey.get() == "true":
lordcrc@384
  5202
                        if gui: gui.newline("Key", 2, level, None, [0.35,0.35,0.55])
lordcrc@384
  5203
                        link += luxRGB("compo_key_color", luxProp(mat, "compo_key_color", "0.0 0.0 1.0"), 1.0, "key", "", gui, 2.0)
lordcrc@384
  5204
lordcrc@384
  5205
        # transformation options (common)
lordcrc@384
  5206
        if (level == 0) and mattype.get() not in ['portal', 'null']:
lordcrc@384
  5207
            if gui: gui.newline("", 2, level, None, [0.6,0.6,0.4])
lordcrc@384
  5208
            usetransformation = luxProp(mat, "transformation", "false")
lordcrc@384
  5209
            luxCollapse("usetransformation", usetransformation, "Texture Transformation", "Enable transformation option", gui, 2.0)
lordcrc@384
  5210
            if usetransformation.get() == "true":
lordcrc@384
  5211
                scale = luxProp(mat, "3dscale", 1.0)
lordcrc@384
  5212
                rotate = luxProp(mat, "3drotate", "0 0 0")
lordcrc@384
  5213
                translate = luxProp(mat, "3dtranslate", "0 0 0")
lordcrc@384
  5214
                if gui:
lordcrc@384
  5215
                    gui.newline("scale:", -2, level, icon_map3dparam)
lordcrc@384
  5216
                    luxVectorUniform("scale", scale, 0.001, 1000.0, "scale", "scale-vector", gui, 2.0)
lordcrc@384
  5217
                    gui.newline("rot:", -2, level, icon_map3dparam)
lordcrc@384
  5218
                    luxVector("rotate", rotate, -360.0, 360.0, "rotate", "rotate-vector", gui, 2.0)
lordcrc@384
  5219
                    gui.newline("move:", -2, level, icon_map3dparam)
lordcrc@384
  5220
                    luxVector("translate", translate, -1000.0, 1000.0, "move", "translate-vector", gui, 2.0)
lordcrc@384
  5221
                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"
lordcrc@384
  5222
lordcrc@384
  5223
        # Object options (common)
lordcrc@384
  5224
        if (level == 0) and (has_object_options == 1):
lordcrc@384
  5225
            if gui: gui.newline("Mesh:", 2, level, icon, [0.6,0.6,0.4])
lordcrc@384
  5226
            usesubdiv = luxProp(mat, "subdiv", "false")
lordcrc@384
  5227
            luxBool("usesubdiv", usesubdiv, "Subdivision", "Enable Loop Subdivision options", gui, 1.0)
lordcrc@384
  5228
            usedisp = luxProp(mat, "dispmap", "false")
lordcrc@384
  5229
            luxBool("usedisp", usedisp, "Displacement Map", "Enable Displacement mapping options", gui, 1.0)
lordcrc@384
  5230
            if usesubdiv.get() == "true" or usedisp.get() == "true":
lordcrc@384
  5231
                luxInt("sublevels", luxProp(mat, "sublevels", 2), 0, 12, "sublevels", "The number of levels of object subdivision", gui, 2.0)
lordcrc@384
  5232
                sharpbound = luxProp(mat, "sharpbound", "false")
lordcrc@384
  5233
                luxBool("sharpbound", sharpbound, "Sharpen Bounds", "Sharpen boundaries during subdivision", gui, 1.0)
lordcrc@384
  5234
                nsmooth = luxProp(mat, "nsmooth", "true")
lordcrc@384
  5235
                luxBool("nsmooth", nsmooth, "Smooth", "Smooth faces during subdivision", gui, 1.0)
lordcrc@384
  5236
            if usedisp.get() == "true":
lordcrc@384
  5237
                (str,ll) = c((str,link), luxDispFloatTexture("dispmap", keyname, 0.1, -10, 10.0, "dispmap", "Displacement Mapping amount", mat, gui, level+1))
lordcrc@384
  5238
                luxFloat("sdoffset",  luxProp(mat, "sdoffset", 0.0), 0.0, 1.0, "Offset", "Offset for displacement map", gui, 2.0)
lordcrc@384
  5239
                usesubdiv.set("true")
lordcrc@384
  5240
lordcrc@384
  5241
        if mattype.get() == "light":
lordcrc@384
  5242
            return (str, link)
lordcrc@384
  5243
lordcrc@384
  5244
        str += "MakeNamedMaterial \"%s\"%s\n"%(matname, link)
lordcrc@384
  5245
    return (str, " \"string %s\" [\"%s\"]"%(luxname, matname))
lordcrc@384
  5246
lordcrc@384
  5247
lordcrc@384
  5248
def luxMaterial(mat, gui=None):
lordcrc@384
  5249
    str = ""
lordcrc@384
  5250
    if mat:
lordcrc@384
  5251
        if luxProp(mat, "type", "").get()=="": # lux material not defined yet
lordcrc@384
  5252
            print("Blender material \"%s\" has no lux material definition, converting..."%(mat.getName()))
lordcrc@384
  5253
            try:
lordcrc@384
  5254
                convertMaterial(mat) # try converting the blender material to a lux material
lordcrc@384
  5255
            except: pass
lordcrc@384
  5256
        (str, link) = luxMaterialBlock("", "", "", mat, gui, 0)
lordcrc@384
  5257
        if luxProp(mat, "type", "matte").get() != "light":
lordcrc@384
  5258
            link = "NamedMaterial \"%s\""%(mat.getName())
lordcrc@384
  5259
        # export emission options (no gui)
lordcrc@384
  5260
        useemission = luxProp(mat, "emission", "false")
lordcrc@384
  5261
        if useemission.get() == "true":
lordcrc@384
  5262
            lightgroup = luxProp(mat, "light.lightgroup", "default")
lordcrc@384
  5263
            if luxProp(Scene.GetCurrent(), "nolg", "false").get()!="true":
lordcrc@384
  5264
                link += "\n\tLightGroup \"%s\"\n"%lightgroup.get()
lordcrc@384
  5265
            
lordcrc@384
  5266
            (estr, elink) = luxLight("", "", mat, None, 0)
lordcrc@384
  5267
            str += estr
lordcrc@384
  5268
            link += "\n\tAreaLightSource \"area\" "+elink 
lordcrc@384
  5269
            
lordcrc@384
  5270
        luxProp(mat, "link", "").set("".join(link))
lordcrc@384
  5271
        
lordcrc@384
  5272
    return str
lordcrc@384
  5273
        
lordcrc@384
  5274
lordcrc@384
  5275
def luxVolume(mat, gui=None):
lordcrc@384
  5276
    str = ""
lordcrc@384
  5277
    if mat:
lordcrc@384
  5278
        (str, link) = luxMaterialBlock("", "", "", mat, gui, 0)
lordcrc@384
  5279
        luxProp(mat, "link", "").set("".join(link))
lordcrc@384
  5280
    return str
lordcrc@384
  5281
lordcrc@384
  5282
runRenderAfterExport = None
lordcrc@384
  5283
def CBluxExport(default, run):
lordcrc@384
  5284
    global runRenderAfterExport
lordcrc@384
  5285
    runRenderAfterExport = run
lordcrc@384
  5286
    if default:
lordcrc@384
  5287
        datadir = luxProp(Scene.GetCurrent(), "datadir", "").get()
lordcrc@384
  5288
        if datadir=="": datadir = Blender.Get("datadir")
tom@407
  5289
        import os.path
tom@407
  5290
        if not os.path.exists(datadir):
tom@407
  5291
            Draw.PupMenu("ERROR: output directory does not exist!")
tom@407
  5292
            if LuxIsGUI:
tom@407
  5293
                Draw.Redraw()
tom@407
  5294
            return
lordcrc@384
  5295
        filename = datadir + os.sep + "default.lxs"
lordcrc@384
  5296
        save_still(filename)
lordcrc@384
  5297
    else:
lordcrc@384
  5298
        Window.FileSelector(save_still, "Export", sys.makename(Blender.Get("filename"), ".lxs"))
lordcrc@384
  5299
lordcrc@384
  5300
lordcrc@384
  5301
def CBluxAnimExport(default, run, fileselect=True):
lordcrc@384
  5302
    if default:
lordcrc@384
  5303
        datadir = luxProp(Scene.GetCurrent(), "datadir", "").get()
lordcrc@384
  5304
        if datadir=="": datadir = Blender.Get("datadir")
tom@407
  5305
        import os.path
tom@407
  5306
        if not os.path.exists(datadir):
tom@407
  5307
            Draw.PupMenu("ERROR: output directory does not exist!")
tom@407
  5308
            if LuxIsGUI:
tom@407
  5309
                Draw.Redraw()
tom@407
  5310
            return
lordcrc@384
  5311
        filename = datadir + os.sep + "default.lxs"
lordcrc@384
  5312
        save_anim(filename)
lordcrc@384
  5313
    else:
lordcrc@384
  5314
        if fileselect:
lordcrc@384
  5315
            Window.FileSelector(save_anim, "Export", sys.makename(Blender.Get("filename"), ".lxs"))
lordcrc@384
  5316
        else:
lordcrc@384
  5317
            datadir = luxProp(Scene.GetCurrent(), "datadir", "").get()
lordcrc@384
  5318
            if datadir=="": datadir = Blender.Get("datadir")
lordcrc@384
  5319
            filename = sys.makename(Blender.Get("filename") , ".lxs")
lordcrc@384
  5320
            save_anim(filename)
lordcrc@384
  5321
lordcrc@384
  5322
lordcrc@384
  5323
# convert a Blender material to lux material
lordcrc@384
  5324
def convertMaterial(mat):
lordcrc@384
  5325
    def dot(str):
lordcrc@384
  5326
        if str != "": return str+"."
lordcrc@384
  5327
        return str
lordcrc@384
  5328
    def ddot(str):
lordcrc@384
  5329
        if str != "": return str+":"
lordcrc@384
  5330
        return str
lordcrc@384
  5331
    def mapConstDict(value, constant_dict, lux_dict, default=None):
lordcrc@384
  5332
        for k,v in constant_dict.items():
lordcrc@384
  5333
            if (v == value) and (lux_dict.has_key(k)):
lordcrc@384
  5334
                return lux_dict[k]
lordcrc@384
  5335
        return default
lordcrc@384
  5336
lordcrc@384
  5337
    def convertMapping(name, tex):
lordcrc@384
  5338
        if tex.texco == Texture.TexCo["UV"]:
lordcrc@384
  5339
            luxProp(mat, dot(name)+"mapping","").set("uv")
lordcrc@384
  5340
            luxProp(mat, dot(name)+"uscale", 1.0).set(tex.size[0])
lordcrc@384
  5341
            luxProp(mat, dot(name)+"vscale", 1.0).set(-tex.size[1])
lordcrc@384
  5342
            luxProp(mat, dot(name)+"udelta", 0.0).set(tex.ofs[0]+0.5*(1.0-tex.size[0]))
lordcrc@384
  5343
            luxProp(mat, dot(name)+"vdelta", 0.0).set(-tex.ofs[1]-0.5*(1.0-tex.size[1]))
lordcrc@384
  5344
            if tex.mapping != Texture.Mappings["FLAT"]:
lordcrc@384
  5345
                print("Material Conversion Warning: for UV-texture-input only FLAT mapping is supported\n") 
lordcrc@384
  5346
        else:
lordcrc@384
  5347
            if tex.mapping == Texture.Mappings["FLAT"]:
jensverwiebe@409
  5348
                luxProp(mat, dot(name)+"mapping","").set("planar") # make planar-mapping convert correctly from blender(WYSIWYG)- jens
jensverwiebe@409
  5349
                luxProp(mat, dot(name)+"v1", "1.0 1.0 1.0").setVector((0.5*tex.size[0], 0.0, 0.0))
jensverwiebe@409
  5350
                luxProp(mat, dot(name)+"v2", "0.0 0.0 0.0").setVector((0.0, -0.5*tex.size[1], -0.0))
jensverwiebe@409
  5351
                luxProp(mat, dot(name)+"udelta", 0.0).set(tex.ofs[0]+0.5)
jensverwiebe@409
  5352
                luxProp(mat, dot(name)+"vdelta", 0.0).set(-tex.ofs[1]-0.5)
lordcrc@384
  5353
            elif tex.mapping == Texture.Mappings["TUBE"]:
lordcrc@384
  5354
                luxProp(mat, dot(name)+"mapping","").set("cylindrical")
lordcrc@384
  5355
            elif tex.mapping == Texture.Mappings["SPHERE"]:
lordcrc@384
  5356
                luxProp(mat, dot(name)+"mapping","").set("spherical")
lordcrc@384
  5357
            else: luxProp(mat, dot(name)+"mapping","").set("planar")
jensverwiebe@409
  5358
lordcrc@384
  5359
        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]))
lordcrc@384
  5360
        luxProp(mat, dot(name)+"3dtranslate", "0.0 0.0 0.0").setVector((-tex.ofs[0], -tex.ofs[1], -tex.ofs[2]))
lordcrc@384
  5361
lordcrc@384
  5362
    def convertColorband(colorband):
lordcrc@384
  5363
        # colorbands are not supported in lux - so lets extract a average low-side and high-side color
lordcrc@384
  5364
        cb = [colorband[0]] + colorband[:] + [colorband[-1]]
lordcrc@384
  5365
        cb[0][4], cb[-1][4] = 0.0, 1.0
lordcrc@384
  5366
        low, high = [0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0]
lordcrc@384
  5367
        for i in range(1, len(cb)):
lordcrc@384
  5368
            for c in range(4):
lordcrc@384
  5369
                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])
lordcrc@384
  5370
                high[c] += (cb[i-1][c]*cb[i-1][4] + cb[i][c]*cb[i][4]) * (cb[i][4]-cb[i-1][4])
lordcrc@384
  5371
        return low, high
lordcrc@384
  5372
lordcrc@384
  5373
    def createLuxTexture(name, tex):
lordcrc@384
  5374
        texture = tex.tex
lordcrc@384
  5375
        convertMapping(name, tex)
lordcrc@384
  5376
        if (texture.type == Texture.Types["IMAGE"]) and (texture.image) and (texture.image.filename!=""):
lordcrc@384
  5377
            luxProp(mat, dot(name)+"texture", "").set("imagemap")
lordcrc@384
  5378
            luxProp(mat, dot(name)+"filename", "").set(texture.image.filename)
lordcrc@384
  5379
            luxProp(mat, dot(name)+"wrap", "").set(mapConstDict(texture.extend, Texture.ExtendModes, {"REPEAT":"repeat", "EXTEND":"clamp", "CLIP":"black"}, ""))
lordcrc@384
  5380
        else:
lordcrc@384
  5381
            if tex.texco != Texture.TexCo["GLOB"]:
lordcrc@384
  5382
                print("Material Conversion Warning: procedural textures supports global mapping only\n")
lordcrc@384
  5383
            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"}
lordcrc@384
  5384
            luxProp(mat, dot(name)+"bright", 1.0).set(texture.brightness)
lordcrc@384
  5385
            luxProp(mat, dot(name)+"contrast", 1.0).set(texture.contrast)
lordcrc@384
  5386
            if texture.type == Texture.Types["CLOUDS"]:
lordcrc@384
  5387
                luxProp(mat, dot(name)+"texture", "").set("blender_clouds")
lordcrc@384
  5388
                luxProp(mat, dot(name)+"mtype", "").set(mapConstDict(texture.stype, Texture.STypes, {"CLD_DEFAULT":"default", "CLD_COLOR":"color"}, ""))
lordcrc@384
  5389
                luxProp(mat, dot(name)+"noisetype", "").set({"soft":"soft_noise", "hard":"hard_noise"}[texture.noiseType])
lordcrc@384
  5390
                luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
lordcrc@384
  5391
                luxProp(mat, dot(name)+"noisedepth", 2).set(texture.noiseDepth)
lordcrc@384
  5392
                luxProp(mat, dot(name)+"noisebasis", "").set(mapConstDict(texture.noiseBasis, Texture.Noise, noiseDict, ""))
lordcrc@384
  5393
            elif texture.type == Texture.Types["WOOD"]:
lordcrc@384
  5394
                luxProp(mat, dot(name)+"texture", "").set("blender_wood")
lordcrc@384
  5395
                luxProp(mat, dot(name)+"mtype", "").set(mapConstDict(texture.stype, Texture.STypes, {"WOD_BANDS":"bands", "WOD_RINGS":"rings", "WOD_BANDNOISE":"bandnoise", "WOD_RINGNOISE":"ringnoise"}, ""))
lordcrc@384
  5396
                luxProp(mat, dot(name)+"noisebasis2", "").set(mapConstDict(texture.noiseBasis2, Texture.Noise, {"SINE":"sin", "SAW":"saw", "TRI":"tri"}, ""))
lordcrc@384
  5397
                luxProp(mat, dot(name)+"noisebasis", "").set(mapConstDict(texture.noiseBasis, Texture.Noise, noiseDict, ""))
lordcrc@384
  5398
                luxProp(mat, dot(name)+"noisetype", "").set({"soft":"soft_noise", "hard":"hard_noise"}[texture.noiseType])
lordcrc@384
  5399
                luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
lordcrc@384
  5400
                luxProp(mat, dot(name)+"turbulance", 0.25).set(texture.turbulence)
lordcrc@384
  5401
            elif texture.type == Texture.Types["MUSGRAVE"]:
lordcrc@384
  5402
                luxProp(mat, dot(name)+"texture", "").set("blender_musgrave")
lordcrc@384
  5403
                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"}, ""))
lordcrc@384
  5404
                luxProp(mat, dot(name)+"noisebasis", "").set(mapConstDict(texture.noiseBasis, Texture.Noise, noiseDict, ""))
lordcrc@384
  5405
                luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
lordcrc@384
  5406
                # 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)
lordcrc@384
  5407
                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
lordcrc@384
  5408
                else: luxProp(mat, dot(name)+"h", 1.0).set(0.5) # use a default value
lordcrc@384
  5409
                # bug in blender python API: values "offset" and "gain" are missing in Python-API (reported to Ideasman42 - will be fixed after Blender 2.47)
lordcrc@384
  5410
                try:
lordcrc@384
  5411
                    luxProp(mat, dot(name)+"offset", 1.0).set(texture.offset)
lordcrc@384
  5412
                    luxProp(mat, dot(name)+"gain", 1.0).set(texture.gain)
lordcrc@384
  5413
                except AttributeError: pass
lordcrc@384
  5414
                luxProp(mat, dot(name)+"lacu", 2.0).set(texture.lacunarity)
lordcrc@384
  5415
                luxProp(mat, dot(name)+"octs", 2.0).set(texture.octs)
lordcrc@384
  5416
                luxProp(mat, dot(name)+"outscale", 1.0).set(texture.iScale)
lordcrc@384
  5417
            elif texture.type == Texture.Types["MARBLE"]:
lordcrc@384
  5418
                luxProp(mat, dot(name)+"texture", "").set("blender_marble")
lordcrc@384
  5419
                luxProp(mat, dot(name)+"mtype", "").set(mapConstDict(texture.stype, Texture.STypes, {"MBL_SOFT":"soft", "MBL_SHARP":"sharp", "MBL_SHARPER":"sharper"}, ""))
lordcrc@384
  5420
                luxProp(mat, dot(name)+"noisetype", "").set({"soft":"soft_noise", "hard":"hard_noise"}[texture.noiseType])
lordcrc@384
  5421
                luxProp(mat, dot(name)+"turbulance", 0.25).set(texture.turbulence)
lordcrc@384
  5422
                luxProp(mat, dot(name)+"noisedepth", 2).set(texture.noiseDepth)
lordcrc@384
  5423
                luxProp(mat, dot(name)+"noisebasis", "").set(mapConstDict(texture.noiseBasis, Texture.Noise, noiseDict, ""))
lordcrc@384
  5424
                luxProp(mat, dot(name)+"noisebasis2", "").set(mapConstDict(texture.noiseBasis2, Texture.Noise, {"SINE":"sin", "SAW":"saw", "TRI":"tri"}, ""))
lordcrc@384
  5425
                luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
lordcrc@384
  5426
            elif texture.type == Texture.Types["VORONOI"]:
lordcrc@384
  5427
                luxProp(mat, dot(name)+"texture", "").set("blender_voronoi")
lordcrc@384
  5428
                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])
lordcrc@384
  5429
                luxProp(mat, dot(name)+"outscale", 1.0).set(texture.iScale)
lordcrc@384
  5430
                luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
lordcrc@384
  5431
                luxProp(mat, dot(name)+"minkosky_exp", 2.5).set(texture.exp)
lordcrc@384
  5432
                luxProp(mat, dot(name)+"w1", 1.0).set(texture.weight1)
lordcrc@384
  5433
                luxProp(mat, dot(name)+"w2", 0.0).set(texture.weight2)
lordcrc@384
  5434
                luxProp(mat, dot(name)+"w3", 0.0).set(texture.weight3)
lordcrc@384
  5435
                luxProp(mat, dot(name)+"w4", 0.0).set(texture.weight4)
lordcrc@384
  5436
            elif texture.type == Texture.Types["NOISE"]:
lordcrc@384
  5437
                luxProp(mat, dot(name)+"texture", "").set("blender_noise")
lordcrc@384
  5438
            elif texture.type == Texture.Types["DISTNOISE"]:
lordcrc@384
  5439
                luxProp(mat, dot(name)+"texture", "").set("blender_distortednoise")
lordcrc@384
  5440
                luxProp(mat, dot(name)+"distamount", 1.0).set(texture.distAmnt)
lordcrc@384
  5441
                luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
lordcrc@384
  5442
                luxProp(mat, dot(name)+"noisebasis", "").set(mapConstDict(texture.noiseBasis, Texture.Noise, noiseDict, ""))
lordcrc@384
  5443
                luxProp(mat, dot(name)+"noisebasis2", "").set(mapConstDict(texture.noiseBasis2, Texture.Noise, noiseDict, ""))
lordcrc@384
  5444
            elif texture.type == Texture.Types["MAGIC"]:
lordcrc@384
  5445
                luxProp(mat, dot(name)+"texture", "").set("blender_magic")
lordcrc@384
  5446
                luxProp(mat, dot(name)+"turbulance", 0.25).set(texture.turbulence)
lordcrc@384
  5447
                luxProp(mat, dot(name)+"noisedepth", 2).set(texture.noiseDepth)
lordcrc@384
  5448
            elif texture.type == Texture.Types["STUCCI"]:
lordcrc@384
  5449
                luxProp(mat, dot(name)+"texture", "").set("blender_stucci")
lordcrc@384
  5450
                luxProp(mat, dot(name)+"mtype", "").set(mapConstDict(texture.stype, Texture.STypes, {"STC_PLASTIC":"Plastic", "MSTC_WALLIN":"Wall In", "STC_WALLOUT":"Wall Out"}, ""))
lordcrc@384
  5451
                luxProp(mat, dot(name)+"noisetype", "").set({"soft":"soft_noise", "hard":"hard_noise"}[texture.noiseType])
lordcrc@384
  5452
                luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
lordcrc@384
  5453
                luxProp(mat, dot(name)+"turbulance", 0.25).set(texture.turbulence)
lordcrc@384
  5454
                luxProp(mat, dot(name)+"noisebasis", "").set(mapConstDict(texture.noiseBasis, Texture.Noise, noiseDict, ""))
lordcrc@384
  5455
            elif texture.type == Texture.Types["BLEND"]:
lordcrc@384
  5456
                luxProp(mat, dot(name)+"texture", "").set("blender_blend")
lordcrc@384
  5457
                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"}, ""))
lordcrc@384
  5458
                luxProp(mat, dot(name)+"flipXY", "false").set({0:"false", 1:"true"}[texture.rot90])
lordcrc@384
  5459
            else:
lordcrc@384
  5460
                print("Material Conversion Warning: SORRY, this procedural texture isn\'t implemented in conversion\n")
lordcrc@384
  5461
lordcrc@384
  5462
    def convertTextures(basename, texs, type="float", channel="col", val=1.0):
lordcrc@384
  5463
        tex = texs.pop()
lordcrc@384
  5464
        texture = tex.tex
lordcrc@384
  5465
        isImagemap = (texture.type == Texture.Types["IMAGE"]) and (texture.image) and (texture.image.filename!="")
lordcrc@384
  5466
        if channel == "col":
lordcrc@384
  5467
            if texture.flags & Texture.Flags["COLORBAND"] > 0:
lordcrc@384
  5468
                cbLow, cbHigh = convertColorband(texture.colorband)
lordcrc@384
  5469
                val1, alpha1, val2, alpha2 = (cbLow[0],cbLow[1],cbLow[2]), cbLow[3]*tex.colfac, (cbHigh[0], cbHigh[1], cbHigh[2]), cbHigh[3]*tex.colfac
lordcrc@384
  5470
                if tex.noRGB:
lordcrc@384
  5471
                    lum1, lum2 = (val1[0]+val1[1]+val1[2])/3.0, (val2[0]+val2[1]+val2[2])/3.0
lordcrc@384
  5472
                    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)
lordcrc@384
  5473
            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
lordcrc@384
  5474
            else: val1, alpha1, val2, alpha2 = tex.col, 0.0, tex.col, tex.colfac
lordcrc@384
  5475
        elif channel == "nor": val1, alpha1, val2, alpha2 = tex.norfac * 0.01, 0.0, tex.norfac * 0.01, 1.0
lordcrc@384
  5476
        else: val1, alpha1, val2, alpha2 = 1.0, 0.0, 1.0, tex.varfac
lordcrc@384
  5477
        if (tex.neg)^((channel=="nor") and (tex.mtNor<0)): val1, alpha1, val2, alpha2 = val2, alpha2, val1, alpha1
lordcrc@384
  5478
        luxProp(mat, dot(basename)+"textured", "").set("true")
lordcrc@384
  5479
lordcrc@384
  5480
        name = basename
lordcrc@384
  5481
        if (alpha1 < 1.0) or (alpha2 < 1.0): # texture with transparency
lordcrc@384
  5482
            luxProp(mat, dot(basename)+"texture", "").set("mix")
lordcrc@384
  5483
            if alpha1 == alpha2: # constant alpha
lordcrc@384
  5484
                luxProp(mat, ddot(basename)+"amount.value", 1.0).set(alpha1)
lordcrc@384
  5485
            else:
lordcrc@384
  5486
                createLuxTexture(ddot(basename)+"amount", tex)
lordcrc@384
  5487
                luxProp(mat, ddot(basename)+"amount:tex1.value", 1.0).set(alpha1)
lordcrc@384
  5488
                luxProp(mat, ddot(basename)+"amount:tex2.value", 1.0).set(alpha2)
lordcrc@384
  5489
            # transparent to next texture
lordcrc@384
  5490
            name = ddot(basename)+"tex1"
lordcrc@384
  5491
            if len(texs) > 0:
lordcrc@384
  5492
                convertTextures(ddot(basename)+"tex1", texs, type, channel, val)
lordcrc@384
  5493
            else:
lordcrc@384
  5494
                if type=="float": luxProp(mat, ddot(basename)+"tex1.value", 1.0).set(val)
lordcrc@384
  5495
                else: luxProp(mat, ddot(basename)+"tex1.value", "1.0 1.0 1.0").setRGB((val[0], val[1], val[2]))
lordcrc@384
  5496
            name = ddot(basename)+"tex2"
lordcrc@384
  5497
        if val1 == val2: # texture with different colors / value
lordcrc@384
  5498
            if type == "col": luxProp(mat, dot(name)+"value", "1.0 1.0 1.0").setRGB(val1)
lordcrc@384
  5499
            else: luxProp(mat, dot(name)+"value", 1.0).set(val1)
lordcrc@384
  5500
        else:
lordcrc@384
  5501
            createLuxTexture(name, tex)
lordcrc@384
  5502
            if type == "col": luxProp(mat, ddot(name)+"tex1.value", "1.0 1.0 1.0").setRGB(val1)
lordcrc@384
  5503
            else: luxProp(mat, ddot(name)+"tex1.value", 1.0).set(val1)
lordcrc@384
  5504
            if type == "col": luxProp(mat, ddot(name)+"tex2.value", "1.0 1.0 1.0").setRGB(val2)
lordcrc@384
  5505
            else: luxProp(mat, ddot(name)+"tex2.value", 1.0).set(val2)
lordcrc@384
  5506
lordcrc@384
  5507
lordcrc@384
  5508
    def convertDiffuseTexture(name):
lordcrc@384
  5509
        texs = []
lordcrc@384
  5510
        for tex in mat.getTextures():
lordcrc@384
  5511
            if tex and (tex.mapto & Texture.MapTo["COL"] > 0) and (tex.tex) and (tex.tex.type != Texture.Types["NONE"]): texs.append(tex)
lordcrc@384
  5512
        if len(texs) > 0:
lordcrc@384
  5513
            luxProp(mat, name, "").setRGB((mat.ref, mat.ref, mat.ref))
lordcrc@384
  5514
            convertTextures(name, texs, "col", "col", (mat.R, mat.G, mat.B))
lordcrc@384
  5515
    def convertSpecularTexture(name):
lordcrc@384
  5516
        texs = []
lordcrc@384
  5517
        for tex in mat.getTextures():
lordcrc@384
  5518
            if tex and (tex.mapto & Texture.MapTo["CSP"] > 0) and (tex.tex) and (tex.tex.type != Texture.Types["NONE"]): texs.append(tex)
lordcrc@384
  5519
        if len(texs) > 0:
lordcrc@384
  5520
            luxProp(mat, name, "").setRGB((mat.ref*mat.spec, mat.ref*mat.spec, mat.ref*mat.spec))
lordcrc@384
  5521
            convertTextures(name, texs, "col", "col", (mat.specR, mat.specG, mat.specB))
lordcrc@384
  5522
    def convertMirrorTexture(name):
lordcrc@384
  5523
        texs = []
lordcrc@384
  5524
        for tex in mat.getTextures():
lordcrc@384
  5525
            if tex and (tex.mapto & Texture.MapTo["CMIR"] > 0) and (tex.tex) and (tex.tex.type != Texture.Types["NONE"]): texs.append(tex)
lordcrc@384
  5526
        if len(texs) > 0:
lordcrc@384
  5527
            luxProp(mat, name, "").setRGB((mat.ref, mat.ref, mat.ref))
lordcrc@384
  5528
            convertTextures(name, texs, "col", "col", (mat.mirR, mat.mirG, mat.mirB))
lordcrc@384
  5529
    def convertBumpTexture(basename):
lordcrc@384
  5530
        texs = []
lordcrc@384
  5531
        for tex in mat.getTextures():
lordcrc@384
  5532
            if tex and (tex.mapto & Texture.MapTo["NOR"] > 0) and (tex.tex) and (tex.tex.type != Texture.Types["NONE"]): texs.append(tex)
lordcrc@384
  5533
        if len(texs) > 0:
lordcrc@384
  5534
            name = basename+":bumpmap"
lordcrc@384
  5535
            luxProp(mat, basename+".usebump", "").set("true")
lordcrc@384
  5536
            luxProp(mat, dot(name)+"textured", "").set("true")
lordcrc@384
  5537
            luxProp(mat, name, "").set(1.0)
lordcrc@384
  5538
            convertTextures(name, texs, "float", "nor", 0.0)
lordcrc@384
  5539
lordcrc@384
  5540
    def makeMatte(name):
lordcrc@384
  5541
        luxProp(mat, dot(name)+"type", "").set("matte")
lordcrc@384
  5542
        luxProp(mat, name+":Kd", "").setRGB((mat.R*mat.ref, mat.G*mat.ref, mat.B*mat.ref))
lordcrc@384
  5543
        convertDiffuseTexture(name+":Kd")
lordcrc@384
  5544
        convertBumpTexture(name)
lordcrc@384
  5545
    def makeGlossy(name, roughness):
lordcrc@384
  5546
        luxProp(mat, dot(name)+"type", "").set("glossy")
lordcrc@384
  5547
        luxProp(mat, name+":Kd", "").setRGB((mat.R*mat.ref, mat.G*mat.ref, mat.B*mat.ref))
lordcrc@384
  5548
        luxProp(mat, name+":Ks", "").setRGB((mat.specR*mat.spec*0.5, mat.specG*mat.spec*0.5, mat.specB*mat.spec*0.5))
lordcrc@384
  5549
        luxProp(mat, name+":uroughness", 0.0).set(roughness)
lordcrc@384
  5550
        luxProp(mat, name+":vroughness", 0.0).set(roughness)
lordcrc@384
  5551
        convertDiffuseTexture(name+":Kd")
lordcrc@384
  5552
        convertSpecularTexture(name+":Ks")
lordcrc@384
  5553
        convertBumpTexture(name)
lordcrc@384
  5554
    def makeMirror(name):
lordcrc@384
  5555
        luxProp(mat, dot(name)+"type", "").set("mirror")
lordcrc@384
  5556
        luxProp(mat, name+":Kr", "").setRGB((mat.mirR, mat.mirG, mat.mirB))
lordcrc@384
  5557
        convertMirrorTexture(name+":Kr")
lordcrc@384
  5558
        convertBumpTexture(name)
lordcrc@384
  5559
    def makeGlass(name):
lordcrc@384
  5560
        luxProp(mat, dot(name)+"type", "").set("glass")
lordcrc@384
  5561
        luxProp(mat, name+":Kr", "").setRGB((0.0, 0.0, 0.0))
lordcrc@384
  5562
        luxProp(mat, name+":Kt", "").setRGB((mat.R, mat.G, mat.B))
lordcrc@384
  5563
        luxProp(mat, name+":index.iorusepreset", "").set("false")
lordcrc@384
  5564
        luxProp(mat, name+":index", 0.0).set(mat.getIOR())
lordcrc@384
  5565
        convertMirrorTexture(name+":Kr")
lordcrc@384
  5566
        convertDiffuseTexture(name+":Kt")
lordcrc@384
  5567
        convertBumpTexture(name)
lordcrc@384
  5568
    def makeRoughglass(name, roughness):
lordcrc@384
  5569
        luxProp(mat, dot(name)+"type", "").set("roughglass")
lordcrc@384
  5570
        luxProp(mat, name+":Kr", "").setRGB((0.0, 0.0, 0.0))
lordcrc@384
  5571
        luxProp(mat, name+":Kt", "").setRGB((mat.R, mat.G, mat.B))
lordcrc@384
  5572
        luxProp(mat, name+":index.iorusepreset", "").set("false")
lordcrc@384
  5573
        luxProp(mat, name+":index", 0.0).set(mat.getIOR())
lordcrc@384
  5574
        luxProp(mat, name+":uroughness", 0.0).set(roughness)
lordcrc@384
  5575
        luxProp(mat, name+":vroughness", 0.0).set(roughness)
lordcrc@384
  5576
        convertMirrorTexture(name+":Kr")
lordcrc@384
  5577
        convertDiffuseTexture(name+":Kt")
lordcrc@384
  5578
        convertBumpTexture(name)
lordcrc@384
  5579
    print("convert Blender material \"%s\" to lux material"%(mat.name))
lordcrc@384
  5580
    mat.properties['luxblend'] = {}
lordcrc@384
  5581
    if mat.emit > 0.0001:
lordcrc@384
  5582
        luxProp(mat, "type", "").set("light")
lordcrc@384
  5583
        luxProp(mat, "light.l", "").setRGB((mat.R, mat.G, mat.B))
lordcrc@384
  5584
        luxProp(mat, "light.gain", 1.0).set(mat.emit)
lordcrc@384
  5585
        return
lordcrc@384
  5586
    alpha = mat.alpha
lordcrc@384
  5587
    if not(mat.mode & Material.Modes.RAYTRANSP): alpha = 1.0
lordcrc@384
  5588
    alpha0name, alpha1name = "", ""
lordcrc@384
  5589
    if (alpha > 0.0) and (alpha < 1.0):
lordcrc@384
  5590
        luxProp(mat, "type", "").set("mix")
lordcrc@384
  5591
        luxProp(mat, ":amount", 0.0).set(alpha)
lordcrc@384
  5592
        alpha0name, alpha1name = "mat2", "mat1"
lordcrc@384
  5593
    if alpha > 0.0:
lordcrc@384
  5594
        mirror = mat.rayMirr
lordcrc@384
  5595
        if not(mat.mode & Material.Modes.RAYMIRROR): mirror = 0.0
lordcrc@384
  5596
        mirror0name, mirror1name = alpha1name, alpha1name
lordcrc@384
  5597
        if (mirror > 0.0) and (mirror < 1.0):
lordcrc@384
  5598
            luxProp(mat, dot(alpha1name)+"type", "").set("mix")
lordcrc@384
  5599
            luxProp(mat, alpha1name+":amount", 0.0).set(1.0 - mirror)
lordcrc@384
  5600
            mirror0name, mirror1name = ddot(alpha1name)+"mat1", ddot(alpha1name)+"mat2"
lordcrc@384
  5601
        if mirror > 0.0:
lordcrc@384
  5602
            if mat.glossMir < 1.0: makeGlossy(mirror1name, 1.0-mat.glossMir**2)
lordcrc@384
  5603
            else: makeMirror(mirror1name)
lordcrc@384
  5604
        if mirror < 1.0:
lordcrc@384
  5605
            if mat.spec > 0.0: makeGlossy(mirror0name, 1.0/mat.hard)
lordcrc@384
  5606
            else: makeMatte(mirror0name)
lordcrc@384
  5607
    if alpha < 1.0:
lordcrc@384
  5608
        if mat.glossTra < 1.0: makeRoughnessGlass(alpha0name, 1.0-mat.glossTra**2)
lordcrc@384
  5609
        else: makeGlass(alpha0name)
lordcrc@384
  5610
lordcrc@384
  5611
def convertAllMaterials():
lordcrc@384
  5612
    for mat in Material.Get(): convertMaterial(mat)
lordcrc@384
  5613
lordcrc@384
  5614
lordcrc@384
  5615
lordcrc@384
  5616
lordcrc@384
  5617
### Connect LRMDB ###
lordcrc@384
  5618
ConnectLrmdb = False
lordcrc@384
  5619
try:
lordcrc@384
  5620
    import socket  # try import of socket library
lordcrc@384
  5621
    ConnectLrmdb = True
lordcrc@384
  5622
    def downloadLRMDB(mat, id):
lordcrc@384
  5623
        if id.isalnum():
lordcrc@384
  5624
            DrawProgressBar(0.0,'Getting Material #'+id)
lordcrc@384
  5625
            try:
lordcrc@384
  5626
                HOST = 'www.luxrender.net'
lordcrc@384
  5627
                GET = '/lrmdb/en/material/download/'+id
lordcrc@384
  5628
                PORT = 80
lordcrc@384
  5629
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
lordcrc@384
  5630
                sock.connect((HOST, PORT))
lordcrc@384
  5631
                sock.send("GET %s HTTP/1.0\r\nHost: %s\r\n\r\n" % (GET, HOST))
lordcrc@384
  5632
                data = sock.recv(1024)
lordcrc@384
  5633
                str = ""
lordcrc@384
  5634
                while len(data):
lordcrc@384
  5635
                    str += data
lordcrc@384
  5636
                    data = sock.recv(1024)
lordcrc@384
  5637
                sock.close()
lordcrc@384
  5638
                if str.split("\n", 1)[0].find("200") < 0:
lordcrc@384
  5639
                    print("ERROR: server error: %s"%(str.split("\n",1)[0]))
lordcrc@384
  5640
                    return None
lordcrc@384
  5641
                str = (str.split("\r\n\r\n")[1]).strip()
lordcrc@384
  5642
                if (str[0]=="{") and (str[-1]=="}"):
lordcrc@384
  5643
                    return str2MatTex(str)
lordcrc@384
  5644
                print("ERROR: downloaded data is not a material or texture")
lordcrc@384
  5645
            except:
lordcrc@384
  5646
                print("ERROR: download failed")
lordcrc@384
  5647
                
lordcrc@384
  5648
            DrawProgressBar(1.0,'')
lordcrc@384
  5649
        else:
lordcrc@384
  5650
            print("ERROR: material id is not valid")
lordcrc@384
  5651
        return None
lordcrc@384
  5652
    
lordcrc@384
  5653
        
lordcrc@384
  5654
    #===========================================================================
lordcrc@384
  5655
    # COOKIETRANSPORT
lordcrc@384
  5656
    #===========================================================================
lordcrc@384
  5657
    
lordcrc@384
  5658
    #--------------------------------------------------------------------------- 
lordcrc@384
  5659
    # IMPORTS
lordcrc@384
  5660
    import cookielib, urllib2, xmlrpclib
lordcrc@384
  5661
    
lordcrc@384
  5662
    #---------------------------------------------------------------------------
lordcrc@384
  5663
    # pilfered from
lordcrc@384
  5664
    # https://fedorahosted.org/python-bugzilla/browser/bugzilla.py?rev=e6f699f06e92b1e49b1b8d2c8fbe89d9425a4a9a
lordcrc@384
  5665
    class CookieTransport(xmlrpclib.Transport):
lordcrc@384
  5666
        '''
lordcrc@384
  5667
        A subclass of xmlrpclib.Transport that supports cookies.
lordcrc@384
  5668
        '''
lordcrc@384
  5669
        
lordcrc@384
  5670
        cookiejar = None
lordcrc@384
  5671
        scheme = 'http'
lordcrc@384
  5672
        verbose = None
lordcrc@384
  5673
    
lordcrc@384
  5674
        # Cribbed from xmlrpclib.Transport.send_user_agent 
lordcrc@384
  5675
        def send_cookies(self, connection, cookie_request):
lordcrc@384
  5676
            '''
lordcrc@384
  5677
            Send all the cookie data that we have received
lordcrc@384
  5678
            '''
lordcrc@384
  5679
            
lordcrc@384
  5680
            if self.cookiejar is None:
lordcrc@384
  5681
                self.cookiejar = cookielib.CookieJar()
lordcrc@384
  5682
            elif self.cookiejar:
lordcrc@384
  5683
                # Let the cookiejar figure out what cookies are appropriate
lordcrc@384
  5684
                self.cookiejar.add_cookie_header(cookie_request)
lordcrc@384
  5685
                # Pull the cookie headers out of the request object...
lordcrc@384
  5686
                cookielist = list()
lordcrc@384
  5687
                for header, value in cookie_request.header_items():
lordcrc@384
  5688
                    if header.startswith('Cookie'):
lordcrc@384
  5689
                        cookielist.append([header, value])
lordcrc@384
  5690
                # ...and put them over the connection
lordcrc@384
  5691
                for header, value in cookielist:
lordcrc@384
  5692
                    connection.putheader(header, value)
lordcrc@384
  5693
    
lordcrc@384
  5694
        # This is the same request() method from xmlrpclib.Transport,
lordcrc@384
  5695
        # with a couple additions noted below
lordcrc@384
  5696
        def request(self, host, handler, request_body, verbose=0):
lordcrc@384
  5697
            '''
lordcrc@384
  5698
            Handle the request
lordcrc@384
  5699
            '''
lordcrc@384
  5700
            
lordcrc@384
  5701
            host_connection = self.make_connection(host)
lordcrc@384
  5702
            if verbose:
lordcrc@384
  5703
                host_connection.set_debuglevel(1)
lordcrc@384
  5704
    
lordcrc@384
  5705
            # ADDED: construct the URL and Request object for proper cookie handling
lordcrc@384
  5706
            request_url = "%s://%s/" % (self.scheme, host)
lordcrc@384
  5707
            cookie_request  = urllib2.Request(request_url) 
lordcrc@384
  5708
    
lordcrc@384
  5709
            self.send_request(host_connection, handler, request_body)
lordcrc@384
  5710
            self.send_host(host_connection, host) 
lordcrc@384
  5711
            
lordcrc@384
  5712
            # ADDED. creates cookiejar if None.
lordcrc@384
  5713
            self.send_cookies(host_connection, cookie_request)
lordcrc@384
  5714
            self.send_user_agent(host_connection)
lordcrc@384
  5715
            self.send_content(host_connection, request_body)
lordcrc@384
  5716
    
lordcrc@384
  5717
            errcode, errmsg, headers = host_connection.getreply()
lordcrc@384
  5718
    
lordcrc@384
  5719
            # ADDED: parse headers and get cookies here
lordcrc@384
  5720
            class CookieResponse:
lordcrc@384
  5721
                '''
lordcrc@384
  5722
                fake a response object that we can fill with the headers above
lordcrc@384
  5723
                '''
lordcrc@384
  5724
                
lordcrc@384
  5725
                def __init__(self, headers):
lordcrc@384
  5726
                    self.headers = headers
lordcrc@384
  5727
                    
lordcrc@384
  5728
                def info(self):
lordcrc@384
  5729
                    return self.headers
lordcrc@384
  5730
                
lordcrc@384
  5731
            cookie_response = CookieResponse(headers)
lordcrc@384
  5732
            
lordcrc@384
  5733
            # Okay, extract the cookies from the headers
lordcrc@384
  5734
            self.cookiejar.extract_cookies(cookie_response, cookie_request)
lordcrc@384
  5735
            
lordcrc@384
  5736
            # And write back any changes
lordcrc@384
  5737
            # DH THIS DOESN'T WORK
lordcrc@384
  5738
            # self.cookiejar.save(self.cookiejar.filename)
lordcrc@384
  5739
    
lordcrc@384
  5740
            if errcode != 200:
lordcrc@384
  5741
                raise xmlrpclib.ProtocolError(
lordcrc@384
  5742
                    host + handler,
lordcrc@384
  5743
                    errcode, errmsg,
lordcrc@384
  5744
                    headers
lordcrc@384
  5745
                )
lordcrc@384
  5746
    
lordcrc@384
  5747
            self.verbose = verbose
lordcrc@384
  5748
    
lordcrc@384
  5749
            try:
lordcrc@384
  5750
                sock = host_connection._conn.sock
lordcrc@384
  5751
            except AttributeError:
lordcrc@384
  5752
                sock = None
lordcrc@384
  5753
    
lordcrc@384
  5754
            return self._parse_response(host_connection.getfile(), sock)
lordcrc@384
  5755
    
lordcrc@384
  5756
lordcrc@384
  5757
    #===========================================================================
lordcrc@384
  5758
    # LRMDB Integration
lordcrc@384
  5759
    #===========================================================================
lordcrc@384
  5760
    class lrmdb:
lordcrc@384
  5761
        host              = 'http://www.luxrender.net/lrmdb/ixr'
lordcrc@384
  5762
        
lordcrc@384
  5763
        username          = ""
lordcrc@384
  5764
        password          = ""
lordcrc@384
  5765
        logged_in         = False
lordcrc@384
  5766
        
lordcrc@384
  5767
        SERVER            = None
lordcrc@384
  5768
        
lordcrc@384
  5769
        last_error_str    = None
lordcrc@384
  5770
        
lordcrc@384
  5771
        def last_error(self):
lordcrc@384
  5772
            return self.last_error_str #'LRMDB Connector: %s' %
lordcrc@384
  5773
        
lordcrc@384
  5774
        def login(self):
lordcrc@384
  5775
            try:
lordcrc@384
  5776
                result = self.SERVER.user.login(
lordcrc@384
  5777
                    self.username,
lordcrc@384
  5778
                    self.password
lordcrc@384
  5779
                )
lordcrc@384
  5780
                if not result:
lordcrc@384
  5781
                    raise
lordcrc@384
  5782
                else:
lordcrc@384
  5783
                    self.logged_in = True
lordcrc@384
  5784
                    return True
lordcrc@384
  5785
            except:
lordcrc@384
  5786
                self.last_error_str = 'Login Failed'
lordcrc@384
  5787
                self.logged_in = False
lordcrc@384
  5788
                return False
lordcrc@384
  5789
            
lordcrc@384
  5790
        def submit_object(self, mat, basekey, tex):
lordcrc@384
  5791
            if not self.check_creds(): return False
lordcrc@384
  5792
            
lordcrc@384
  5793
            try:
lordcrc@384
  5794
                result = 'Unknown Error'
lordcrc@384
  5795
                
lordcrc@384
  5796
                if tex:
lordcrc@384
  5797
                    name = Draw.PupStrInput('Name: ', '', 32)
lordcrc@384
  5798
                else:
lordcrc@384
  5799
                    name = mat.name
lordcrc@384
  5800
                
lordcrc@384
  5801
                result = self.SERVER.object.submit(
lordcrc@384
  5802
                    name,
lordcrc@384
  5803
                    MatTex2dict( getMatTex(mat, basekey, tex), tex )
lordcrc@384
  5804
                )
lordcrc@384
  5805
                if result is not True:
lordcrc@384
  5806
                    raise
lordcrc@384
  5807
                else:
lordcrc@384
  5808
                    return True
lordcrc@384
  5809
            except:
lordcrc@384
  5810
                self.last_error_str = 'Submit failed: %s' % result
lordcrc@384
  5811
                return False
lordcrc@384
  5812
        
lordcrc@384
  5813
        def check_creds(self):
lordcrc@384
  5814
            if self.SERVER is None:
lordcrc@384
  5815
                try:
lordcrc@384
  5816
                    self.SERVER = xmlrpclib.ServerProxy(self.host, transport=CookieTransport())
lordcrc@384
  5817
                except:
lordcrc@384
  5818
                    self.last_error_str = 'ServerProxy init failed'
lordcrc@384
  5819
                    return False
lordcrc@384
  5820
            
lordcrc@384
  5821
            
lordcrc@384
  5822
            if not self.logged_in:
lordcrc@384
  5823
                #if self.username is "":
lordcrc@384
  5824
                self.request_username()
lordcrc@384
  5825
                
lordcrc@384
  5826
                #if self.password is "":
lordcrc@384
  5827
                self.request_password()
lordcrc@384
  5828
                    
lordcrc@384
  5829
                return self.login()
lordcrc@384
  5830
            else:
lordcrc@384
  5831
                return True
lordcrc@384
  5832
                
lordcrc@384
  5833
        def request_username(self):
lordcrc@384
  5834
            self.username = Draw.PupStrInput("Username:", self.username, 32)
lordcrc@384
  5835
            
lordcrc@384
  5836
        def request_password(self):
lordcrc@384
  5837
            self.password = Draw.PupStrInput("Password:", self.password, 32)
lordcrc@384
  5838
lordcrc@384
  5839
    lrmdb_connector = lrmdb()
lordcrc@384
  5840
        
lordcrc@384
  5841
    
lordcrc@384
  5842
except: print("WARNING: LRMDB support not available")
lordcrc@384
  5843
lordcrc@384
  5844
lordcrc@384
  5845
lordcrc@384
  5846
### MatTex functions ###
lordcrc@384
  5847
### MatTex : is a dictionary of material or texture properties
lordcrc@384
  5848
lordcrc@384
  5849
def getMatTex(mat, basekey='', tex=False):
lordcrc@384
  5850
    global usedproperties, usedpropertiesfilterobj
lordcrc@384
  5851
    usedproperties = {}
lordcrc@384
  5852
    usedpropertiesfilterobj = mat
lordcrc@384
  5853
    luxMaterial(mat)
lordcrc@384
  5854
    dict = {}
lordcrc@384
  5855
    for k,v in usedproperties.items():
lordcrc@384
  5856
        if k[:len(basekey)]==basekey:
lordcrc@384
  5857
            if k[-9:] != '.textured':
lordcrc@384
  5858
                name = k[len(basekey):]
lordcrc@384
  5859
                if name == ".type": name = "type"
lordcrc@384
  5860
                dict[name] = v
lordcrc@384
  5861
    dict["__type__"] = ["material","texture"][bool(tex)]
lordcrc@384
  5862
    return dict
lordcrc@384
  5863
lordcrc@384
  5864
def putMatTex(mat, dict, basekey='', tex=None):
lordcrc@384
  5865
    if dict and (tex!=None) and (tex ^ (dict.has_key("__type__") and (dict["__type__"]=="texture"))):
lordcrc@384
  5866
        print("ERROR: Can't apply %s as %s"%(["texture","material"][bool(tex)],["material","texture"][bool(tex)]))
lordcrc@384
  5867
        return
lordcrc@384
  5868
    if dict:
lordcrc@384
  5869
        # remove all current properties in mat that starts with basekey
lordcrc@384
  5870
        try:
lordcrc@384
  5871
            d = mat.properties['luxblend']
lordcrc@384
  5872
            for k,v in d.convert_to_pyobject().items():
lordcrc@384
  5873
                kn = k
lordcrc@384
  5874
                if k[:7]=="__hash:":    # decode if entry is hashed (cause of 32chars limit)
lordcrc@384
  5875
                    l = v.split(" = ")
lordcrc@384
  5876
                    kn = l[0]
lordcrc@384
  5877
                if kn[:len(basekey)]==basekey:
lordcrc@384
  5878
                    del mat.properties['luxblend'][k]
lordcrc@384
  5879
        except: print("error") # pass
lordcrc@384
  5880
        # assign loaded properties
lordcrc@384
  5881
        for k,v in dict.items():
lordcrc@384
  5882
            try:
lordcrc@384
  5883
                if (basekey!="") and (k=="type"): k = ".type"
lordcrc@384
  5884
                # zuegs: following two lines should fix issue http://www.luxrender.net/forum/viewtopic.php?f=16&t=1618&p=14512#p14512
lordcrc@384
  5885
                if (basekey!="") and ((k[0]!=".") and (k[0]!=":")): k = ":"+k
lordcrc@384
  5886
                if (basekey=="") and (k[0:4]==":mat"): k = k[1:]
lordcrc@384
  5887
                luxProp(mat, basekey+k, None).set(v)
lordcrc@384
  5888
                if k[-8:] == '.texture':
lordcrc@384
  5889
                    luxProp(mat, basekey+k[:-8]+'.textured', 'false').set('true')
lordcrc@384
  5890
            except: pass
lordcrc@384
  5891
lordcrc@384
  5892
lordcrc@384
  5893
LBX_VERSION = '0.7'
lordcrc@384
  5894
lordcrc@384
  5895
def MatTex2dict(d, tex = None):
lordcrc@384
  5896
    global LBX_VERSION
lordcrc@384
  5897
    
lordcrc@384
  5898
    if LBX_VERSION == '0.6':
lordcrc@384
  5899
    
lordcrc@384
  5900
        if tex is not None and tex == True:
lordcrc@384
  5901
            d['LUX_DATA'] = 'TEXTURE'
lordcrc@384
  5902
        else:
lordcrc@384
  5903
            d['LUX_DATA'] = 'MATERIAL'
lordcrc@384
  5904
        
lordcrc@384
  5905
        d['LUX_VERSION'] = '0.6'
lordcrc@384
  5906
        
lordcrc@384
  5907
        return d
lordcrc@384
  5908
    
lordcrc@384
  5909
    elif LBX_VERSION == '0.7':
lordcrc@384
  5910
        definition = []
lordcrc@384
  5911
        for k in d.keys():
lordcrc@384
  5912
            if type(d[k]) == types.IntType:
lordcrc@384
  5913
                t = 'integer'
lordcrc@384
  5914
            if type(d[k]) == types.FloatType:
lordcrc@384
  5915
                t = 'float'
lordcrc@384
  5916
            if type(d[k]) == types.BooleanType:
lordcrc@384
  5917
                t = 'bool'
lordcrc@384
  5918
            if type(d[k]) == types.StringType:
lordcrc@384
  5919
                l=None
lordcrc@384
  5920
                try:
lordcrc@384
  5921
                    l = d[k].split(" ")
lordcrc@384
  5922
                except: pass
lordcrc@384
  5923
                if l==None or len(l)!=3:
lordcrc@384
  5924
                    t = 'string'
lordcrc@384
  5925
                else:
lordcrc@384
  5926
                    t = 'vector'
lordcrc@384
  5927
                
lordcrc@384
  5928
            definition.append([ t, k, d[k] ])
lordcrc@384
  5929
        
lordcrc@384
  5930
        
lordcrc@384
  5931
        lbx = {
lordcrc@384
  5932
            'type': d['__type__'],
lordcrc@384
  5933
            'version': '0.7',
lordcrc@384
  5934
            'definition': definition,
lordcrc@384
  5935
            'metadata': [
lordcrc@384
  5936
                ['string', 'generator', 'luxblend'],
lordcrc@384
  5937
            ]
lordcrc@384
  5938
        }
lordcrc@384
  5939
        
lordcrc@384
  5940
        return lbx
lordcrc@384
  5941
lordcrc@384
  5942
def format_dictStr(dictStr):
lordcrc@384
  5943
    result = ''
lordcrc@384
  5944
    pos = 0
lordcrc@384
  5945
    indentStr = '  '
lordcrc@384
  5946
    newLine = '\n'
lordcrc@384
  5947
    
lordcrc@384
  5948
    for char in dictStr:
lordcrc@384
  5949
        if char in ['}', ']']:
lordcrc@384
  5950
            result += newLine
lordcrc@384
  5951
            pos -= 1
lordcrc@384
  5952
            for j in range(0,pos):
lordcrc@384
  5953
                result += indentStr
lordcrc@384
  5954
                
lordcrc@384
  5955
        result += char
lordcrc@384
  5956
        
lordcrc@384
  5957
        if char in [',', '{', '[']:
lordcrc@384
  5958
            result += newLine
lordcrc@384
  5959
            if char in ['{', '[']:
lordcrc@384
  5960
                pos += 1
lordcrc@384
  5961
            for j in range(0,pos):
lordcrc@384
  5962
                result += indentStr
lordcrc@384
  5963
            
lordcrc@384
  5964
    return result
lordcrc@384
  5965
lordcrc@384
  5966
lordcrc@384
  5967
def MatTex2str(d, tex = None):
lordcrc@384
  5968
    global LBX_VERSION
lordcrc@384
  5969
    
lordcrc@384
  5970
    if LBX_VERSION == '0.6':
lordcrc@384
  5971
        return format_dictStr(str( MatTex2dict(d, tex) )) #.replace(", \'", ",\n\'")
lordcrc@384
  5972
    
lordcrc@384
  5973
    elif LBX_VERSION == '0.7':
lordcrc@384
  5974
        return format_dictStr(str( MatTex2dict(d, tex) )) #.replace("], \'", "],\r\n\'").replace("[","\r\n\t[")
lordcrc@384
  5975
        
lordcrc@384
  5976
lordcrc@384
  5977
def str2MatTex(s, tex = None):    # todo: this is not absolutely save from attacks!!!
lordcrc@384
  5978
    global LBX_VERSION
lordcrc@384
  5979
    
lordcrc@384
  5980
    s = s.strip()
lordcrc@384
  5981
    if (s[0]=='{') and (s[-1]=='}'):
lordcrc@384
  5982
        d = eval(s, dict(__builtins__=None))
lordcrc@384
  5983
        if type(d)==types.DictType:
lordcrc@384
  5984
            
lordcrc@384
  5985
            
lordcrc@384
  5986
            if LBX_VERSION == '0.6':
lordcrc@384
  5987
            
lordcrc@384
  5988
                if tex is not None and tex == True:
lordcrc@384
  5989
                    test_str = 'TEXTURE'
lordcrc@384
  5990
                else:
lordcrc@384
  5991
                    test_str = 'MATERIAL'
lordcrc@384
  5992
                    
lordcrc@384
  5993
                if   ('LUX_DATA' in d.keys() and d['LUX_DATA'] == test_str) \
lordcrc@384
  5994
                and  ('LUX_VERSION' in d.keys() and (d['LUX_VERSION'] == '0.6' or d['LUX_VERSION'] == 0.6)):
lordcrc@384
  5995
                    return d
lordcrc@384
  5996
                else:
lordcrc@384
  5997
                    reason = 'Missing/incorrect metadata'
lordcrc@384
  5998
                    
lordcrc@384
  5999
            elif LBX_VERSION == '0.7':
lordcrc@384
  6000
                
lordcrc@384
  6001
                def lb_list_to_dict(list):
lordcrc@384
  6002
                    d = {}
lordcrc@384
  6003
                    for t, k, v in list:
lordcrc@384
  6004
                        if t == 'float':
lordcrc@384
  6005
                            v = float(v)
lordcrc@384
  6006
                            
lordcrc@384
  6007
                        d[k] = v
lordcrc@384
  6008
                    return d
lordcrc@384
  6009
                
lordcrc@384
  6010
                if   ('version' in d.keys() and d['version'] in ['0.6', '0.7']) \
lordcrc@384
  6011
                and  ('type' in d.keys() and d['type'] in ['material', 'texture']) \
lordcrc@384
  6012
                and  ('definition' in d.keys()):
lordcrc@384
  6013
                    
lordcrc@384
  6014
                    
lordcrc@384
  6015
                    try:
lordcrc@384
  6016
                        definition = lb_list_to_dict(d['definition'])
lordcrc@384
  6017
                        
lordcrc@384
  6018
                        if 'metadata' in d.keys():
lordcrc@384
  6019
                            definition.update( lb_list_to_dict(d['metadata']) )
lordcrc@384
  6020
                        
lordcrc@384
  6021
                        return definition
lordcrc@384
  6022
                    except:
lordcrc@384
  6023
                        reason = 'Incorrect LBX definition data'
lordcrc@384
  6024
                else: 
lordcrc@384
  6025
                    reason = 'Missing/incorrect metadata'
lordcrc@384
  6026
            else:
lordcrc@384
  6027
                reason = 'Unknown LBX version'
lordcrc@384
  6028
        else:
lordcrc@384
  6029
            reason = 'Not a parsed dict'
lordcrc@384
  6030
    else:
lordcrc@384
  6031
        reason = 'Not a stored dict'
lordcrc@384
  6032
            
lordcrc@384
  6033
            
lordcrc@384
  6034
    print("ERROR: string to material/texture conversion failed: %s" % reason)
lordcrc@384
  6035
    return None
lordcrc@384
  6036
lordcrc@384
  6037
lordcrc@384
  6038
luxclipboard = None # global variable for copy/paste content
lordcrc@384
  6039
def showMatTexMenu(mat, basekey='', tex=False):
lordcrc@384
  6040
    global luxclipboard, ConnectLrmdb
lordcrc@384
  6041
    if tex: menu="Texture menu:%t"
lordcrc@384
  6042
    else: menu="Material menu:%t"
lordcrc@384
  6043
    menu += "|Copy%x1"
lordcrc@384
  6044
    try:
lordcrc@384
  6045
        if luxclipboard and (not(tex) ^ (luxclipboard["__type__"]=="texture")): menu +="|Paste%x2"
lordcrc@384
  6046
    except: pass
lordcrc@384
  6047
    if (tex):
lordcrc@384
  6048
        menu += "|Load LBT%x3|Save LBT%x4"
lordcrc@384
  6049
    else:
lordcrc@384
  6050
        menu += "|Load LBM%x3|Save LBM%x4"
lordcrc@384
  6051
    if  ConnectLrmdb:
lordcrc@384
  6052
        menu += "|Download from DB%x5" #not(tex) and
lordcrc@384
  6053
        menu += "|Upload to DB%x6"
lordcrc@384
  6054
lordcrc@384
  6055
#    menu += "|%l|dump material%x99|dump clipboard%x98"
lordcrc@384
  6056
    r = Draw.PupMenu(menu)
lordcrc@384
  6057
    if r==1:
lordcrc@384
  6058
        luxclipboard = getMatTex(mat, basekey, tex)
lordcrc@384
  6059
    elif r==2: putMatTex(mat, luxclipboard, basekey, tex)
lordcrc@384
  6060
    elif r==3: 
lordcrc@384
  6061
        scn = Scene.GetCurrent()
lordcrc@384
  6062
        if (tex):
lordcrc@384
  6063
            Window.FileSelector(lambda fn:loadMatTex(mat, fn, basekey, tex), "load texture", luxProp(scn, "lux", "").get()+os.sep+".lbt")
lordcrc@384
  6064
        else:
lordcrc@384
  6065
            Window.FileSelector(lambda fn:loadMatTex(mat, fn, basekey, tex), "load material", luxProp(scn, "lux", "").get()+os.sep+".lbm")
lordcrc@384
  6066
    elif r==4:
lordcrc@384
  6067
        scn = Scene.GetCurrent()
lordcrc@384
  6068
        if (tex):
lordcrc@384
  6069
            Window.FileSelector(lambda fn:saveMatTex(mat, fn, basekey, tex), "save texture", luxProp(scn, "lux", "").get()+os.sep+".lbt")
lordcrc@384
  6070
        else:
lordcrc@384
  6071
            Window.FileSelector(lambda fn:saveMatTex(mat, fn, basekey, tex), "save material", luxProp(scn, "lux", "").get()+os.sep+".lbm")
lordcrc@384
  6072
    elif r==5:
lordcrc@384
  6073
        if not tex:
lordcrc@384
  6074
            id = Draw.PupStrInput("Material ID:", "", 32)
lordcrc@384
  6075
        else:
lordcrc@384
  6076
            id = Draw.PupStrInput("Texture ID:", "", 32)
lordcrc@384
  6077
        if id: putMatTex(mat, downloadLRMDB(mat, id), basekey, tex)
lordcrc@384
  6078
    elif r==6:
lordcrc@384
  6079
        global lrmdb_connector
lordcrc@384
  6080
        if not lrmdb_connector.submit_object(mat, basekey, tex):
lordcrc@384
  6081
            msg = lrmdb_connector.last_error()
lordcrc@384
  6082
        else:
lordcrc@384
  6083
            msg = 'OK'
lordcrc@384
  6084
            
lordcrc@384
  6085
        Draw.PupMenu("Upload: "+msg+".%t|OK")
lordcrc@384
  6086
#    elif r==99:
lordcrc@384
  6087
#        for k,v in mat.properties['luxblend'].convert_to_pyobject().items(): print(k+"="+repr(v))
lordcrc@384
  6088
#    elif r==98:
lordcrc@384
  6089
#        for k,v in luxclipboard.items(): print(k+"="+repr(v))
lordcrc@384
  6090
#    prin()
lordcrc@384
  6091
    Draw.Redraw()
lordcrc@384
  6092
lordcrc@384
  6093
lordcrc@384
  6094
def saveMatTex(mat, fn, basekey='', tex=False):
lordcrc@384
  6095
    global LuxIsGUI
lordcrc@384
  6096
    d = getMatTex(mat, basekey, tex)
lordcrc@384
  6097
    file = open(fn, 'w')
lordcrc@384
  6098
    file.write(MatTex2str(d, tex))
lordcrc@384
  6099
    file.close()
lordcrc@384
  6100
    if LuxIsGUI: Draw.Redraw()
lordcrc@384
  6101
lordcrc@384
  6102
lordcrc@384
  6103
def loadMatTex(mat, fn, basekey='', tex=None):
lordcrc@384
  6104
    global LuxIsGUI
lordcrc@384
  6105
    file = open(fn, 'r')
lordcrc@384
  6106
    data = file.read()
lordcrc@384
  6107
    file.close()
lordcrc@384
  6108
    data = str2MatTex(data, tex)
lordcrc@384
  6109
    putMatTex(mat, data, basekey, tex) 
lordcrc@384
  6110
    if LuxIsGUI: Draw.Redraw()
lordcrc@384
  6111
lordcrc@384
  6112
lordcrc@384
  6113
activemat = None
lordcrc@384
  6114
def setactivemat(mat):
lordcrc@384
  6115
    global activemat
lordcrc@384
  6116
    activemat = mat
lordcrc@384
  6117
lordcrc@384
  6118
lordcrc@384
  6119
# scrollbar
lordcrc@384
  6120
class scrollbar:
lordcrc@384
  6121
    def __init__(self):
lordcrc@384
  6122
        self.position = 0 # current position at top (inside 0..height-viewHeight)
lordcrc@384
  6123
        self.height = 0 # total height of the content
lordcrc@384
  6124
        self.viewHeight = 0 # height of window
lordcrc@384
  6125
        self.x = 0 # horizontal position of the scrollbar
lordcrc@384
  6126
        self.scrolling = self.over = False # start without scrolling ;)
lordcrc@384
  6127
    def calcRects(self):
lordcrc@384
  6128
        # Blender doesn't give us direct access to the window size yet, but it does set the
lordcrc@384
  6129
        # GL scissor box for it, so we can get the size from that. (thx to Daniel Dunbar)
lordcrc@384
  6130
        size = BGL.Buffer(BGL.GL_FLOAT, 4)
lordcrc@384
  6131
        BGL.glGetFloatv(BGL.GL_SCISSOR_BOX, size)
lordcrc@384
  6132
        size = size.list # [winx, winy, width, height]
lordcrc@384
  6133
        self.winrect = size[:]
lordcrc@384
  6134
        self.viewHeight = size[3]
lordcrc@384
  6135
        size[0], size[1] = size[2]-20, 0 # [scrollx1, scrolly1, scrollx2, scrolly2]
lordcrc@384
  6136
        self.rect = size[:]
lordcrc@384
  6137
        if self.position < 0: self.position = 0
lordcrc@384
  6138
        if self.height < self.viewHeight: self.height = self.viewHeight
lordcrc@384
  6139
        if self.position > self.height-self.viewHeight: self.position = self.height-self.viewHeight
lordcrc@384
  6140
        self.factor = (size[3]-size[1]-4)/self.height
lordcrc@384
  6141
        self.sliderRect = [size[0]+2, size[3]-2-(self.position+self.viewHeight)*self.factor, size[2]-2, size[3]-2-self.position*self.factor]
lordcrc@384
  6142
    def draw(self):
lordcrc@384
  6143
        self.calcRects()
lordcrc@384
  6144
        BGL.glColor3f(0.5,0.5,0.5); BGL.glRectf(self.rect[0],self.rect[1],self.rect[2],self.rect[3])
lordcrc@384
  6145
        if self.over or self.scrolling: BGL.glColor3f(1.0,1.0,0.7)
lordcrc@384
  6146
        else: BGL.glColor3f(0.7,0.7,0.7)
lordcrc@384
  6147
        BGL.glRectf(self.sliderRect[0],self.sliderRect[1],self.sliderRect[2],self.sliderRect[3])
lordcrc@384
  6148
    def getTop(self):
lordcrc@384
  6149
        return self.viewHeight+self.position
lordcrc@384
  6150
    def scroll(self, delta):
lordcrc@384
  6151
        self.position = self.position + delta
lordcrc@384
  6152
        self.calcRects()
lordcrc@384
  6153
        Draw.Redraw()
lordcrc@384
  6154
    def Mouse(self):
lordcrc@384
  6155
        self.calcRects()
lordcrc@384
  6156
        coord, buttons = Window.GetMouseCoords(), Window.GetMouseButtons()
lordcrc@384
  6157
        over = (coord[0]>=self.winrect[0]+self.rect[0]) and (coord[0]<=self.winrect[0]+self.rect[2]) and \
lordcrc@384
  6158
               (coord[1]>=self.winrect[1]+self.rect[1]) and (coord[1]<=self.winrect[1]+self.rect[3])
lordcrc@384
  6159
        if Window.MButs.L and buttons > 0:
lordcrc@384
  6160
            if self.scrolling:
lordcrc@384
  6161
                if self.factor > 0: self.scroll((self.lastcoord[1]-coord[1])/self.factor)
lordcrc@384
  6162
                Draw.Redraw()
lordcrc@384
  6163
            elif self.over:
lordcrc@384
  6164
                self.scrolling = True
lordcrc@384
  6165
            self.lastcoord = coord
lordcrc@384
  6166
        elif self.scrolling:
lordcrc@384
  6167
            self.scrolling = False
lordcrc@384
  6168
            Draw.Redraw()
lordcrc@384
  6169
        if self.over != over: Draw.Redraw()
lordcrc@384
  6170
        self.over = over
lordcrc@384
  6171
lordcrc@384
  6172
scrollbar = scrollbar()
lordcrc@384
  6173
lordcrc@384
  6174
lordcrc@384
  6175
# gui main draw
lordcrc@384
  6176
def luxDraw():
lordcrc@384
  6177
    global icon_luxblend
lordcrc@384
  6178
lordcrc@384
  6179
    BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
lordcrc@384
  6180
lordcrc@384
  6181
    y = int(scrollbar.getTop()) # 420
lordcrc@384
  6182
    BGL.glColor3f(0.1,0.1,0.1); BGL.glRectf(0,0,440,y)
jensverwiebe@414
  6183
    BGL.glColor3f(1.0,0.5,0.0); BGL.glRasterPos2i(130,y-21); Draw.Text("v0.6")
lordcrc@384
  6184
    BGL.glColor3f(0.9,0.9,0.9)
lordcrc@384
  6185
lordcrc@384
  6186
    drawLogo(icon_luxblend, 6, y-25)
lordcrc@384
  6187
lordcrc@384
  6188
    scn = Scene.GetCurrent()
lordcrc@384
  6189
    if scn:
lordcrc@384
  6190
        luxpage = luxProp(scn, "page", 0)
lordcrc@384
  6191
        gui = luxGui(y-70)
lordcrc@384
  6192
lordcrc@384
  6193
        # render presets
lordcrc@384
  6194
        BGL.glRasterPos2i(10,y-45); Draw.Text("Render presets:")
lordcrc@384
  6195
        luxpreset = luxProp(scn, "preset", "1C - Final - medium MLT/Path Tracing (indoor) (recommended)")
lordcrc@384
  6196
        presets = getScenePresets()
lordcrc@384
  6197
        presetskeys = presets.keys()
lordcrc@384
  6198
        presetskeys.sort()
lordcrc@384
  6199
        presetskeys.insert(0, "")
lordcrc@384
  6200
        presetsstr = "presets: %t"
lordcrc@384
  6201
        for i, v in enumerate(presetskeys): presetsstr = "%s %%x%d|%s"%(v, i, presetsstr)
lordcrc@384
  6202
        try: i = presetskeys.index(luxpreset.get())
lordcrc@384
  6203
        except ValueError: i = 0
lordcrc@384
  6204
        Draw.Menu(presetsstr, evtLuxGui, 110, y-50, 220, 18, i, "", lambda e,v: luxpreset.set(presetskeys[v]))
lordcrc@384
  6205
        Draw.Button("save", evtSavePreset, 330, y-50, 40, 18, "create a render-settings preset")
lordcrc@384
  6206
        Draw.Button("del", evtDeletePreset, 370, y-50, 40, 18, "delete a render-settings preset")
lordcrc@384
  6207
lordcrc@384
  6208
        # if preset is selected load values
lordcrc@384
  6209
        if luxpreset.get() != "":
lordcrc@384
  6210
            try:
lordcrc@384
  6211
                d = presets[luxpreset.get()]
lordcrc@384
  6212
                for k,v in d.items(): scn.properties['luxblend'][k] = v
lordcrc@384
  6213
            except: pass
lordcrc@384
  6214
lordcrc@384
  6215
        Draw.Button("Material", evtLuxGui, 10, y-70, 80, 16, "", lambda e,v:luxpage.set(0))
lordcrc@384
  6216
        Draw.Button("Cam/Env", evtLuxGui, 90, y-70, 80, 16, "", lambda e,v:luxpage.set(1))
lordcrc@384
  6217
        Draw.Button("Render", evtLuxGui, 170, y-70, 80, 16, "", lambda e,v:luxpage.set(2))
lordcrc@384
  6218
        Draw.Button("Output", evtLuxGui, 250, y-70, 80, 16, "", lambda e,v:luxpage.set(3))
lordcrc@384
  6219
        Draw.Button("System", evtLuxGui, 330, y-70, 80, 16, "", lambda e,v:luxpage.set(4))
lordcrc@384
  6220
        if luxpage.get() == 0:
lordcrc@384
  6221
            BGL.glColor3f(1.0,0.5,0.0);BGL.glRectf(10,y-74,90,y-70);BGL.glColor3f(0.9,0.9,0.9)
lordcrc@384
  6222
            obj = scn.objects.active
lordcrc@384
  6223
            if obj:
lordcrc@384
  6224
                if (obj.getType() == "Lamp"):
lordcrc@384
  6225
                    ltype = obj.getData(mesh=1).getType() # data
lordcrc@384
  6226
                    if (ltype == Lamp.Types["Area"]): luxLight("Area LIGHT", "", obj, gui, 0)
lordcrc@384
  6227
                    elif (ltype == Lamp.Types["Spot"]): luxSpot("Spot LIGHT", "", obj, gui, 0)
lordcrc@384
  6228
                    elif (ltype == Lamp.Types["Lamp"]): luxLamp("Point LIGHT", "", obj, gui, 0)
lordcrc@384
  6229
                else:
lordcrc@384
  6230
                    matfilter = luxProp(scn, "matlistfilter", "false")
lordcrc@384
  6231
                    mats = getMaterials(obj, True)
lordcrc@384
  6232
                    if (activemat == None) and (len(mats) > 0):
lordcrc@384
  6233
                        setactivemat(mats[0])
lordcrc@384
  6234
                    if matfilter.get() == "false":
lordcrc@384
  6235
                        mats = Material.Get()
lordcrc@384
  6236
                    matindex = 0
lordcrc@384
  6237
                    for i, v in enumerate(mats):
lordcrc@384
  6238
                        if v==activemat: matindex = i
lordcrc@384
  6239
                    matnames = [m.getName() for m in mats]
lordcrc@384
  6240
                    menustr = "Material: %t"
lordcrc@384
  6241
                    for i, v in enumerate(matnames): menustr = "%s %%x%d|%s"%(v, i, menustr)
lordcrc@384
  6242
                    gui.newline("MATERIAL:", 8) 
lordcrc@384
  6243
                    r = gui.getRect(1.1, 1)
lordcrc@384
  6244
                    Draw.Button("C", evtConvertMaterial, r[0]-gui.h, gui.y-gui.h, gui.h, gui.h, "convert blender material to lux material")
lordcrc@384
  6245
                    Draw.Menu(menustr, evtLuxGui, r[0], r[1], r[2], r[3], matindex, "", lambda e,v: setactivemat(mats[v]))
lordcrc@384
  6246
                    luxBool("", matfilter, "filter", "only show active object materials", gui, 0.5)
lordcrc@384
  6247
lordcrc@384
  6248
                    Draw.Button("L", evtLoadMaterial, gui.x, gui.y-gui.h, gui.h, gui.h, "load a material preset")
lordcrc@384
  6249
                    Draw.Button("S", evtSaveMaterial, gui.x+gui.h, gui.y-gui.h, gui.h, gui.h, "save a material preset")
lordcrc@384
  6250
                    Draw.Button("D", evtDeleteMaterial, gui.x+gui.h*2, gui.y-gui.h, gui.h, gui.h, "delete a material preset")
lordcrc@384
  6251
                    if len(mats) > 0:
lordcrc@384
  6252
                        setactivemat(mats[matindex])
lordcrc@384
  6253
                        luxMaterial(activemat, gui)
lordcrc@384
  6254
        if luxpage.get() == 1:
lordcrc@384
  6255
            BGL.glColor3f(1.0,0.5,0.0);BGL.glRectf(90,y-74,170,y-70);BGL.glColor3f(0.9,0.9,0.9)
lordcrc@384
  6256
            cam = scn.getCurrentCamera()
lordcrc@384
  6257
            if cam:
lordcrc@384
  6258
                r = gui.getRect(1.1, 1)
lordcrc@384
  6259
                luxCamera(cam.data, scn.getRenderingContext(), gui)
lordcrc@384
  6260
            gui.newline("", 10)
lordcrc@384
  6261
            luxEnvironment(scn, gui)
lordcrc@384
  6262
        if luxpage.get() == 2:
lordcrc@384
  6263
            BGL.glColor3f(1.0,0.5,0.0);BGL.glRectf(170,y-74,250,y-70);BGL.glColor3f(0.9,0.9,0.9)
lordcrc@384
  6264
            r = gui.getRect(1.1, 1)
lordcrc@384
  6265
            luxSampler(scn, gui)
lordcrc@384
  6266
            gui.newline("", 10)
lordcrc@384
  6267
            luxSurfaceIntegrator(scn, gui)
lordcrc@384
  6268
            gui.newline("", 10)
lordcrc@384
  6269
            luxVolumeIntegrator(scn, gui)
lordcrc@384
  6270
            gui.newline("", 10)
lordcrc@384
  6271
            luxPixelFilter(scn, gui)
lordcrc@384
  6272
        if luxpage.get() == 3:
lordcrc@384
  6273
            BGL.glColor3f(1.0,0.5,0.0);BGL.glRectf(250,y-74,330,y-70);BGL.glColor3f(0.9,0.9,0.9)
lordcrc@384
  6274
            r = gui.getRect(1.1, 1)
lordcrc@384
  6275
            luxFilm(scn, gui)
lordcrc@384
  6276
        if luxpage.get() == 4:
lordcrc@384
  6277
            BGL.glColor3f(1.0,0.5,0.0);BGL.glRectf(330,y-74,410,y-70);BGL.glColor3f(0.9,0.9,0.9)
lordcrc@384
  6278
            luxSystem(scn, gui)
lordcrc@384
  6279
            gui.newline("", 10)
lordcrc@384
  6280
            luxAccelerator(scn, gui)
lordcrc@384
  6281
            gui.newline("MATERIALS:", 10)
lordcrc@384
  6282
            r = gui.getRect(2,1)
lordcrc@384
  6283
            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())
lordcrc@384
  6284
            gui.newline("SETTINGS:", 10)
lordcrc@384
  6285
            r = gui.getRect(2,1)
lordcrc@384
  6286
            Draw.Button("save defaults", 0, r[0], r[1], r[2], r[3], "save current settings as defaults", lambda e,v:saveluxdefaults())
lordcrc@384
  6287
        y = gui.y - 80
lordcrc@384
  6288
        if y > 0: y = 0 # bottom align of render button
lordcrc@384
  6289
        run = luxProp(scn, "run", "true")
lordcrc@384
  6290
        dlt = luxProp(scn, "default", "true")
lordcrc@384
  6291
        pipe = luxProp(scn, "pipe", "false")
lordcrc@384
  6292
        clay = luxProp(scn, "clay", "false")
lordcrc@384
  6293
        nolg = luxProp(scn, "nolg", "false")
lordcrc@384
  6294
        lxs = luxProp(scn, "lxs", "true")
lordcrc@384
  6295
        lxo = luxProp(scn, "lxo", "true")
lordcrc@384
  6296
        lxm = luxProp(scn, "lxm", "true")
lordcrc@384
  6297
        lxv = luxProp(scn, "lxv", "true")
lordcrc@384
  6298
        net = luxProp(scn, "netrenderctl", "false")
lordcrc@384
  6299
        donet = luxProp(scn, "donetrender", "true")
lordcrc@384
  6300
        
lordcrc@384
  6301
        global render_status_text
lordcrc@384
  6302
        global render_status
lordcrc@384
  6303
        
lordcrc@384
  6304
        if render_status == True:
lordcrc@384
  6305
            BGL.glRasterPos2i(10,y+20)
lordcrc@384
  6306
            Draw.Text(render_status_text)
lordcrc@384
  6307
        else:
lordcrc@384
  6308
            BGL.glRasterPos2i(10,y+5)
lordcrc@384
  6309
            Draw.Text(render_status_text, "tiny")
lordcrc@384
  6310
            
doug@410
  6311
            def check_pipe_def_exclusion(m, v):
doug@410
  6312
            	if m == 'd':
doug@410
  6313
            		dlt.set(["false","true"][bool(v)])
doug@410
  6314
            		
doug@410
  6315
            		if dlt.get() == 'true':
doug@410
  6316
            			pipe.set('false')
doug@410
  6317
            	elif m == 'p':
doug@410
  6318
            		pipe.set(["false","true"][bool(v)])
doug@410
  6319
            		
doug@410
  6320
            		if pipe.get() == 'true':
doug@410
  6321
            			dlt.set('false')
doug@410
  6322
            
lordcrc@384
  6323
            if (run.get()=="true"):
lordcrc@384
  6324
                Draw.Button("Render", 0, 10, y+20, 100, 36, "Render with Lux", lambda e,v:CBluxExport(dlt.get()=="true" or pipe.get()=="true", True))
lordcrc@384
  6325
                Draw.Button("Render Anim", 0, 110, y+20, 100, 36, "Render animation with Lux", lambda e,v:CBluxAnimExport(dlt.get()=="true" or pipe.get()=="true", True))
lordcrc@384
  6326
            else:
lordcrc@384
  6327
                Draw.Button("Export", 0, 10, y+20, 100, 36, "Export", lambda e,v:CBluxExport(dlt.get()=="true" or pipe.get()=="true", False))
lordcrc@384
  6328
                Draw.Button("Export Anim", 0, 110, y+20, 100, 36, "Export animation", lambda e,v:CBluxAnimExport(dlt.get()=="true" or pipe.get()=="true", False))
lordcrc@384
  6329
            
lordcrc@384
  6330
            Draw.Toggle("run", evtLuxGui, 265, y+40, 30, 16, run.get()=="true", "start Lux after export", lambda e,v: run.set(["false","true"][bool(v)]))
lordcrc@384
  6331
            
lordcrc@384
  6332
            if (pipe.get() == 'false' and dlt.get() == 'true') or run.get()=='false':
doug@410
  6333
                Draw.Toggle("def", evtLuxGui, 295, y+40, 55, 16, dlt.get()=="true", "write to default lxs file", lambda e,v: check_pipe_def_exclusion('d',v))
lordcrc@384
  6334
            elif pipe.get() == 'true' and dlt.get() == 'false':
doug@410
  6335
                Draw.Toggle("pipe", evtLuxGui, 295, y+40, 55, 16, pipe.get()=="true", "do not write any lxs file", lambda e,v: check_pipe_def_exclusion('p',v))
lordcrc@384
  6336
            else:
doug@410
  6337
                Draw.Toggle("def", evtLuxGui, 295, y+40, 25, 16, dlt.get()=="true", "write to default lxs file", lambda e,v: check_pipe_def_exclusion('d',v))
doug@410
  6338
                Draw.Toggle("pipe", evtLuxGui, 320, y+40, 30, 16, pipe.get()=="true", "do not write any lxs file", lambda e,v: check_pipe_def_exclusion('p',v))
lordcrc@384
  6339
            
lordcrc@384
  6340
            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)]))
lordcrc@384
  6341
            Draw.Toggle("noLG", evtLuxGui, 380, y+40, 35, 16, nolg.get()=="true", "disables all light groups", lambda e,v: nolg.set(["false","true"][bool(v)]))
lordcrc@384
  6342
            
lordcrc@384
  6343
            if pipe.get() == "false":
lordcrc@384
  6344
                Draw.Toggle(".lxs", 0, 265, y+20, 37, 16, lxs.get()=="true", "export .lxs scene file", lambda e,v: lxs.set(["false","true"][bool(v)]))
lordcrc@384
  6345
                Draw.Toggle(".lxo", 0, 302, y+20, 38, 16, lxo.get()=="true", "export .lxo geometry file", lambda e,v: lxo.set(["false","true"][bool(v)]))
lordcrc@384
  6346
                Draw.Toggle(".lxm", 0, 340, y+20, 37, 16, lxm.get()=="true", "export .lxm material file", lambda e,v: lxm.set(["false","true"][bool(v)]))
lordcrc@384
  6347
                Draw.Toggle(".lxv", 0, 377, y+20, 38, 16, lxv.get()=="true", "export .lxv volume file", lambda e,v: lxv.set(["false","true"][bool(v)]))
lordcrc@384
  6348
    
lordcrc@384
  6349
    BGL.glColor3f(0.9, 0.9, 0.9)
lordcrc@384
  6350
    
lordcrc@384
  6351
    BGL.glRasterPos2i(330,y+5) ; Draw.Text("Press Q or ESC to quit.", "tiny")
lordcrc@384
  6352
    scrollbar.height = scrollbar.getTop() - y
lordcrc@384
  6353
    scrollbar.draw()
lordcrc@384
  6354
lordcrc@384
  6355
render_status_text = ''
lordcrc@384
  6356
render_status = False
lordcrc@384
  6357
lordcrc@384
  6358
mouse_xr=1 
lordcrc@384
  6359
mouse_yr=1 
lordcrc@384
  6360
lordcrc@384
  6361
activeObject = None
lordcrc@384
  6362
activeEvent = None
lordcrc@384
  6363
lastEventTime = 0
lordcrc@384
  6364
key_tabs = {
lordcrc@384
  6365
    Draw.ONEKEY:     0,
lordcrc@384
  6366
    Draw.TWOKEY:     1,
lordcrc@384
  6367
    Draw.THREEKEY:   2,
lordcrc@384
  6368
    Draw.FOURKEY:    3,
lordcrc@384
  6369
    Draw.FIVEKEY:    4,
lordcrc@384
  6370
}
lordcrc@384
  6371
def luxEvent(evt, val):  # function that handles keyboard and mouse events
lordcrc@384
  6372
    global activeObject, activemat, activeEvent, lastEventTime, key_tabs
lordcrc@384
  6373
    if evt == Draw.ESCKEY or evt == Draw.QKEY:
lordcrc@384
  6374
        stop = Draw.PupMenu("OK?%t|Cancel export %x1")
lordcrc@384
  6375
        if stop == 1:
lordcrc@384
  6376
            Draw.Exit()
lordcrc@384
  6377
            return
lordcrc@384
  6378
    scn = Scene.GetCurrent()
lordcrc@384
  6379
    if scn:
lordcrc@384
  6380
        if scn.objects.active != activeObject:
lordcrc@384
  6381
            activeObject = scn.objects.active
lordcrc@384
  6382
            activemat = None
lordcrc@384
  6383
            Window.QRedrawAll()
lordcrc@384
  6384
    if (evt == Draw.MOUSEX) or (evt == Draw.MOUSEY): scrollbar.Mouse()
lordcrc@384
  6385
    if evt == Draw.WHEELUPMOUSE: scrollbar.scroll(-16)
lordcrc@384
  6386
    if evt == Draw.WHEELDOWNMOUSE: scrollbar.scroll(16)
lordcrc@384
  6387
    if evt == Draw.PAGEUPKEY: scrollbar.scroll(-50)
lordcrc@384
  6388
    if evt == Draw.PAGEDOWNKEY: scrollbar.scroll(50)
lordcrc@384
  6389
lordcrc@384
  6390
    # scroll to [T]op and [B]ottom
lordcrc@384
  6391
    if evt == Draw.TKEY:
lordcrc@384
  6392
        scrollbar.scroll(-scrollbar.position)
lordcrc@384
  6393
    if evt == Draw.BKEY:
lordcrc@384
  6394
        scrollbar.scroll(100000)   # Some large number should be enough ?!
lordcrc@384
  6395
lordcrc@384
  6396
    # R key shortcut to launch render
lordcrc@384
  6397
    # E key shortcut to export current scene (not render)
lordcrc@384
  6398
    # P key shortcut to preview current material
lordcrc@384
  6399
    # These keys need time and process-complete locks
lordcrc@384
  6400
    if evt in [Draw.RKEY, Draw.EKEY, Draw.PKEY]:
lordcrc@384
  6401
        if activeEvent == None and (sys.time() - lastEventTime) > 5:
lordcrc@384
  6402
            lastEventTime = sys.time()
lordcrc@384
  6403
            if evt == Draw.RKEY:
lordcrc@384
  6404
                activeEvent = 'RKEY'
lordcrc@384
  6405
                CBluxExport(luxProp(scn, "default", "true").get() == "true" or luxProp(scn, "pipe", "false").get() == "true", True)
lordcrc@384
  6406
                activeEvent = None
lordcrc@384
  6407
            if evt == Draw.EKEY:
lordcrc@384
  6408
                activeEvent = 'EKEY'
lordcrc@384
  6409
                CBluxExport(luxProp(scn, "default", "true").get() == "true" or luxProp(scn, "pipe", "false").get() == "true", False)
lordcrc@384
  6410
                activeEvent = None
lordcrc@384
  6411
            if evt == Draw.PKEY:
lordcrc@384
  6412
                activeEvent = 'PKEY'
lordcrc@384
  6413
                if activemat != None:
lordcrc@384
  6414
                    Preview_Update(activemat, '', True, 0, None, None, None)
lordcrc@384
  6415
                activeEvent = None
lordcrc@384
  6416
        
lordcrc@384
  6417
    # Switch GUI tabs with number keys
lordcrc@384
  6418
    if evt in key_tabs.keys():
lordcrc@384
  6419
        luxProp(scn, "page", 0).set(key_tabs[evt])        
lordcrc@384
  6420
        luxDraw()
lordcrc@384
  6421
        Window.QRedrawAll()
lordcrc@384
  6422
          
lordcrc@384
  6423
lordcrc@384
  6424
    # Handle icon button events - note - radiance - this is a work in progress! :)
lordcrc@384
  6425
#    if evt == Draw.LEFTMOUSE and not val: 
lordcrc@384
  6426
#           size=BGL.Buffer(BGL.GL_FLOAT, 4) 
lordcrc@384
  6427
#           BGL.glGetFloatv(BGL.GL_SCISSOR_BOX, size) 
lordcrc@384
  6428
#            size= [int(s) for s in size] 
lordcrc@384
  6429
#        mx, my = Window.GetMouseCoords()
lordcrc@384
  6430
#        mousex = mx - size[0]
lordcrc@384
  6431
#        print("mousex = %i"%mousex)
lordcrc@384
  6432
#        #if((mousex > 2) and (mousex < 25)):
lordcrc@384
  6433
#            # Mouse clicked in left button bar
lordcrc@384
  6434
#        if((mousex > 399) and (mousex < 418)):
lordcrc@384
  6435
#            # Mouse clicked in right button bar
lordcrc@384
  6436
#            mousey = my - size[1] - scrollbar.position
lordcrc@384
  6437
#            print("mousey = %i"%mousey)
lordcrc@384
  6438
            
lordcrc@384
  6439
    
lordcrc@384
  6440
def luxButtonEvt(evt):  # function that handles button events
lordcrc@384
  6441
    global usedproperties, usedpropertiesfilterobj
lordcrc@384
  6442
    if evt == evtLuxGui:
lordcrc@384
  6443
        Draw.Redraw()
lordcrc@384
  6444
    if evt == evtSavePreset:
lordcrc@384
  6445
        scn = Scene.GetCurrent()
lordcrc@384
  6446
        if scn:
lordcrc@384
  6447
            name = Draw.PupStrInput("preset name: ", "")
lordcrc@384
  6448
            if name != "":
lordcrc@384
  6449
                usedproperties = {}
lordcrc@384
  6450
                usedpropertiesfilterobj = None
lordcrc@384
  6451
                luxSurfaceIntegrator(scn)
lordcrc@384
  6452
                luxSampler(scn)
lordcrc@384
  6453
                luxPixelFilter(scn)
lordcrc@384
  6454
                # luxFilm(scn)
lordcrc@384
  6455
                luxAccelerator(scn)
lordcrc@384
  6456
                # luxEnvironment(scn)
lordcrc@384
  6457
                saveScenePreset(name, usedproperties.copy())
lordcrc@384
  6458
                luxProp(scn, "preset", "").set(name)
lordcrc@384
  6459
                Draw.Redraw()
lordcrc@384
  6460
    if evt == evtDeletePreset:
lordcrc@384
  6461
        presets = getScenePresets().keys()
lordcrc@384
  6462
        presets.sort()
lordcrc@384
  6463
        presetsstr = "delete preset: %t"
lordcrc@384
  6464
        for i, v in enumerate(presets): presetsstr += "|%s %%x%d"%(v, i)
lordcrc@384
  6465
        r = Draw.PupMenu(presetsstr, 20)
lordcrc@384
  6466
        if r >= 0:
lordcrc@384
  6467
            saveScenePreset(presets[r], None)
lordcrc@384
  6468
            Draw.Redraw()
lordcrc@384
  6469
lordcrc@384
  6470
    if evt == evtLoadMaterial:
lordcrc@384
  6471
        if activemat:
lordcrc@384
  6472
            mats = getMaterialPresets()
lordcrc@384
  6473
            matskeys = mats.keys()
lordcrc@384
  6474
            matskeys.sort()
lordcrc@384
  6475
            matsstr = "load preset: %t"
lordcrc@384
  6476
            for i, v in enumerate(matskeys): matsstr += "|%s %%x%d"%(v, i)
lordcrc@384
  6477
            r = Draw.PupMenu(matsstr, 20)
lordcrc@384
  6478
            if r >= 0:
lordcrc@384
  6479
                name = matskeys[r]
lordcrc@384
  6480
                try:
lordcrc@384
  6481
#                    for k,v in mats[name].items(): activemat.properties['luxblend'][k] = v
lordcrc@384
  6482
                    for k,v in mats[name].items(): luxProp(activemat, k, None).set(v)
lordcrc@384
  6483
                except: pass
lordcrc@384
  6484
                Draw.Redraw()
lordcrc@384
  6485
    if evt == evtSaveMaterial:
lordcrc@384
  6486
        if activemat:
lordcrc@384
  6487
            name = Draw.PupStrInput("preset name: ", "")
lordcrc@384
  6488
            if name != "":
lordcrc@384
  6489
                usedproperties = {}
lordcrc@384
  6490
                usedpropertiesfilterobj = activemat
lordcrc@384
  6491
                luxMaterial(activemat)
lordcrc@384
  6492
                saveMaterialPreset(name, usedproperties.copy())
lordcrc@384
  6493
                Draw.Redraw()
lordcrc@384
  6494
    if evt == evtDeleteMaterial:
lordcrc@384
  6495
        matskeys = getMaterialPresets().keys()
lordcrc@384
  6496
        matskeys.sort()
lordcrc@384
  6497
        matsstr = "delete preset: %t"
lordcrc@384
  6498
        for i, v in enumerate(matskeys): matsstr += "|%s %%x%d"%(v, i)
lordcrc@384
  6499
        r = Draw.PupMenu(matsstr, 20)
lordcrc@384
  6500
        if r >= 0:
lordcrc@384
  6501
            saveMaterialPreset(matskeys[r], None)
lordcrc@384
  6502
            Draw.Redraw()
lordcrc@384
  6503
    if evt == evtConvertMaterial:
lordcrc@384
  6504
        if activemat: convertMaterial(activemat)
lordcrc@384
  6505
        Draw.Redraw()
lordcrc@384
  6506
    if evt == evtLoadMaterial2:
lordcrc@384
  6507
        if activemat:
lordcrc@384
  6508
            scn = Scene.GetCurrent()
lordcrc@384
  6509
            Window.FileSelector(lambda fn:loadMatTex(activemat, fn), "load material", luxProp(scn, "lux", "").get()+os.sep+".lbm")
lordcrc@384
  6510
    if evt == evtSaveMaterial2:
lordcrc@384
  6511
        if activemat:
lordcrc@384
  6512
            scn = Scene.GetCurrent()
lordcrc@384
  6513
            Window.FileSelector(lambda fn:saveMaterial(activemat, fn), "save material", luxProp(scn, "lux", "").get()+os.sep+".lbm")
lordcrc@384
  6514
    
lordcrc@384
  6515
lordcrc@384
  6516
def setFocus(target):
lordcrc@384
  6517
    currentscene = Scene.GetCurrent()
lordcrc@384
  6518
    camObj = currentscene.objects.camera # currentscene.getCurrentCamera()
lordcrc@384
  6519
    if target == "S":
lordcrc@384
  6520
        try:
lordcrc@384
  6521
            refLoc = (Object.GetSelected()[0]).getLocation()
lordcrc@384
  6522
        except:
lordcrc@384
  6523
            print("select an object to focus\n")
lordcrc@384
  6524
    elif target == "C":
lordcrc@384
  6525
        refLoc = Window.GetCursorPos()
lordcrc@384
  6526
    else:
lordcrc@384
  6527
        refLoc = (Object.Get(target)).getLocation()
lordcrc@384
  6528
    dist = Mathutils.Vector(refLoc) - Mathutils.Vector(camObj.getLocation())
lordcrc@384
  6529
    camDir = camObj.getMatrix()[2]*(-1.0)
lordcrc@384
  6530
    camObj.getData(mesh=1).dofDist = (camDir[0]*dist[0]+camDir[1]*dist[1]+camDir[2]*dist[2])/camDir.length # data
lordcrc@384
  6531
lordcrc@384
  6532
lordcrc@384
  6533
# Parse command line arguments for batch mode rendering if supplied
lordcrc@384
  6534
lordcrc@384
  6535
try:
lordcrc@384
  6536
    batchindex = osys.argv.index('--batch')
lordcrc@384
  6537
    pyargs = osys.argv[osys.argv.index('--batch')+1:]
lordcrc@384
  6538
except: pyargs = []
lordcrc@384
  6539
lordcrc@384
  6540
if (pyargs != []) and (batchindex != 0):
jensverwiebe@414
  6541
    print("\n\nLuxBlend v0.6 - BATCH mode\n")
lordcrc@384
  6542
    LuxIsGUI = False
lordcrc@384
  6543
lordcrc@384
  6544
    scene = Scene.GetCurrent()
lordcrc@384
  6545
    context = scene.getRenderingContext()
lordcrc@384
  6546
lordcrc@384
  6547
    luxpath = ""
lordcrc@384
  6548
    import getopt
lordcrc@384
  6549
    o, a = getopt.getopt(pyargs, 's:e:o:t:l:',["scale=","haltspp=","run=", "lbm=", "lbt="])
lordcrc@384
  6550
lordcrc@384
  6551
    opts = {}
lordcrc@384
  6552
    for k,v in o:
lordcrc@384
  6553
        opts[k] = v
lordcrc@384
  6554
lordcrc@384
  6555
    if (opts.has_key('--run')) and (opts['--run'] == 'false'):
lordcrc@384
  6556
        print("Run: false")
lordcrc@384
  6557
        luxProp(scene, "run", "true").set("false")
lordcrc@384
  6558
    else:
lordcrc@384
  6559
        luxProp(scene, "run", "true").set("true")
lordcrc@384
  6560
lordcrc@384
  6561
    if opts.has_key('--scale'):
lordcrc@384
  6562
        print("Zoom: %s" %opts['--scale'])
lordcrc@384
  6563
        luxProp(scene, "film.scale", "100 %").set(opts['--scale'])
lordcrc@384
  6564
lordcrc@384
  6565
    if opts.has_key('--haltspp'):
lordcrc@384
  6566
        print("haltspp: %s" %opts['--haltspp'])
lordcrc@384
  6567
        luxProp(scene, "haltspp", 0).set(int(opts['--haltspp']))
lordcrc@384
  6568
lordcrc@384
  6569
    if opts.has_key('-s'):
lordcrc@384
  6570
        print("Start frame: %s" %opts['-s'])
lordcrc@384
  6571
        context.startFrame(int(opts['-s']))
lordcrc@384
  6572
    else:
lordcrc@384
  6573
        print("Error: Start frame not supplied (-s)"); osys.exit(1)
lordcrc@384
  6574
    if opts.has_key('-e'):
lordcrc@384
  6575
        print("End frame: %s" %opts['-e'])
lordcrc@384
  6576
        context.endFrame(int(opts['-e']))
lordcrc@384
  6577
    else:
lordcrc@384
  6578
        print("Error: End frame not supplied (-e)"); osys.exit(1)
lordcrc@384
  6579
    if opts.has_key('-l'):
lordcrc@384
  6580
        print("Path to lux binary: %s" %opts['-l'])
lordcrc@384
  6581
        luxbatchconsolemode = luxProp(scene, "luxbatchc", "false")
lordcrc@384
  6582
        luxbatchconsolemode.set("true")
lordcrc@384
  6583
        luxpathprop = luxProp(scene, "lux", "")
lordcrc@384
  6584
        luxpathprop.set(opts['-l'])
lordcrc@384
  6585
    else:
lordcrc@384
  6586
        print("Error: path to lux binary not supplied (-l)"); osys.exit(1)
lordcrc@384
  6587
    if opts.has_key('-o'):
lordcrc@384
  6588
        print("Image output path: %s" %opts['-o'])
lordcrc@384
  6589
        luxProp(scene, "overrideoutputpath", "").set(opts['-o'])
lordcrc@384
  6590
    else:
lordcrc@384
  6591
        print("Error: image output path not supplied (-o)"); osys.exit(1)
lordcrc@384
  6592
    if opts.has_key('-t'):
lordcrc@384
  6593
        print("Temporary export path: %s" %opts['-t'])
lordcrc@384
  6594
        luxProp(scene, "datadir", "").set(opts['-t'])
lordcrc@384
  6595
    else:
lordcrc@384
  6596
        print("Error: Temporary export path not supplied (-t)"); osys.exit(1)
lordcrc@384
  6597
    
lordcrc@384
  6598
    if opts.has_key('--lbm'):
lordcrc@384
  6599
        print("Load material: %s" %opts['--lbm'])
lordcrc@384
  6600
        mat = Material.Get("Material")
lordcrc@384
  6601
        if mat: loadMatTex(mat, opts['--lbm'])
lordcrc@384
  6602
        else:
lordcrc@384
  6603
            print("Error: No material with name \"Material\" found (--lbm)"); osys.exit(1)
lordcrc@384
  6604
            
lordcrc@384
  6605
    if opts.has_key('--lbt'):
lordcrc@384
  6606
        print("Load material: %s" %opts['--lbt'])
lordcrc@384
  6607
        mat = Material.Get("Material")
lordcrc@384
  6608
        if mat: loadMatTex(mat, opts['--lbt'], ':Kd')
lordcrc@384
  6609
        else:
lordcrc@384
  6610
            print("Error: No material with name \"Material\" found (--lbt)"); osys.exit(1)
lordcrc@384
  6611
lordcrc@384
  6612
#    CBluxAnimExport(True, True)
lordcrc@384
  6613
    CBluxAnimExport(True, True, False) # as by zukazuka (http://www.luxrender.net/forum/viewtopic.php?f=11&t=1288)
lordcrc@384
  6614
    osys.exit(0)
lordcrc@384
  6615
lordcrc@384
  6616
else:
jensverwiebe@414
  6617
    print("\n\nLuxBlend v0.6 - UI mode\n")
lordcrc@384
  6618
    from Blender.Window import DrawProgressBar
lordcrc@384
  6619
    LuxIsGUI = True
lordcrc@384
  6620
    
lordcrc@384
  6621
    Draw.Register(luxDraw, luxEvent, luxButtonEvt) # init GUI
lordcrc@384
  6622
lordcrc@384
  6623
    luxpathprop = luxProp(Scene.GetCurrent(), "lux", "")
lordcrc@384
  6624
    luxpath = luxpathprop.get()
lordcrc@384
  6625
    luxrun = luxProp(Scene.GetCurrent(), "run", True).get()
lordcrc@384
  6626
    checkluxpath = luxProp(Scene.GetCurrent(), "checkluxpath", True).get()
lordcrc@384
  6627
lordcrc@384
  6628
    if checkluxpath and luxrun:
lordcrc@384
  6629
        if (luxpath is None) or (sys.exists(luxpath)<=0):
doug@411
  6630
            # luxpath not valid, so delete entry from .blend scene file
lordcrc@384
  6631
            luxpathprop.delete()
lordcrc@384
  6632
            # and re-get luxpath, so we get the path from default-settings
lordcrc@384
  6633
            luxpath = luxpathprop.get()
doug@411
  6634
            #
tom@412
  6635
            LUXRENDER_ROOT = os.getenv('LUXRENDER_ROOT')
doug@411
  6636
            if LUXRENDER_ROOT is not None:
tom@413
  6637
                LUXRENDER_ROOT = LUXRENDER_ROOT + os.sep
doug@411
  6638
                luxpathprop.set(LUXRENDER_ROOT)
doug@411
  6639
                luxpath = LUXRENDER_ROOT
doug@411
  6640
                if sys.exists(luxpath)>0:
doug@411
  6641
                    print('LuxRender path set from LUXRENDER_ROOT environment variable')
doug@411
  6642
                    saveluxdefaults()
doug@411
  6643
            
lordcrc@384
  6644
            if (luxpath is None) or (sys.exists(luxpath)<=0):
lordcrc@384
  6645
                print("WARNING: LuxPath \"%s\" is not valid\n"%(luxpath))
lordcrc@384
  6646
                scn = Scene.GetCurrent()
lordcrc@384
  6647
                if scn:
lordcrc@384
  6648
                    r = Draw.PupMenu("Installation: Set path to the lux render software?%t|Yes%x1|No%x0|Never%x2")
lordcrc@384
  6649
                    if r == 1:
lordcrc@384
  6650
                        Window.FileSelector(lambda s:luxProp(scn, "lux", "").set(Blender.sys.dirname(s)+os.sep), "Select file in Lux path")
lordcrc@384
  6651
                        saveluxdefaults()
lordcrc@384
  6652
                    if r == 2:
lordcrc@384
  6653
                        newluxdefaults["checkluxpath"] = False
lordcrc@384
  6654
                        saveluxdefaults()
lordcrc@384
  6655
    else    :
jeanphi@391
  6656
        print("Lux path check disabled\n")